View Javadoc

1   /*
2    *  Copyright 2010 Felix Roethenbacher
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package ch.syabru.nagios.broker.impl;
17  
18  import java.net.MalformedURLException;
19  import java.util.Date;
20  import java.util.List;
21  
22  import javax.annotation.PostConstruct;
23  import javax.management.MalformedObjectNameException;
24  import javax.management.ObjectName;
25  import javax.management.remote.JMXServiceURL;
26  import javax.xml.datatype.XMLGregorianCalendar;
27  import javax.xml.transform.stream.StreamSource;
28  
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  import org.springframework.beans.factory.annotation.Required;
32  import org.springframework.core.io.Resource;
33  import org.springframework.oxm.Unmarshaller;
34  import org.springframework.oxm.XmlMappingException;
35  
36  import ch.syabru.nagios.broker.Configuration;
37  import ch.syabru.nagios.broker.ConfigurationException;
38  import ch.syabru.nagios.broker.ExternalCommandFactory;
39  import ch.syabru.nagios.broker.Matcher;
40  import ch.syabru.nagios.broker.MatcherException;
41  import ch.syabru.nagios.broker.MessageHandler;
42  import ch.syabru.nagios.broker.MessageListener;
43  import ch.syabru.nagios.broker.MessageListenerManager;
44  import ch.syabru.nagios.broker.jmx.JmxMatcher;
45  import ch.syabru.nagios.broker.jmx.JmxMessageListener;
46  import ch.syabru.nagios.broker.xml.XmlActionProcessServiceCheckResult;
47  import ch.syabru.nagios.broker.xml.XmlActionScheduleForcedServiceCheck;
48  import ch.syabru.nagios.broker.xml.XmlActionScheduleServiceCheck;
49  import ch.syabru.nagios.broker.xml.XmlConfiguration;
50  import ch.syabru.nagios.broker.xml.XmlJmx;
51  import ch.syabru.nagios.broker.xml.XmlJmxMBeanServer;
52  import ch.syabru.nagios.broker.xml.XmlJmxMatch;
53  import ch.syabru.nagios.broker.xml.XmlJmxNotification;
54  
55  /**
56   * Configuration implementation.
57   *
58   * @author fr
59   *
60   */
61  public class ConfigurationImpl implements Configuration {
62      private final Logger logger = LoggerFactory.getLogger(this.getClass());
63  
64      private Unmarshaller unmarshaller;
65      private Resource configFile;
66      private MessageHandler messageHandler;
67      private MessageListenerManager messageListenerManager;
68      private List<MessageListener> messageListeners;
69      private List<Matcher> matchers;
70  
71      private XmlConfiguration config;
72  
73      /**
74       * Read configuration.
75       * @throws ConfigurationException XX
76       */
77      @PostConstruct
78      public void readConfiguration()
79      throws ConfigurationException
80      {
81          logger.info("Reading configuration [{}])",
82                  configFile.getDescription());
83          try {
84              StreamSource source = new StreamSource(
85                      configFile.getInputStream());
86              config = (XmlConfiguration) unmarshaller.unmarshal(source);
87          } catch (XmlMappingException e) {
88              throw new ConfigurationException(
89                      "Error parsing configuration file", e);
90          } catch (Exception e) {
91              throw new ConfigurationException("Error reading configuration", e);
92          }
93          if (config.getJmx() != null)
94              processJmxConfiguration(config.getJmx());
95          else
96              logger.warn("No configuration elements found. " +
97                      "Please check your configuration file.");
98      }
99  
100     /**
101      * Process JMX configuration.
102      * @param xmlJmx JMX XML configuration.
103      * @throws ConfigurationException XX
104      */
105     private void processJmxConfiguration(XmlJmx xmlJmx)
106     throws ConfigurationException
107     {
108         // JMX MBean servers.
109         for (XmlJmxMBeanServer server : xmlJmx.getMBeanServer()) {
110             JMXServiceURL serviceURL;
111             try {
112                 serviceURL = new JMXServiceURL(server.getJmxServiceUrl());
113             } catch (MalformedURLException e) {
114                 throw new ConfigurationException(
115                         "Malformed JMX service URL", e);
116             }
117             // Notifications.
118             for (XmlJmxNotification xmlJmxNotification :
119                 server.getNotification())
120             {
121                 // Create listener.
122                 ObjectName objectName;
123                 try {
124                     objectName = new ObjectName(
125                             xmlJmxNotification.getObjectName());
126                 } catch (MalformedObjectNameException e) {
127                     throw new ConfigurationException(
128                             "Malformed object name", e);
129                 }
130                 JmxMessageListener listener = new JmxMessageListener(
131                         messageListenerManager, messageHandler, serviceURL,
132                         objectName);
133                 messageListeners.add(listener);
134                 logger.debug("Created JMX listener [{}, {}]", new Object[] {
135                         serviceURL.toString(), objectName.toString()});
136                 // Create matcher.
137                 XmlJmxMatch xmlJmxMatch = xmlJmxNotification.getMatch();
138                 String classNameRegex = xmlJmxMatch.getClassName();
139                 String messageRegex = xmlJmxMatch.getMessage();
140                 String typeRegex = xmlJmxMatch.getType();
141                 String sourceRegex = xmlJmxMatch.getSource();
142                 // Get external command factory.
143                 for (Object obj : xmlJmxNotification.getAction().getXmlAction())
144                 {
145                     ExternalCommandFactory factory;
146                     if (obj instanceof XmlActionProcessServiceCheckResult) {
147                         XmlActionProcessServiceCheckResult action =
148                             (XmlActionProcessServiceCheckResult) obj;
149                         String hostName = action.getHostName();
150                         String serviceDescription =
151                             action.getServiceDescription();
152                         int returnCode = action.getReturnCode();
153                         String pluginOutput = action.getPluginOutput();
154                         factory = new ProcessServiceCheckResultCommandFactory(
155                                 hostName, serviceDescription, returnCode,
156                                 pluginOutput);
157                     } else if (obj instanceof XmlActionScheduleServiceCheck) {
158                         XmlActionScheduleServiceCheck action =
159                             (XmlActionScheduleServiceCheck) obj;
160                         String hostName = action.getHostName();
161                         String serviceDescription =
162                             action.getServiceDescription();
163                         XMLGregorianCalendar xmlCheckTime =
164                             action.getCheckTime();
165                         Integer delaySeconds =
166                             action.getDelaySeconds() != null ?
167                                     action.getDelaySeconds() : 0;
168                         Date checkTime = null;
169                         if (xmlCheckTime != null) {
170                             checkTime = xmlCheckTime.toGregorianCalendar().
171                                     getTime();
172                         }
173                         factory = new ScheduleServiceCheckCommandFactory(
174                                 hostName, serviceDescription, checkTime,
175                                 delaySeconds);
176                     } else if (obj instanceof
177                             XmlActionScheduleForcedServiceCheck)
178                     {
179                         XmlActionScheduleForcedServiceCheck action =
180                             (XmlActionScheduleForcedServiceCheck) obj;
181                         String hostName = action.getHostName();
182                         String serviceDescription =
183                             action.getServiceDescription();
184                         XMLGregorianCalendar xmlCheckTime =
185                             action.getCheckTime();
186                         Integer delaySeconds =
187                             action.getDelaySeconds() != null ?
188                                     action.getDelaySeconds() : 0;
189                         Date checkTime = null;
190                         if (xmlCheckTime != null) {
191                             checkTime = xmlCheckTime.toGregorianCalendar().
192                                     getTime();
193                         }
194                         factory = new ScheduleForcedServiceCheckCommandFactory(
195                                 hostName, serviceDescription, checkTime,
196                                 delaySeconds);
197                     } else {
198                         throw new ConfigurationException("Unknown action [" +
199                                 obj.getClass().getName() + "]");
200                     }
201                     try {
202                         JmxMatcher matcher = new JmxMatcher(classNameRegex,
203                                 messageRegex, typeRegex, sourceRegex, factory);
204                         matchers.add(matcher);
205                     } catch (MatcherException e) {
206                         throw new ConfigurationException(
207                                 "Error creating matcher", e);
208                     }
209                     logger.debug("Created matcher [{}, {}]", new Object[] {
210                             serviceURL.toString(),
211                             factory.getClass().getSimpleName()});
212                 }
213             }
214         }
215     }
216 
217     @Required
218     public void setUnmarshaller(Unmarshaller unmarshaller) {
219         this.unmarshaller = unmarshaller;
220     }
221 
222     @Required
223     public void setConfigFile(Resource configFile) {
224         this.configFile = configFile;
225     }
226 
227     @Required
228     public void setMessageListeners(List<MessageListener> messageListeners) {
229         this.messageListeners = messageListeners;
230     }
231 
232     @Required
233     public void setMatchers(List<Matcher> matchers) {
234         this.matchers = matchers;
235     }
236 
237     @Required
238     public void setMessageHandler(MessageHandler messageHandler) {
239         this.messageHandler = messageHandler;
240     }
241 
242     @Required
243     public void setMessageListenerManager(
244             MessageListenerManager messageListenerManager)
245     {
246         this.messageListenerManager = messageListenerManager;
247     }
248 }