View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2007, 2014 Massimiliano Ziccardi
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 it.jnrpe.osgi;
17  
18  import it.jnrpe.JNRPE;
19  import it.jnrpe.commands.CommandDefinition;
20  import it.jnrpe.commands.CommandRepository;
21  import it.jnrpe.plugins.IPluginRepository;
22  import it.jnrpe.plugins.PluginRepository;
23  import it.jnrpe.utils.StringUtils;
24  
25  import java.net.UnknownHostException;
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Dictionary;
29  import java.util.Enumeration;
30  import java.util.Hashtable;
31  import java.util.List;
32  
33  import org.osgi.framework.BundleActivator;
34  import org.osgi.framework.BundleContext;
35  import org.osgi.framework.Constants;
36  import org.osgi.framework.ServiceRegistration;
37  import org.osgi.service.cm.ConfigurationException;
38  import org.osgi.service.cm.ManagedService;
39  import org.osgi.util.tracker.BundleTracker;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  import org.slf4j.impl.OSGILogFactory;
43  
44  public class JNRPEBundleActivator implements BundleActivator, ManagedService {
45  
46  	private final static String PID = "it.jnrpe.osgi";
47  
48  	/**
49  	 * The logger.
50  	 */
51  	private static final Logger LOG = LoggerFactory
52  			.getLogger(JNRPEBundleActivator.class);
53  
54  	private BundleTracker bundleTracker;
55  
56  	private IPluginRepository pluginRepository;
57  	private CommandRepository commandRepository;
58  
59  	private JNRPE jnrpeEngine;
60  
61  	/**
62  	 * Automatically called by the OSGI layer when a new configuration is ready.
63  	 */
64  	public void updated(final Dictionary properties)
65  			throws ConfigurationException {
66  		if (properties == null) {
67  			LOG.info("Empty configuration received. JNRPE Server not started");
68  			return;
69  		}
70  
71  		LOG.info("New configuration received");
72  		if (jnrpeEngine != null) {
73  			LOG.info("Shutting down JNRPE listener...");
74  			jnrpeEngine.shutdown();
75  		}
76  
77  		// String acceptParamsString = "" + properties.get("accept_params");
78  		String bindAddress = (String) properties.get("bind_address");
79  		String allowAddress = (String) properties.get("allow_address");
80  
81  		// Parsing command definition...
82  		for (CommandDefinition cd : parseCommandDefinitions(properties)) {
83  			LOG.info("Adding command definition for command '{}'", cd.getName());
84  			commandRepository.addCommandDefinition(cd);
85  		}
86  
87  		JNRPE engine = new JNRPE(pluginRepository, commandRepository);
88  		engine.addEventListener(new EventLoggerListener());
89  
90  		if (allowAddress == null || allowAddress.trim().length() == 0) {
91  			allowAddress = "127.0.0.1";
92  		}
93  
94  		for (String addr : allowAddress.split(",")) {
95  
96  			LOG.info("Allowing requests from : {}", addr);
97  
98  			if (addr.trim().length() == 0) {
99  				continue;
100 			}
101 
102 			engine.addAcceptedHost(addr);
103 		}
104 
105 		if (bindAddress != null && bindAddress.trim().length() != 0) {
106 			JNRPEBindingAddress address = new JNRPEBindingAddress(bindAddress);
107 			try {
108 
109 				LOG.info("Listening on : {}:{} - SSL:{}", address.getAddress(),
110 						address.getPort(), address.isSsl());
111 
112 				engine.listen(address.getAddress(), address.getPort(),
113 						address.isSsl());
114 			} catch (UnknownHostException e) {
115 				LOG.error("Bad binding address: {}", bindAddress);
116 				throw new ConfigurationException("bind_address",
117 						e.getMessage(), e);
118 			}
119 		} else {
120 			throw new ConfigurationException("bind_address",
121 					"Binding address can't be empty");
122 		}
123 		jnrpeEngine = engine;
124 	}
125 
126 	private Collection<CommandDefinition> parseCommandDefinitions(
127 			final Dictionary<String, String> props) {
128 
129 		List<CommandDefinition> res = new ArrayList<CommandDefinition>();
130 
131 		final String prefix = "command.";
132 		final int prefixLen = prefix.length();
133 
134 		Enumeration<String> en = props.keys();
135 		while (en.hasMoreElements()) {
136 			String key = en.nextElement();
137 			if (key.startsWith(prefix)) {
138 				String commandName = key.substring(prefixLen);
139 
140 				String commandLine = props.get(key);
141 				String[] elements = StringUtils.split(commandLine, false);
142 				String pluginName = elements[0];
143 
144 				StringBuffer cmdLine = new StringBuffer();
145 
146 				for (int i = 1; i < elements.length; i++) {
147 					cmdLine.append(quoteAndEscape(elements[i])).append(" ");
148 				}
149 
150 				CommandDefinition cd = new CommandDefinition(commandName,
151 						pluginName);
152 				cd.setArgs(cmdLine.toString());
153 				res.add(cd);
154 			}
155 		}
156 
157 		return res;
158 	}
159 
160 	/**
161 	 * Quotes a string.
162 	 * 
163 	 * @param string
164 	 *            The string to be quoted
165 	 * @return The quoted string
166 	 */
167 	private String quoteAndEscape(final String string) {
168 		if (string.indexOf(' ') == -1) {
169 			return string;
170 		}
171 
172 		String res = "\"" + string.replaceAll("\"", "\\\"") + "\"";
173 		return res;
174 	}
175 
176 	/**
177 	 * Initializes the bundle.
178 	 */
179 	public void start(final BundleContext context) throws Exception {
180 
181 		OSGILogFactory.initOSGI(context);
182 
183 		pluginRepository = new PluginRepository();
184 		commandRepository = new CommandRepository();
185 
186 		bundleTracker = new JNRPEBundleTracker(context, pluginRepository,
187 				commandRepository);
188 		bundleTracker.open();
189 		// Register the managed service...
190 		Dictionary<String, String> props = new Hashtable<String, String>();
191 		props.put(Constants.SERVICE_PID, PID);
192 
193 		ServiceRegistration servReg = context.registerService(
194 				ManagedService.class.getName(), this, props);
195 		servReg.setProperties(props);
196 		LOG.info("JNRPE bundle started");
197 	}
198 
199 	/**
200 	 * Stops the JNRPE bundle.
201 	 */
202 	public void stop(final BundleContext context) throws Exception {
203 		if (jnrpeEngine != null) {
204 			jnrpeEngine.shutdown();
205 		}
206 
207 	}
208 
209 }