package org.eclipse.virgo.kernel.userregion.internal;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.util.Dictionary;
import java.util.Hashtable;
import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkUtils;
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;
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) {
this.context = context;
this.configAdmin = OsgiFrameworkUtils.getService(context, ConfigurationAdmin.class).getService();
}
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, Object> properties = new Hashtable<String, Object>();
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<String, String> properties;
@SuppressWarnings({ "unchecked", "rawtypes" })
@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);
}
}
}