blob: 58793859e794dc6ae424e0362ca537a6ce182183 [file] [log] [blame]
package org.eclipse.virgo.kernel.config.internal;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Properties;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* This class reads the merged shell configuration and registers it separated in the @link(ConfigurationAdmin).
* <p />
*
* <strong>Concurrent Semantics</strong><br />
* Thread-safe.
*/
public class ConsoleConfigurationConvertor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final BundleContext context;
private final ConfigurationAdmin configAdmin;
private ServiceRegistration<ManagedService> configuratorRegistration;
private static final String CONSOLE_PID = "osgi.console";
private static final String TELNET_PID = "osgi.console.telnet";
private static final String SSH_PID = "osgi.console.ssh";
private static final String TELNET_PORT = "telnet.port";
private static final String TELNET_HOST = "telnet.host";
private static final String TELNET_ENABLED = "telnet.enabled";
private static final String SSH_PORT = "ssh.port";
private static final String SSH_HOST = "ssh.host";
private static final String SSH_ENABLED = "ssh.enabled";
private static final String HOST = "host";
private static final String PORT = "port";
private static final String ENABLED = "enabled";
private static final String TELNET_SERVICE = "telnet";
private static final String SSH_SERVICE = "ssh";
private static final Object monitor = new Object();
ConsoleConfigurationConvertor(BundleContext context, ConfigurationAdmin configAdmin) {
this.context = context;
this.configAdmin = configAdmin;
}
public void start() {
Dictionary<String, String> consoleProperties = new Hashtable<String, String>();
consoleProperties.put(Constants.SERVICE_PID, CONSOLE_PID);
synchronized (ConsoleConfigurationConvertor.monitor) {
this.configuratorRegistration = this.context.registerService(ManagedService.class, new ConsoleConfigurator(), consoleProperties);
}
}
private void updateConfiguration(String pid, String host, String port, String enabled) {
boolean isPortAvailable;
if (pid.contains(TELNET_SERVICE)) {
isPortAvailable = checkPortAvailability(port, enabled, TELNET_SERVICE);
} else {
isPortAvailable = checkPortAvailability(port, enabled, SSH_SERVICE);
}
if(!isPortAvailable) {
return;
}
try {
Configuration configuration = this.configAdmin.getConfiguration(pid, null);
Dictionary<String, String> properties = new Hashtable<String, String>();
properties.put(HOST, host);
properties.put(PORT, port);
properties.put(ENABLED, enabled);
configuration.update(properties);
} catch (IOException e) {
String message = String.format("Unable to update configuration with pid '%s'", pid);
this.logger.error(message, e);
}
}
public void stop() {
deleteConfiguration(TELNET_PID);
deleteConfiguration(SSH_PID);
deleteConfiguration(CONSOLE_PID);
}
private void deleteConfiguration(String pid) {
try {
Configuration configuration = configAdmin.getConfiguration(pid, null);
configuration.delete();
} catch (IOException e) {
String message = String.format("Unable to delete configuration with pid: " + pid);
this.logger.error(message, e);
}
}
private boolean checkPortAvailability(String portStr, String enabled, String service) {
if ("false".equalsIgnoreCase(enabled)) {
return true;
}
int port = Integer.parseInt(portStr);
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
return true;
} catch (BindException e) {
String message = "Port " + port + " already in use; " + service + " access to console will not be available";
this.logger.error(message, e);
} catch (IOException e) {
// do nothing
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// do nothing
}
}
}
return false;
}
class ConsoleConfigurator implements ManagedService {
private Dictionary properties;
@Override
public void updated(Dictionary props) throws ConfigurationException {
if (props != null) {
this.properties = props;
this.properties.put(Constants.SERVICE_PID, CONSOLE_PID);
} else {
return;
}
synchronized (ConsoleConfigurationConvertor.monitor) {
ConsoleConfigurationConvertor.this.configuratorRegistration.setProperties(this.properties);
}
String telnetHost = (String) this.properties.get(TELNET_HOST);
String telnetPort = (String) this.properties.get(TELNET_PORT);
String telnetEnabled = (String) this.properties.get(TELNET_ENABLED);
updateConfiguration(TELNET_PID, telnetHost, telnetPort, telnetEnabled);
String sshHost = (String) this.properties.get(SSH_HOST);
String sshPort = (String) this.properties.get(SSH_PORT);
String sshEnabled = (String) this.properties.get(SSH_ENABLED);
updateConfiguration(SSH_PID, sshHost, sshPort, sshEnabled);
}
}
}