diff --git a/activemq-gbean/.cvsignore b/activemq-gbean/.cvsignore new file mode 100755 index 0000000000..cfed26ff57 --- /dev/null +++ b/activemq-gbean/.cvsignore @@ -0,0 +1,8 @@ +target +.classpath +.project +*.iws +*.ipr +*.iml +build.properties +bin diff --git a/activemq-gbean/project.properties b/activemq-gbean/project.properties new file mode 100755 index 0000000000..ac1bf0f121 --- /dev/null +++ b/activemq-gbean/project.properties @@ -0,0 +1,9 @@ +# ------------------------------------------------------------------- +# Build Properties +# ------------------------------------------------------------------- +maven.multiproject.type=jar + +maven.repo.remote=\ +http://www.ibiblio.org/maven,\ +http://dist.codehaus.org,\ +http://cvs.apache.org/repository diff --git a/activemq-gbean/project.xml b/activemq-gbean/project.xml new file mode 100755 index 0000000000..aa78bcefe0 --- /dev/null +++ b/activemq-gbean/project.xml @@ -0,0 +1,81 @@ + + + + 3 + ${basedir}/../../etc/project.xml + + ActiveMQ :: GBeans + activemq-gbean + Geronimo / GBean support + ActiveMQ GBeans used for integration into Apache Geronimo + + org.activemq.gbean + + + Geronimo / GBean support + org.activemq.gbean + + + + + + + + + + activemq + activemq-core + ${pom.currentVersion} + + true + + + + activemq + activemq-gbean-management + ${pom.currentVersion} + + true + + + + activemq + activemq-core-test + ${pom.currentVersion} + + + + geronimo + geronimo-kernel + ${geronimo_kernel_version} + + + geronimo + geronimo-system + ${geronimo_system_version} + + + geronimo + geronimo-management + ${geronimo_management_version} + + + geronimo + geronimo-j2ee + ${geronimo_j2ee_version} + + + + activeio + activeio + ${activeio_version} + + + + mx4j + mx4j + ${mx4j_version} + + + + diff --git a/activemq-gbean/src/java/org/activemq/gbean/ActiveMQConnectorGBean.java b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQConnectorGBean.java new file mode 100755 index 0000000000..24701fa7a2 --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQConnectorGBean.java @@ -0,0 +1,179 @@ +/** + * + * Copyright 2004 Protique Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.gbean; + +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import javax.jms.JMSException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.gbean.GConstructorInfo; +import org.apache.geronimo.kernel.Kernel; +import org.activemq.ActiveMQConnectionFactory; +import org.activemq.broker.BrokerConnector; +import org.activemq.broker.impl.BrokerConnectorImpl; +import org.activemq.io.WireFormat; +import org.activemq.io.impl.DefaultWireFormat; + +/** + * Default implementation of the ActiveMQ connector + * + * @version $Revision: 1.1.1.1 $ + */ +public class ActiveMQConnectorGBean implements GBeanLifecycle, ActiveMQConnector { + private Log log = LogFactory.getLog(getClass().getName()); + + private BrokerConnector brokerConnector; + private ActiveMQContainer container; + private WireFormat wireFormat = new DefaultWireFormat(); + private String protocol; + private String host; + private int port; + private String path; + private String query; + private String urlAsStarted; + + public ActiveMQConnectorGBean(ActiveMQContainer container, String protocol, String host, int port) { + this.container = container; + this.protocol = protocol; + this.host = host; + this.port = port; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getUrl() { + try { + return new URI(protocol, null, host, port, path, query, null).toString(); + } catch (URISyntaxException e) { + throw new IllegalStateException("Attributes don't form a valid URI: "+protocol+"://"+host+":"+port+"/"+path+"?"+query); + } + } + + public WireFormat getWireFormat() { + return wireFormat; + } + + public void setWireFormat(WireFormat wireFormat) { + this.wireFormat = wireFormat; + } + + public InetSocketAddress getListenAddress() { + return brokerConnector == null ? null : brokerConnector.getServerChannel().getSocketAddress(); + } + + public synchronized void doStart() throws Exception { + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(ActiveMQContainerGBean.class.getClassLoader()); + try { + if (brokerConnector == null) { + urlAsStarted = getUrl(); + brokerConnector = createBrokerConnector(urlAsStarted); + brokerConnector.start(); + ActiveMQConnectionFactory.registerBroker(urlAsStarted, brokerConnector); + } + } finally { + Thread.currentThread().setContextClassLoader(old); + } + } + + public synchronized void doStop() throws Exception { + if (brokerConnector != null) { + ActiveMQConnectionFactory.unregisterBroker(urlAsStarted); + BrokerConnector temp = brokerConnector; + brokerConnector = null; + temp.stop(); + } + } + + public synchronized void doFail() { + if (brokerConnector != null) { + BrokerConnector temp = brokerConnector; + brokerConnector = null; + try { + temp.stop(); + } + catch (JMSException e) { + log.info("Caught while closing due to failure: " + e, e); + } + } + } + + protected BrokerConnector createBrokerConnector(String url) throws Exception { + return new BrokerConnectorImpl(container.getBrokerContainer(), url, wireFormat); + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Message Broker Connector", ActiveMQConnectorGBean.class, CONNECTOR_J2EE_TYPE); + infoFactory.addAttribute("url", String.class.getName(), false); + infoFactory.addAttribute("wireFormat", WireFormat.class.getName(), false); + infoFactory.addReference("activeMQContainer", ActiveMQContainer.class); + infoFactory.addInterface(ActiveMQConnector.class, new String[]{"host","port","protocol","path","query"}); + infoFactory.setConstructor(new GConstructorInfo(new String[]{"activeMQContainer", "protocol", "host", "port"})); + GBEAN_INFO = infoFactory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} diff --git a/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainer.java b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainer.java new file mode 100755 index 0000000000..e7189fe9f6 --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainer.java @@ -0,0 +1,41 @@ +/** + * + * Copyright 2004 Protique Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.gbean; + +import java.util.Properties; + +import org.activemq.broker.BrokerAdmin; +import org.activemq.broker.BrokerContainer; +import org.apache.geronimo.management.geronimo.JMSBroker; + +/** + * An interface to the ActiveMQContainerGBean for use by the + * ActiveMQConnectorGBean. + * + * @version $Revision: 1.1.1.1 $ + */ +public interface ActiveMQContainer extends ActiveMQBroker { + + public abstract BrokerContainer getBrokerContainer(); + public abstract BrokerAdmin getBrokerAdmin(); + + public String getBrokerName(); + public String getJaasConfiguration(); + public Properties getSecurityRoles(); + +} \ No newline at end of file diff --git a/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainerGBean.java b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainerGBean.java new file mode 100755 index 0000000000..741b1e00dd --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/gbean/ActiveMQContainerGBean.java @@ -0,0 +1,169 @@ +/** + * + * Copyright 2004 Protique Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.gbean; + +import java.util.Properties; +import javax.jms.JMSException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.activemq.broker.BrokerAdmin; +import org.activemq.broker.BrokerContainer; +import org.activemq.broker.BrokerContext; +import org.activemq.broker.impl.BrokerContainerImpl; +import org.activemq.security.jassjacc.JassJaccSecurityAdapter; +import org.activemq.security.jassjacc.PropertiesConfigLoader; +import org.activemq.store.PersistenceAdapter; + +/** + * Default implementation of the ActiveMQ Message Server + * + * @version $Revision: 1.1.1.1 $ + */ +public class ActiveMQContainerGBean implements GBeanLifecycle, ActiveMQContainer { + + private Log log = LogFactory.getLog(getClass().getName()); + + private final String brokerName; + + private BrokerContext context = BrokerContext.getInstance(); + private BrokerContainer container; + + private final PersistenceAdapter persistenceAdapter; + private final String jaasConfiguration; + private final Properties securityRoles; + + //default constructor for use as gbean endpoint. + public ActiveMQContainerGBean() { + brokerName = null; + jaasConfiguration = null; + securityRoles = null; + persistenceAdapter=null; + } + + public ActiveMQContainerGBean(String brokerName, PersistenceAdapter persistenceAdapter, String jaasConfiguration, Properties securityRoles) { + + assert brokerName != null; + assert persistenceAdapter != null; + + this.brokerName = brokerName; + this.jaasConfiguration=jaasConfiguration; + this.persistenceAdapter = persistenceAdapter; + this.securityRoles = securityRoles; + } + + public synchronized BrokerContainer getBrokerContainer() { + return container; + } + + /** + * @see org.activemq.gbean.ActiveMQContainer#getBrokerAdmin() + */ + public BrokerAdmin getBrokerAdmin() { + return container.getBroker().getBrokerAdmin(); + } + + public synchronized void doStart() throws Exception { + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(ActiveMQContainerGBean.class.getClassLoader()); + try { + if (container == null) { + container = createContainer(); + container.start(); + } + } finally { + Thread.currentThread().setContextClassLoader(old); + } + } + + public synchronized void doStop() throws Exception { + if (container != null) { + BrokerContainer temp = container; + container = null; + temp.stop(); + } + } + + public synchronized void doFail() { + if (container != null) { + BrokerContainer temp = container; + container = null; + try { + temp.stop(); + } + catch (JMSException e) { + log.info("Caught while closing due to failure: " + e, e); + } + } + } + + protected BrokerContainer createContainer() throws Exception { + BrokerContainerImpl answer = new BrokerContainerImpl(brokerName, context); + answer.setPersistenceAdapter( persistenceAdapter ); + if( jaasConfiguration != null ) { + answer.setSecurityAdapter(new JassJaccSecurityAdapter(jaasConfiguration)); + } + if( securityRoles != null ) { + // Install JACC configuration. + PropertiesConfigLoader loader = new PropertiesConfigLoader(brokerName, securityRoles); + loader.installSecurity(); + } + return answer; + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Message Broker", ActiveMQContainerGBean.class, "JMSServer"); + infoFactory.addAttribute("brokerName", String.class, true); + infoFactory.addReference("persistenceAdapter", PersistenceAdapter.class); + infoFactory.addAttribute("jaasConfiguration", String.class, true); + infoFactory.addAttribute("securityRoles", Properties.class, true); + infoFactory.addInterface(ActiveMQContainer.class); + infoFactory.setConstructor(new String[]{"brokerName", "persistenceAdapter", "jaasConfiguration", "securityRoles"}); + GBEAN_INFO = infoFactory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } + + /** + * @return Returns the brokerName. + */ + public String getBrokerName() { + return brokerName; + } + + /** + * @return Returns the jassConfiguration. + */ + public String getJaasConfiguration() { + return jaasConfiguration; + } + + /** + * @return Returns the securityRoles. + */ + public Properties getSecurityRoles() { + return securityRoles; + } + +} \ No newline at end of file diff --git a/activemq-gbean/src/java/org/activemq/gbean/management/ActiveMQManagerGBean.java b/activemq-gbean/src/java/org/activemq/gbean/management/ActiveMQManagerGBean.java new file mode 100644 index 0000000000..37700d189a --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/gbean/management/ActiveMQManagerGBean.java @@ -0,0 +1 @@ +/** * * Copyright 2004 Protique Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ package org.activemq.gbean.management; import java.util.Set; import java.util.Iterator; import java.util.ArrayList; import java.util.List; import java.util.Hashtable; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import org.activemq.gbean.ActiveMQManager; import org.activemq.gbean.ActiveMQBroker; import org.activemq.gbean.ActiveMQConnector; import org.activemq.gbean.ActiveMQConnectorGBean; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoBuilder; import org.apache.geronimo.gbean.GBeanQuery; import org.apache.geronimo.gbean.GBeanData; import org.apache.geronimo.kernel.Kernel; import org.apache.geronimo.kernel.GBeanNotFoundException; import org.apache.geronimo.j2ee.management.impl.Util; import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Implementation of the ActiveMQ management interface. These are the ActiveMQ * mangement features available at runtime. * * @version $Revision: 1.0$ */ public class ActiveMQManagerGBean implements ActiveMQManager { private static final Log log = LogFactory.getLog(ActiveMQManagerGBean.class.getName()); private Kernel kernel; public ActiveMQManagerGBean(Kernel kernel) { this.kernel = kernel; } public String[] getContainers() { GBeanQuery query = new GBeanQuery(null, ActiveMQBroker.class.getName()); Set set = kernel.listGBeans(query); String[] results = new String[set.size()]; int i=0; for (Iterator it = set.iterator(); it.hasNext();) { ObjectName name = (ObjectName) it.next(); results[i++] = name.getCanonicalName(); } return results; } public String[] getSupportedProtocols() { // see files in modules/core/src/conf/META-INF/services/org/activemq/transport/server/ return new String[]{"activeio","jabber","multicast","openwire","peer","stomp","tcp","udp","vm",}; } public String[] getConnectors() { GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName()); Set set = kernel.listGBeans(query); String[] results = new String[set.size()]; int i=0; for (Iterator it = set.iterator(); it.hasNext();) { ObjectName name = (ObjectName) it.next(); results[i++] = name.getCanonicalName(); } return results; } public String[] getConnectors(String protocol) { if(protocol == null) { return getConnectors(); } GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName()); Set set = kernel.listGBeans(query); List results = new ArrayList(); for (Iterator it = set.iterator(); it.hasNext();) { ObjectName name = (ObjectName) it.next(); try { String target = (String) kernel.getAttribute(name, "protocol"); if(target != null && target.equals(protocol)) { results.add(name.getCanonicalName()); } } catch (Exception e) { log.error("Unable to look up protocol for connector '"+name+"'",e); } } return (String[]) results.toArray(new String[results.size()]); } public String[] getConnectorsForContainer(String broker) { try { ObjectName brokerName = ObjectName.getInstance(broker); List results = new ArrayList(); GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName()); Set set = kernel.listGBeans(query); // all ActiveMQ connectors for (Iterator it = set.iterator(); it.hasNext();) { ObjectName name = (ObjectName) it.next(); // a single ActiveMQ connector GBeanData data = kernel.getGBeanData(name); Set refs = data.getReferencePatterns("activeMQContainer"); for (Iterator refit = refs.iterator(); refit.hasNext();) { ObjectName ref = (ObjectName) refit.next(); if(ref.isPattern()) { Set matches = kernel.listGBeans(ref); if(matches.size() != 1) { log.error("Unable to compare a connector->container reference that's a pattern to a fixed container name: "+ref.getCanonicalName()); } else { ref = (ObjectName)matches.iterator().next(); if(ref.equals(brokerName)) { results.add(name.getCanonicalName()); break; } } } else { if(ref.equals(brokerName)) { results.add(name.getCanonicalName()); break; } } } } return (String[]) results.toArray(new String[results.size()]); } catch (Exception e) { throw new IllegalArgumentException("Unable to look up connectors for broker '"+broker+"': "+e); } } public String[] getConnectorsForContainer(String broker, String protocol) { if(protocol == null) { return getConnectorsForContainer(broker); } try { ObjectName brokerName = ObjectName.getInstance(broker); List results = new ArrayList(); GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName()); Set set = kernel.listGBeans(query); // all ActiveMQ connectors for (Iterator it = set.iterator(); it.hasNext();) { ObjectName name = (ObjectName) it.next(); // a single ActiveMQ connector GBeanData data = kernel.getGBeanData(name); Set refs = data.getReferencePatterns("activeMQContainer"); for (Iterator refit = refs.iterator(); refit.hasNext();) { ObjectName ref = (ObjectName) refit.next(); boolean match = false; if(ref.isPattern()) { Set matches = kernel.listGBeans(ref); if(matches.size() != 1) { log.error("Unable to compare a connector->container reference that's a pattern to a fixed container name: "+ref.getCanonicalName()); } else { ref = (ObjectName)matches.iterator().next(); if(ref.equals(brokerName)) { match = true; } } } else { if(ref.equals(brokerName)) { match = true; } } if(match) { try { String testProtocol = (String) kernel.getAttribute(name, "protocol"); if(testProtocol != null && testProtocol.equals(protocol)) { results.add(name.getCanonicalName()); } } catch (Exception e) { log.error("Unable to look up protocol for connector '"+name+"'",e); } break; } } } return (String[]) results.toArray(new String[results.size()]); } catch (Exception e) { throw new IllegalArgumentException("Unable to look up connectors for broker '"+broker+"': "+e); } } /** * Creates a new connector, and returns the ObjectName for it. Note that * the connector may well require further customization before being fully * functional (e.g. SSL settings for a secure connector). */ public String addConnector(String broker, String uniqueName, String protocol, String host, int port) { ObjectName brokerName = null; try { brokerName = ObjectName.getInstance(broker); } catch (MalformedObjectNameException e) { throw new IllegalArgumentException("Unable to parse ObjectName '"+broker+"'"); } ObjectName name = getConnectorName(brokerName, protocol, host, port, uniqueName); GBeanData connector = new GBeanData(name, ActiveMQConnectorGBean.GBEAN_INFO); //todo: if SSL is supported, need to add more properties or use a different GBean? connector.setAttribute("protocol", protocol); connector.setAttribute("host", host); connector.setAttribute("port", new Integer(port)); connector.setReferencePattern("activeMQContainer", brokerName); ObjectName config = Util.getConfiguration(kernel, brokerName); try { kernel.invoke(config, "addGBean", new Object[]{connector, Boolean.FALSE}, new String[]{GBeanData.class.getName(), boolean.class.getName()}); } catch (Exception e) { log.error("Unable to add GBean ", e); return null; } return name.getCanonicalName(); } public void removeConnector(String objectName) { ObjectName name = null; try { name = ObjectName.getInstance(objectName); } catch (MalformedObjectNameException e) { throw new IllegalArgumentException("Invalid object name '" + objectName + "': " + e.getMessage()); } try { GBeanInfo info = kernel.getGBeanInfo(name); boolean found = false; Set intfs = info.getInterfaces(); for (Iterator it = intfs.iterator(); it.hasNext();) { String intf = (String) it.next(); if (intf.equals(ActiveMQConnector.class.getName())) { found = true; } } if (!found) { throw new GBeanNotFoundException(name); } ObjectName config = Util.getConfiguration(kernel, name); kernel.invoke(config, "removeGBean", new Object[]{name}, new String[]{ObjectName.class.getName()}); } catch (GBeanNotFoundException e) { log.warn("No such GBean '" + objectName + "'"); //todo: what if we want to remove a failed GBean? } catch (Exception e) { log.error("Unable to remove GBean", e); } } /** * Generate an ObjectName for a new connector GBean */ private ObjectName getConnectorName(ObjectName broker, String protocol, String host, int port, String uniqueName) { Hashtable table = new Hashtable(); table.put(NameFactory.J2EE_APPLICATION, broker.getKeyProperty(NameFactory.J2EE_APPLICATION)); table.put(NameFactory.J2EE_SERVER, broker.getKeyProperty(NameFactory.J2EE_SERVER)); table.put(NameFactory.J2EE_MODULE, broker.getKeyProperty(NameFactory.J2EE_MODULE)); table.put(NameFactory.J2EE_TYPE, ActiveMQConnector.CONNECTOR_J2EE_TYPE); String brokerName = broker.getKeyProperty(NameFactory.J2EE_NAME); table.put("broker", brokerName); table.put(NameFactory.J2EE_NAME, brokerName+"."+protocol+"."+host+(port > -1 ? "."+port : "")+"-"+uniqueName); try { return ObjectName.getInstance(broker.getDomain(), table); } catch (MalformedObjectNameException e) { throw new IllegalStateException("Never should have failed: " + e.getMessage()); } } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Manager", ActiveMQManagerGBean.class); infoFactory.addAttribute("kernel", Kernel.class, false); infoFactory.addInterface(ActiveMQManager.class); infoFactory.setConstructor(new String[]{"kernel"}); GBEAN_INFO = infoFactory.getBeanInfo(); } public static GBeanInfo getGBeanInfo() { return GBEAN_INFO; } } \ No newline at end of file diff --git a/activemq-gbean/src/java/org/activemq/gbean/package.html b/activemq-gbean/src/java/org/activemq/gbean/package.html new file mode 100755 index 0000000000..a30d48d3de --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/gbean/package.html @@ -0,0 +1,11 @@ + + + + + +

+ The JMS container using GBeaps for deployment in Geronimo or other JSR 77/88 based containers +

+ + + diff --git a/activemq-gbean/src/java/org/activemq/store/cache/SimpleCachePersistenceAdapterGBean.java b/activemq-gbean/src/java/org/activemq/store/cache/SimpleCachePersistenceAdapterGBean.java new file mode 100755 index 0000000000..add0cac8bb --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/store/cache/SimpleCachePersistenceAdapterGBean.java @@ -0,0 +1,103 @@ +/** + * + * Copyright 2004 Hiram Chirino + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.store.cache; + +import java.util.Map; + +import javax.jms.JMSException; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.activemq.store.MessageStore; +import org.activemq.store.PersistenceAdapter; +import org.activemq.store.TopicMessageStore; +import org.activemq.store.TransactionStore; + +/** + * + */ +public class SimpleCachePersistenceAdapterGBean implements GBeanLifecycle, PersistenceAdapter { + + private final PersistenceAdapter longTermPersistence; + private SimpleCachePersistenceAdapter persistenceAdapter; + private final int cacheSize; + + public SimpleCachePersistenceAdapterGBean() { + this(null, 0); + } + + public SimpleCachePersistenceAdapterGBean(PersistenceAdapter longTermPersistence, int cacheSize) { + this.longTermPersistence = longTermPersistence; + this.cacheSize = cacheSize; + } + + public void doStart() throws Exception { + persistenceAdapter = new SimpleCachePersistenceAdapter(); + persistenceAdapter.setLongTermPersistence(longTermPersistence); + persistenceAdapter.setCacheSize(cacheSize); + persistenceAdapter.start(); + } + + public void doStop() throws Exception { + persistenceAdapter.stop(); + persistenceAdapter = null; + } + + public void doFail() { + } + + public static final GBeanInfo GBEAN_INFO; + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Persistence Cache", SimpleCachePersistenceAdapterGBean.class, "JMSPersistence"); + infoFactory.addReference("longTermPersistence", PersistenceAdapter.class); + infoFactory.addAttribute("cacheSize", int.class, true); + infoFactory.addInterface(PersistenceAdapter.class); + infoFactory.setConstructor(new String[]{"longTermPersistence", "cacheSize"}); + GBEAN_INFO = infoFactory.getBeanInfo(); + } + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } + + public void beginTransaction() throws JMSException { + persistenceAdapter.beginTransaction(); + } + public void commitTransaction() throws JMSException { + persistenceAdapter.commitTransaction(); + } + public MessageStore createQueueMessageStore(String destinationName) throws JMSException { + return persistenceAdapter.createQueueMessageStore(destinationName); + } + public TopicMessageStore createTopicMessageStore(String destinationName) throws JMSException { + return persistenceAdapter.createTopicMessageStore(destinationName); + } + public TransactionStore createTransactionStore() throws JMSException { + return persistenceAdapter.createTransactionStore(); + } + public Map getInitialDestinations() { + return persistenceAdapter.getInitialDestinations(); + } + public void rollbackTransaction() { + persistenceAdapter.rollbackTransaction(); + } + public void start() throws JMSException { + } + public void stop() throws JMSException { + } +} diff --git a/activemq-gbean/src/java/org/activemq/store/jdbc/JDBCPersistenceAdapterGBean.java b/activemq-gbean/src/java/org/activemq/store/jdbc/JDBCPersistenceAdapterGBean.java new file mode 100755 index 0000000000..8cd87afe94 --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/store/jdbc/JDBCPersistenceAdapterGBean.java @@ -0,0 +1,100 @@ +/** + * + * Copyright 2004 Hiram Chirino + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.store.jdbc; + +import java.util.Map; + +import javax.jms.JMSException; +import javax.sql.DataSource; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.activemq.store.MessageStore; +import org.activemq.store.PersistenceAdapter; +import org.activemq.store.TopicMessageStore; +import org.activemq.store.TransactionStore; + +/** + * + */ +public class JDBCPersistenceAdapterGBean implements GBeanLifecycle, PersistenceAdapter { + + JDBCPersistenceAdapter pa; + private final ResourceManager resourceManager; + + public JDBCPersistenceAdapterGBean() { + this(null); + } + + public JDBCPersistenceAdapterGBean(ResourceManager dataSource) { + this.resourceManager = dataSource; + } + + public void doStart() throws Exception { + pa = new JDBCPersistenceAdapter(); + pa.setDataSource((DataSource) resourceManager.$getResource()); + pa.start(); + } + + public void doStop() throws Exception { + pa.stop(); + pa = null; + } + + public void doFail() { + } + + public static final GBeanInfo GBEAN_INFO; + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ JDBC Persistence", JDBCPersistenceAdapterGBean.class, "JMSPersistence"); + infoFactory.addReference("dataSource", ResourceManager.class); + infoFactory.addInterface(PersistenceAdapter.class); + infoFactory.setConstructor(new String[]{"dataSource"}); + GBEAN_INFO = infoFactory.getBeanInfo(); + } + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } + + public void beginTransaction() throws JMSException { + pa.beginTransaction(); + } + public void commitTransaction() throws JMSException { + pa.commitTransaction(); + } + public MessageStore createQueueMessageStore(String destinationName) throws JMSException { + return pa.createQueueMessageStore(destinationName); + } + public TopicMessageStore createTopicMessageStore(String destinationName) throws JMSException { + return pa.createTopicMessageStore(destinationName); + } + public TransactionStore createTransactionStore() throws JMSException { + return pa.createTransactionStore(); + } + public Map getInitialDestinations() { + return pa.getInitialDestinations(); + } + public void rollbackTransaction() { + pa.rollbackTransaction(); + } + public void start() throws JMSException { + } + public void stop() throws JMSException { + } +} diff --git a/activemq-gbean/src/java/org/activemq/store/jdbc/ResourceManager.java b/activemq-gbean/src/java/org/activemq/store/jdbc/ResourceManager.java new file mode 100755 index 0000000000..34fa3b7232 --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/store/jdbc/ResourceManager.java @@ -0,0 +1,25 @@ +/** + * + * Copyright 2004 Hiram Chirino + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.store.jdbc; + +/** + * + */ +public interface ResourceManager { + public Object $getResource(); +} diff --git a/activemq-gbean/src/java/org/activemq/store/journal/JournalPersistenceAdapterGBean.java b/activemq-gbean/src/java/org/activemq/store/journal/JournalPersistenceAdapterGBean.java new file mode 100755 index 0000000000..a4ea3c86a5 --- /dev/null +++ b/activemq-gbean/src/java/org/activemq/store/journal/JournalPersistenceAdapterGBean.java @@ -0,0 +1,112 @@ +/** + * + * Copyright 2004 Hiram Chirino + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.store.journal; + +import java.util.Map; + +import javax.jms.JMSException; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.system.serverinfo.ServerInfo; +import org.activemq.store.MessageStore; +import org.activemq.store.PersistenceAdapter; +import org.activemq.store.TopicMessageStore; +import org.activemq.store.TransactionStore; + +/** + * + */ +public class JournalPersistenceAdapterGBean implements GBeanLifecycle, PersistenceAdapter { + + private final PersistenceAdapter longTermPersistence; + private final ServerInfo serverInfo; + private final String directory; + private JournalPersistenceAdapter persistenceAdapter; + private final String journalType; + + public JournalPersistenceAdapterGBean() { + this(null, null, null, null); + } + + public JournalPersistenceAdapterGBean(ServerInfo serverInfo, PersistenceAdapter longTermPersistence, String directory, String journalType) { + this.serverInfo = serverInfo; + this.longTermPersistence = longTermPersistence; + this.directory = directory; + this.journalType = journalType; + } + + public void doStart() throws Exception { + persistenceAdapter = new JournalPersistenceAdapter(); + persistenceAdapter.setLongTermPersistence(longTermPersistence); + persistenceAdapter.setDirectory(serverInfo.resolve(directory)); + persistenceAdapter.setJournalType(journalType); + persistenceAdapter.start(); + } + + public void doStop() throws Exception { + persistenceAdapter.stop(); + persistenceAdapter = null; + } + + public void doFail() { + } + + public static final GBeanInfo GBEAN_INFO; + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Persistence Journal", JournalPersistenceAdapterGBean.class, "JMSPersistence"); + infoFactory.addReference("serverInfo", ServerInfo.class); + infoFactory.addReference("longTermPersistence", PersistenceAdapter.class); + infoFactory.addAttribute("directory", String.class, true); + infoFactory.addAttribute("journalType", String.class, true); + infoFactory.addInterface(PersistenceAdapter.class); + infoFactory.setConstructor(new String[]{"serverInfo", "longTermPersistence", "directory", "journalType"}); + GBEAN_INFO = infoFactory.getBeanInfo(); + } + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } + + public void beginTransaction() throws JMSException { + persistenceAdapter.beginTransaction(); + } + public void commitTransaction() throws JMSException { + persistenceAdapter.commitTransaction(); + } + + public MessageStore createQueueMessageStore(String destinationName) throws JMSException { + return persistenceAdapter.createQueueMessageStore(destinationName); + } + public TopicMessageStore createTopicMessageStore(String destinationName) throws JMSException { + return persistenceAdapter.createTopicMessageStore(destinationName); + } + public TransactionStore createTransactionStore() throws JMSException { + return persistenceAdapter.createTransactionStore(); + } + public Map getInitialDestinations() { + return persistenceAdapter.getInitialDestinations(); + } + public void rollbackTransaction() { + persistenceAdapter.rollbackTransaction(); + } + public void start() throws JMSException { + } + public void stop() throws JMSException { + } +} diff --git a/activemq-gbean/src/test/org/activemq/gbean/ConnectorTest.java b/activemq-gbean/src/test/org/activemq/gbean/ConnectorTest.java new file mode 100644 index 0000000000..db070de2cc --- /dev/null +++ b/activemq-gbean/src/test/org/activemq/gbean/ConnectorTest.java @@ -0,0 +1,60 @@ +/** + * + * Copyright 2004 Protique Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +package org.activemq.gbean; + +import junit.framework.TestCase; + +/** + * Tests to ensure that URL parsing and updating doesn't blow up + * + * @version $Revision: 1.0$ + */ +public class ConnectorTest extends TestCase { + public ActiveMQConnectorGBean test; + + protected void setUp() throws Exception { + } + + public void testURLManipulation() { + test = new ActiveMQConnectorGBean(null, "foo", "localhost", 1234); + assertEquals("foo://localhost:1234", test.getUrl()); + assertEquals("foo", test.getProtocol()); + assertEquals("localhost", test.getHost()); + assertEquals(1234, test.getPort()); + test.setHost("0.0.0.0"); + assertEquals("foo://0.0.0.0:1234", test.getUrl()); + assertEquals("foo", test.getProtocol()); + assertEquals("0.0.0.0", test.getHost()); + assertEquals(1234, test.getPort()); + test.setPort(8765); + assertEquals("foo://0.0.0.0:8765", test.getUrl()); + assertEquals("foo", test.getProtocol()); + assertEquals("0.0.0.0", test.getHost()); + assertEquals(8765, test.getPort()); + test.setProtocol("bar"); + assertEquals("bar://0.0.0.0:8765", test.getUrl()); + assertEquals("bar", test.getProtocol()); + assertEquals("0.0.0.0", test.getHost()); + assertEquals(8765, test.getPort()); + test = new ActiveMQConnectorGBean(null, "vm", "localhost", -1); + assertEquals("vm://localhost", test.getUrl()); + assertEquals("vm", test.getProtocol()); + assertEquals("localhost", test.getHost()); + assertEquals(-1, test.getPort()); + } +}