From b9f8460f163115b60e5a840bf63c814d72bc8b85 Mon Sep 17 00:00:00 2001 From: David BRASSELY Date: Thu, 6 Feb 2014 10:09:46 +0100 Subject: [PATCH] Provide a new way to configure instance by using yaml. --- openesb-standalone-framework/pom.xml | 15 + .../standalone/framework/JSEJBIFramework.java | 271 ++++++++++-------- .../framework/JSEPlatformContext.java | 8 +- .../settings/ImmutableSettings.java | 72 +++++ .../openesb/standalone/settings/Settings.java | 35 +++ .../settings/SettingsException.java | 18 ++ pom.xml | 2 + 7 files changed, 297 insertions(+), 124 deletions(-) create mode 100644 openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/ImmutableSettings.java create mode 100644 openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/Settings.java create mode 100644 openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/SettingsException.java diff --git a/openesb-standalone-framework/pom.xml b/openesb-standalone-framework/pom.xml index 06398e4..a9c68ca 100644 --- a/openesb-standalone-framework/pom.xml +++ b/openesb-standalone-framework/pom.xml @@ -39,5 +39,20 @@ transactions-jta ${atomikos.version} + + + + + + org.yaml + snakeyaml + ${snakeyaml.version} + diff --git a/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEJBIFramework.java b/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEJBIFramework.java index 60d4376..b69cac2 100644 --- a/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEJBIFramework.java +++ b/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEJBIFramework.java @@ -29,10 +29,15 @@ package net.openesb.standalone.framework; import com.sun.jndi.rmi.registry.RegistryContextFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; import java.rmi.server.UnicastRemoteObject; import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,189 +47,215 @@ import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; +//import net.openesb.standalone.node.Node; +//import net.openesb.standalone.node.NodeBuilder; +import net.openesb.standalone.settings.ImmutableSettings; +import net.openesb.standalone.settings.Settings; +import org.yaml.snakeyaml.Yaml; /** - * JBI framework wrapper for Java SE platform. - *

- * A JSEJBIFramework instance cannot be loaded multiple times in the same - * VM. If multiple instances of the framework are required in a VM, - * instantiate multiple instances of JSEJBIFramework and load each one - * independently. There is no limit on the number of uniquely named - * JSEJBIFramework instances in the same VM. A specific JSEJBIFramework instance - * can be loaded and unloaded multiple times in a VM. + * JBI framework wrapper for Java SE platform. + *

+ * A JSEJBIFramework instance cannot be loaded multiple times in the same VM. If + * multiple instances of the framework are required in a VM, instantiate + * multiple instances of JSEJBIFramework and load each one independently. There + * is no limit on the number of uniquely named JSEJBIFramework instances in the + * same VM. A specific JSEJBIFramework instance can be loaded and unloaded + * multiple times in a VM. * * @author Sun Microsystems, Inc. */ -public class JSEJBIFramework +public class JSEJBIFramework extends com.sun.jbi.framework.JBIFramework - implements JSEJBIFrameworkMBean -{ + implements JSEJBIFrameworkMBean { + + public static final String CONFIG_FILE = "openesb.config"; public static final String INSTALL_ROOT = "install.root"; public static final String INSTANCE_NAME = "instance.name"; - public static final String CONNECTOR_PORT = "connector.port"; - - /** Configuration defaults. */ + public static final String CONNECTOR_PORT = "instance.port"; + /** + * Configuration defaults. + */ private static final String DEFAULT_INSTALL_ROOT = System.getProperty("user.dir"); private static final String DEFAULT_INSTANCE_NAME = "server"; - private static final String DEFAULT_CONNECTOR_PORT = "8699"; - - private JSEPlatformContext mPlatformContext; - private boolean mLoaded; - private Properties mEnvironment; - private JMXConnectorServer mJMXServer; - private Registry mRegistry; - private Logger mLog = + private static final int DEFAULT_CONNECTOR_PORT = 8699; + private JSEPlatformContext mPlatformContext; + private boolean mLoaded; + private Properties mEnvironment; + private JMXConnectorServer mJMXServer; + private Registry mRegistry; + private Logger mLog = Logger.getLogger(this.getClass().getPackage().getName()); - - /** Creates a new instance of the JBI framework. +// private Node instanceNode; + private Settings settings; + + /** + * Creates a new instance of the JBI framework. */ - public JSEJBIFramework(Properties environment) - { + public JSEJBIFramework(Properties environment) { super(); - + mEnvironment = environment; - mPlatformContext = new JSEPlatformContext( - mEnvironment.getProperty(INSTANCE_NAME, DEFAULT_INSTANCE_NAME), - mEnvironment.getProperty(INSTALL_ROOT, DEFAULT_INSTALL_ROOT), - mEnvironment.getProperty(CONNECTOR_PORT, DEFAULT_CONNECTOR_PORT)); } - - /** Load the JBI framework with the specified environment. When this method - * retuns, all public interfaces and system services have completely - * initialized. If a connector port is specified in the environment - * properties, a remote JMX connector server is created. - * @throws Exception failed to load JBI framework - */ - public synchronized void load() - throws Exception - { - if (mLoaded) - { - throw new IllegalStateException("JBI framework already loaded!"); + + private void init() throws Exception { + String installRoot = mEnvironment.getProperty(INSTALL_ROOT, DEFAULT_INSTALL_ROOT); + + String configFile = mEnvironment.getProperty(CONFIG_FILE); + + if (configFile == null) { + configFile = installRoot + File.separatorChar + "config/openesb.yaml"; + } + + mLog.log(Level.INFO, "Loading configuration from {0}", configFile); + + try { + Yaml yaml = new Yaml(); + InputStream input = new FileInputStream(new File(configFile)); + settings = new ImmutableSettings((Map) yaml.load(input)); + } catch (FileNotFoundException fnfe) { + mLog.log(Level.WARNING, "Unable to load configuration file {0}. Default configuration will be used.", configFile); + settings = new ImmutableSettings(null); } + mPlatformContext = new JSEPlatformContext( + installRoot, + settings.get(INSTANCE_NAME, DEFAULT_INSTANCE_NAME), + settings.getAsInt(CONNECTOR_PORT, DEFAULT_CONNECTOR_PORT)); + } + + /** + * Load the JBI framework with the specified environment. When this method + * retuns, all public interfaces and system services have completely + * initialized. If a connector port is specified in the environment + * properties, a remote JMX connector server is created. + * + * @throws Exception failed to load JBI framework + */ + @Override + public synchronized void load() + throws Exception { + if (mLoaded) { + throw new IllegalStateException("JBI framework already loaded!"); + } + + this.init(); + // Register a management MBean for this framework instance - ObjectName fwMBeanName = new ObjectName("com.sun.jbi.jse", + ObjectName fwMBeanName = new ObjectName("com.sun.jbi.jse", "instance", mPlatformContext.getInstanceName()); MBeanServer mbs = mPlatformContext.getMBeanServer(); - if (mbs.isRegistered(fwMBeanName)) - { - if (mbs.getAttribute(fwMBeanName, "Loaded").equals(Boolean.TRUE)) - { + if (mbs.isRegistered(fwMBeanName)) { + if (mbs.getAttribute(fwMBeanName, "Loaded").equals(Boolean.TRUE)) { // Framework already loaded from a separate thread/process - throw new IllegalStateException("JBI framework instance " + - mPlatformContext.getInstanceName() + " has already been loaded"); - } - else - { + throw new IllegalStateException("JBI framework instance " + + mPlatformContext.getInstanceName() + " has already been loaded"); + } else { // MBean should not be registered - try to clean up - mbs.unregisterMBean(fwMBeanName); + mbs.unregisterMBean(fwMBeanName); } } mbs.registerMBean(this, fwMBeanName); - + // Setup the remote JMX connector server - String portStr = mEnvironment.getProperty(CONNECTOR_PORT); - if (portStr != null) - { - try - { - int port = Integer.parseInt(portStr); - createJMXConnectorServer(port); - } - catch (NumberFormatException nfEx) - { - mLog.log(Level.WARNING, "Invalid connector server port: {0}. Remote JMX connector will not be created.", portStr); - } + Integer port = null; + + try { + port = settings.getAsInt(CONNECTOR_PORT, DEFAULT_CONNECTOR_PORT); + createJMXConnectorServer(port); + } catch (NumberFormatException nfEx) { + mLog.log(Level.WARNING, "Invalid connector server port: {0}. Remote JMX connector will not be created.", port); } - + // For stand-alone JBI, JBI_HOME = platform install root - mEnvironment.setProperty("com.sun.jbi.home", + mEnvironment.setProperty("com.sun.jbi.home", mPlatformContext.getInstallRoot()); - - init(mPlatformContext, mEnvironment); - startup(mPlatformContext.getNamingContext(), ""); + + init(mPlatformContext, mEnvironment); + startup(mPlatformContext.getNamingContext(), ""); prepare(); ready(true); - + + // instanceNode = NodeBuilder.nodeBuilder(settings).build(); + + // instanceNode.start(); + // JBI framework has been loaded mLoaded = true; } - - /** Queries the state of the JBI Framework. - * @return true if the JBI framework is loaded, false otherwise. + + /** + * Queries the state of the JBI Framework. + * + * @return true if the JBI framework is loaded, false otherwise. */ - public boolean isLoaded() - { + @Override + public boolean isLoaded() { return mLoaded; } - - /** Unloads the JBI framework. When this method retuns, all - * public interfaces, system services, and JMX connector (if configured) - * have been destroyed. - * @throws javax.jbi.JBIException failed to unload JBI framework + + /** + * Unloads the JBI framework. When this method retuns, all public + * interfaces, system services, and JMX connector (if configured) have been + * destroyed. + * + * @throws javax.jbi.JBIException failed to unload JBI framework */ + @Override public void unload() - throws Exception - { - if (!mLoaded) - { + throws Exception { + if (!mLoaded) { return; } - + + // instanceNode.stop(); + shutdown(); terminate(); - - try - { + + try { mJMXServer.stop(); UnicastRemoteObject.unexportObject(mRegistry, true); - } - catch (Exception ex) - { + } catch (Exception ex) { mLog.log(Level.SEVERE, "Error during framework shutdown: {0}", ex.toString()); } - + mLoaded = false; } - - public JMXServiceURL getServiceURL(int port) - throws java.net.MalformedURLException - { + + private JMXServiceURL getServiceURL(int port) + throws java.net.MalformedURLException { return new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi"); } - - /** Creates a JMX connector server at the specified port. - * @param port port for the JMX connector server. + + /** + * Creates a JMX connector server at the specified port. + * + * @param port port for the JMX connector server. */ - private void createJMXConnectorServer(int port) - { + private void createJMXConnectorServer(int port) { HashMap map = new HashMap(); - + /* - map.put("java.naming.factory.initial", - RegistryContextFactory.class.getName()); - */ - try - { + map.put("java.naming.factory.initial", + RegistryContextFactory.class.getName()); + */ + try { // Create the service URL JMXServiceURL serviceURL = getServiceURL(port); - + // Create an RMI registry instance to hold the JMX connector server mRegistry = LocateRegistry.createRegistry(port); - + // Create and start the connector server mJMXServer = JMXConnectorServerFactory.newJMXConnectorServer( - serviceURL, map, mPlatformContext.getMBeanServer()); + serviceURL, map, mPlatformContext.getMBeanServer()); mJMXServer.start(); - - mLog.log(Level.INFO, "remote JMX connector available at {0}", mJMXServer.getAddress()); - } - catch (Exception ex) - { + + mLog.log(Level.INFO, "remote JMX connector available at {0}", mJMXServer.getAddress()); + } catch (Exception ex) { mLog.log(Level.SEVERE, "Failed to create remote JMX connector: {0}", ex.toString()); } } - } diff --git a/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEPlatformContext.java b/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEPlatformContext.java index 4a213a3..97385be 100644 --- a/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEPlatformContext.java +++ b/openesb-standalone-framework/src/main/java/net/openesb/standalone/framework/JSEPlatformContext.java @@ -56,13 +56,13 @@ public class JSEPlatformContext implements com.sun.jbi.platform.PlatformContext private String mInstanceName; private String mInstanceRoot; private String mInstallRoot; - private String mConnectorPort; + private int mConnectorPort; private InitialContext mNamingContext; private Logger mLog = Logger.getLogger(getClass().getPackage().getName()); - public JSEPlatformContext(String instanceName, String installRoot, String connectorPort) { - mInstanceName = instanceName; + public JSEPlatformContext(String installRoot, String instanceName, int connectorPort) { mInstallRoot = installRoot; + mInstanceName = instanceName; mInstanceRoot = installRoot + File.separator + instanceName; mConnectorPort = connectorPort; @@ -273,7 +273,7 @@ public class JSEPlatformContext implements com.sun.jbi.platform.PlatformContext * @return the JMX RMI connector port as a String. */ public String getJmxRmiPort() { - return mConnectorPort; + return Integer.toString(mConnectorPort); } /** diff --git a/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/ImmutableSettings.java b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/ImmutableSettings.java new file mode 100644 index 0000000..4ab7bc7 --- /dev/null +++ b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/ImmutableSettings.java @@ -0,0 +1,72 @@ +package net.openesb.standalone.settings; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * An immutable implementation of {@link Settings}. + * + * @author David BRASSELY (brasseld at gmail.com) + * @author OpenESB Community + */ +public class ImmutableSettings implements Settings { + + private final Map settings; + + public ImmutableSettings(Map settings) { + if (settings != null) { + this.settings = Collections.unmodifiableMap(settings); + } else { + this.settings = Collections.unmodifiableMap(new HashMap()); + } + } + + @Override + public String get(String setting) { + String retVal = settings.get(setting); + if (retVal != null) { + return retVal; + } + + return null; + } + + @Override + public String get(String setting, String defaultValue) { + String retVal = get(setting); + return retVal == null ? defaultValue : retVal; + } + + @Override + public Boolean getAsBoolean(String setting, Boolean defaultValue) { + return parseBoolean(get(setting), defaultValue); + } + + @Override + public Integer getAsInt(String setting, Integer defaultValue) throws SettingsException { + String sValue = get(setting); + if (sValue == null) { + return defaultValue; + } + try { + return Integer.parseInt(sValue); + } catch (NumberFormatException e) { + throw new SettingsException("Failed to parse int setting [" + setting + "] with value [" + sValue + "]", e); + } + } + + public static boolean parseBoolean(String value, boolean defaultValue) { + if (value == null) { + return defaultValue; + } + return !(value.equals("false") || value.equals("0") || value.equals("off") || value.equals("no")); + } + + public static Boolean parseBoolean(String value, Boolean defaultValue) { + if (value == null) { + return defaultValue; + } + return !(value.equals("false") || value.equals("0") || value.equals("off") || value.equals("no")); + } +} \ No newline at end of file diff --git a/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/Settings.java b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/Settings.java new file mode 100644 index 0000000..259727b --- /dev/null +++ b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/Settings.java @@ -0,0 +1,35 @@ +package net.openesb.standalone.settings; + +/** + * + * @author David BRASSELY (brasseld at gmail.com) + * @author OpenESB Community + */ +public interface Settings { + + /** + * Returns the setting value associated with the setting key. + * + * @param setting The setting key + * @return The setting value, null if it does not exists. + */ + String get(String setting); + + /** + * Returns the setting value associated with the setting key. If it does not exists, + * returns the default value provided. + */ + String get(String setting, String defaultValue); + + /** + * Returns the setting value (as int) associated with the setting key. If it does not exists, + * returns the default value provided. + */ + Integer getAsInt(String setting, Integer defaultValue) throws SettingsException; + + /** + * Returns the setting value (as boolean) associated with the setting key. If it does not exists, + * returns the default value provided. + */ + Boolean getAsBoolean(String setting, Boolean defaultValue) throws SettingsException; +} diff --git a/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/SettingsException.java b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/SettingsException.java new file mode 100644 index 0000000..ab4bd7d --- /dev/null +++ b/openesb-standalone-framework/src/main/java/net/openesb/standalone/settings/SettingsException.java @@ -0,0 +1,18 @@ +package net.openesb.standalone.settings; + +/** + * A generic failure to handle settings. + * + * @author David BRASSELY (brasseld at gmail.com) + * @author OpenESB Community + */ +public class SettingsException extends RuntimeException { + + public SettingsException(String message) { + super(message); + } + + public SettingsException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/pom.xml b/pom.xml index 0ea0b52..9188208 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,8 @@ 1.0.0-SNAPSHOT 3.8.0 7.0.47 + 1.13 +