You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2017/07/05 09:37:06 UTC

[1/8] tomee git commit: Proposal to move the Mdb control logic from ActiveMQ to the MdbContainer

Repository: tomee
Updated Branches:
  refs/heads/master 6557c439a -> 04ab19bac


Proposal to move the Mdb control logic from ActiveMQ to the MdbContainer


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/0472e39e
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/0472e39e
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/0472e39e

Branch: refs/heads/master
Commit: 0472e39eea754b43201cf11ea8f9080919aded26
Parents: 9202bd0
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Fri Jun 23 15:31:44 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Fri Jun 23 16:29:52 2017 +0100

----------------------------------------------------------------------
 .../apache/openejb/core/mdb/MdbContainer.java   | 185 +++++++++++++++++-
 .../activemq/ActiveMQResourceAdapter.java       | 148 --------------
 .../core/mdb/ResourceAdapterControlTest.java    | 194 +++++++++++++++++++
 .../ActiveMQResourceAdapterControlTest.java     | 192 ------------------
 4 files changed, 375 insertions(+), 344 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/0472e39e/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index a17f342..724effd 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -44,8 +44,22 @@ import org.apache.openejb.util.Logger;
 import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Option;
 
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
 import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
+import javax.management.ReflectionException;
 import javax.naming.NamingException;
 import javax.resource.ResourceException;
 import javax.resource.spi.ActivationSpec;
@@ -63,7 +77,9 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 
+import static javax.management.MBeanOperationInfo.ACTION;
 import static org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke;
 import static org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
 import static org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
@@ -73,9 +89,11 @@ public class MdbContainer implements RpcContainer {
     private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
 
     private static final ThreadLocal<BeanContext> CURRENT = new ThreadLocal<>();
-
     private static final Object[] NO_ARGS = new Object[0];
 
+    private final Map<BeanContext, ObjectName> mbeanNames = new ConcurrentHashMap<>();
+    private final Map<BeanContext, MdbActivationContext> activationContexts = new ConcurrentHashMap<>();
+
     private final Object containerID;
     private final SecurityService securityService;
     private final ResourceAdapter resourceAdapter;
@@ -188,7 +206,18 @@ public class MdbContainer implements RpcContainer {
         // activate the endpoint
         CURRENT.set(beanContext);
         try {
-            resourceAdapter.endpointActivation(endpointFactory, activationSpec);
+
+            final MdbActivationContext activationContext = new MdbActivationContext(resourceAdapter, endpointFactory, activationSpec);
+            activationContexts.put(beanContext, activationContext);
+
+            final boolean activeOnStartup = Boolean.parseBoolean(beanContext.getProperties().getProperty("MdbActiveOnStartup", "true"));
+            if (activeOnStartup) {
+                activationContext.start();
+            }
+
+            final String jmxName = beanContext.getProperties().getProperty("MdbJMXControl", "true");
+            addJMxControl(beanContext, jmxName, activationContext);
+
         } catch (final ResourceException e) {
             // activation failed... clean up
             beanContext.setContainer(null);
@@ -201,6 +230,10 @@ public class MdbContainer implements RpcContainer {
         }
     }
 
+    private static String getOrDefault(final Map<String, String> map, final String key, final String defaultValue) {
+        return map.get(key) != null ? map.get(key) : defaultValue;
+    }
+
     private ActivationSpec createActivationSpec(final BeanContext beanContext) throws OpenEJBException {
         try {
             // initialize the object recipe
@@ -253,7 +286,6 @@ public class MdbContainer implements RpcContainer {
                 logger.debug("No Validator bound to JNDI context");
             }
 
-
             // set the resource adapter into the activation spec
             activationSpec.setResourceAdapter(resourceAdapter);
 
@@ -284,7 +316,17 @@ public class MdbContainer implements RpcContainer {
             if (endpointFactory != null) {
                 CURRENT.set(beanContext);
                 try {
-                    resourceAdapter.endpointDeactivation(endpointFactory, endpointFactory.getActivationSpec());
+
+                    final ObjectName jmxBeanToRemove = mbeanNames.remove(beanContext);
+                    if (jmxBeanToRemove != null) {
+                        LocalMBeanServer.unregisterSilently(jmxBeanToRemove);
+                        logger.info("Undeployed MDB control for " + beanContext.getDeploymentID());
+                    }
+
+                    final MdbActivationContext activationContext = activationContexts.remove(beanContext);
+                    if (activationContext != null && activationContext.isStarted()) {
+                        resourceAdapter.endpointDeactivation(endpointFactory, endpointFactory.getActivationSpec());
+                    }
                 } finally {
                     CURRENT.remove();
                 }
@@ -492,6 +534,30 @@ public class MdbContainer implements RpcContainer {
         }
     }
 
+    private void addJMxControl(final BeanContext current, final String name, final MdbActivationContext activationContext) throws ResourceException {
+        if (name == null || "false".equalsIgnoreCase(name)) {
+            return;
+        }
+
+        final ObjectName jmxName;
+        try {
+            jmxName = "true".equalsIgnoreCase(name) ? new ObjectNameBuilder()
+                    .set("J2EEServer", "openejb")
+                    .set("J2EEApplication", null)
+                    .set("EJBModule", current.getModuleID())
+                    .set("StatelessSessionBean", current.getEjbName())
+                    .set("j2eeType", "control")
+                    .set("name", current.getEjbName())
+                    .build() : new ObjectName(name);
+        } catch (final MalformedObjectNameException e) {
+            throw new IllegalArgumentException(e);
+        }
+        mbeanNames.put(current, jmxName);
+
+        LocalMBeanServer.registerSilently(new MdbJmxControl(activationContext), jmxName);
+        logger.info("Deployed MDB control for " + current.getDeploymentID() + " on " + jmxName);
+    }
+
     public static BeanContext current() {
         final BeanContext beanContext = CURRENT.get();
         if (beanContext == null) {
@@ -505,4 +571,115 @@ public class MdbContainer implements RpcContainer {
         private TransactionPolicy txPolicy;
         private ThreadContext oldCallContext;
     }
+
+    private static class MdbActivationContext {
+        private final ResourceAdapter resourceAdapter;
+        private final EndpointFactory endpointFactory;
+        private final ActivationSpec activationSpec;
+
+        private AtomicBoolean started = new AtomicBoolean(false);
+
+        public MdbActivationContext(final ResourceAdapter resourceAdapter, final EndpointFactory endpointFactory, final ActivationSpec activationSpec) {
+            this.resourceAdapter = resourceAdapter;
+            this.endpointFactory = endpointFactory;
+            this.activationSpec = activationSpec;
+        }
+
+        public ResourceAdapter getResourceAdapter() {
+            return resourceAdapter;
+        }
+
+        public EndpointFactory getEndpointFactory() {
+            return endpointFactory;
+        }
+
+        public ActivationSpec getActivationSpec() {
+            return activationSpec;
+        }
+
+        public boolean isStarted() {
+            return started.get();
+        }
+
+        public void start() throws ResourceException {
+            if (started.get()) {
+                return;
+            }
+
+            resourceAdapter.endpointActivation(endpointFactory, activationSpec);
+            started.set(true);
+        }
+
+        public void stop() {
+            if (! started.get()) {
+                return;
+            }
+
+            resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
+            started.set(false);
+        }
+    }
+
+    public static final class MdbJmxControl implements DynamicMBean {
+        private static final AttributeList ATTRIBUTE_LIST = new AttributeList();
+        private static final MBeanInfo INFO = new MBeanInfo(
+                "org.apache.openejb.resource.activemq.ActiveMQResourceAdapter.MdbJmxControl",
+                "Allows to control a MDB (start/stop)",
+                new MBeanAttributeInfo[0],
+                new MBeanConstructorInfo[0],
+                new MBeanOperationInfo[]{
+                        new MBeanOperationInfo("start", "Ensure the listener is active.", new MBeanParameterInfo[0], "void", ACTION),
+                        new MBeanOperationInfo("stop", "Ensure the listener is not active.", new MBeanParameterInfo[0], "void", ACTION)
+                },
+                new MBeanNotificationInfo[0]);
+
+        private final MdbActivationContext activationContext;
+
+        private MdbJmxControl(final MdbActivationContext activationContext) {
+            this.activationContext = activationContext;
+        }
+
+        @Override
+        public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException {
+            if (actionName.equals("stop")) {
+                activationContext.stop();
+
+            } else if (actionName.equals("start")) {
+                try {
+                    activationContext.start();
+                } catch (ResourceException e) {
+                    throw new MBeanException(new IllegalStateException(e.getMessage()));
+                }
+
+            } else {
+                throw new MBeanException(new IllegalStateException("unsupported operation: " + actionName));
+            }
+            return null;
+        }
+
+        @Override
+        public MBeanInfo getMBeanInfo() {
+            return INFO;
+        }
+
+        @Override
+        public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
+            throw new AttributeNotFoundException();
+        }
+
+        @Override
+        public void setAttribute(final Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
+            throw new AttributeNotFoundException();
+        }
+
+        @Override
+        public AttributeList getAttributes(final String[] attributes) {
+            return ATTRIBUTE_LIST;
+        }
+
+        @Override
+        public AttributeList setAttributes(final AttributeList attributes) {
+            return ATTRIBUTE_LIST;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/0472e39e/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
index cd44b79..e5f201e 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
@@ -29,8 +29,6 @@ import org.apache.activemq.ra.MessageActivationSpec;
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.core.mdb.MdbContainer;
 import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.monitoring.LocalMBeanServer;
-import org.apache.openejb.monitoring.ObjectNameBuilder;
 import org.apache.openejb.resource.AutoConnectionTracker;
 import org.apache.openejb.resource.activemq.jms2.TomEEConnectionFactory;
 import org.apache.openejb.resource.activemq.jms2.TomEEManagedConnectionProxy;
@@ -44,28 +42,11 @@ import org.apache.openejb.util.reflection.Reflections;
 
 import javax.jms.Connection;
 import javax.jms.JMSException;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InvalidAttributeValueException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanConstructorInfo;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
-import javax.management.ReflectionException;
 import javax.naming.NamingException;
-import javax.resource.NotSupportedException;
 import javax.resource.ResourceException;
-import javax.resource.spi.ActivationSpec;
 import javax.resource.spi.BootstrapContext;
 import javax.resource.spi.ResourceAdapterInternalException;
-import javax.resource.spi.endpoint.MessageEndpointFactory;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
@@ -78,8 +59,6 @@ import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
-import static javax.management.MBeanOperationInfo.ACTION;
-
 @SuppressWarnings("UnusedDeclaration")
 public class ActiveMQResourceAdapter extends org.apache.activemq.ra.ActiveMQResourceAdapter {
 
@@ -190,65 +169,6 @@ public class ActiveMQResourceAdapter extends org.apache.activemq.ra.ActiveMQReso
         }
     }
 
-    @Override
-    public void endpointActivation(final MessageEndpointFactory endpointFactory, final ActivationSpec activationSpec) throws ResourceException {
-        final BeanContext current = MdbContainer.current();
-        if (current != null && "false".equalsIgnoreCase(current.getProperties().getProperty("MdbActiveOnStartup"))) {
-            if (!equals(activationSpec.getResourceAdapter())) {
-                throw new ResourceException("Activation spec not initialized with this ResourceAdapter instance (" + activationSpec.getResourceAdapter() + " != " + this + ")");
-            }
-            if (!(activationSpec instanceof MessageActivationSpec)) {
-                throw new NotSupportedException("That type of ActivationSpec not supported: " + activationSpec.getClass());
-            }
-
-            final ActiveMQEndpointActivationKey key = new ActiveMQEndpointActivationKey(endpointFactory, MessageActivationSpec.class.cast(activationSpec));
-            Map.class.cast(Reflections.get(this, "endpointWorkers")).put(key, new ActiveMQEndpointWorker(this, key) {
-            });
-            // we dont want that worker.start();
-        } else {
-            super.endpointActivation(endpointFactory, activationSpec);
-        }
-
-        if (current != null) {
-            addJMxControl(current, current.getProperties().getProperty("MdbJMXControl"));
-        }
-    }
-
-    private void addJMxControl(final BeanContext current, final String name) throws ResourceException {
-        if (name == null || "false".equalsIgnoreCase(name)) {
-            return;
-        }
-
-        final ActiveMQEndpointWorker worker = getWorker(current);
-        final ObjectName jmxName;
-        try {
-            jmxName = "true".equalsIgnoreCase(name) ? new ObjectNameBuilder()
-                    .set("J2EEServer", "openejb")
-                    .set("J2EEApplication", null)
-                    .set("EJBModule", current.getModuleID())
-                    .set("StatelessSessionBean", current.getEjbName())
-                    .set("j2eeType", "control")
-                    .set("name", current.getEjbName())
-                    .build() : new ObjectName(name);
-        } catch (final MalformedObjectNameException e) {
-            throw new IllegalArgumentException(e);
-        }
-        mbeanNames.put(current, jmxName);
-
-        LocalMBeanServer.registerSilently(new MdbJmxControl(worker), jmxName);
-        log.info("Deployed MDB control for " + current.getDeploymentID() + " on " + jmxName);
-    }
-
-    @Override
-    public void endpointDeactivation(final MessageEndpointFactory endpointFactory, final ActivationSpec activationSpec) {
-        final BeanContext current = MdbContainer.current();
-        if (current != null && "true".equalsIgnoreCase(current.getProperties().getProperty("MdbJMXControl"))) {
-            LocalMBeanServer.unregisterSilently(mbeanNames.remove(current));
-            log.info("Undeployed MDB control for " + current.getDeploymentID());
-        }
-        super.endpointDeactivation(endpointFactory, activationSpec);
-    }
-
     private ActiveMQEndpointWorker getWorker(final BeanContext beanContext) throws ResourceException {
         final Map<ActiveMQEndpointActivationKey, ActiveMQEndpointWorker> workers = Map.class.cast(Reflections.get(
                 MdbContainer.class.cast(beanContext.getContainer()).getResourceAdapter(), "endpointWorkers"));
@@ -396,72 +316,4 @@ public class ActiveMQResourceAdapter extends org.apache.activemq.ra.ActiveMQReso
             //Ignore
         }
     }
-
-    public static final class MdbJmxControl implements DynamicMBean {
-        private static final AttributeList ATTRIBUTE_LIST = new AttributeList();
-        private static final MBeanInfo INFO = new MBeanInfo(
-                "org.apache.openejb.resource.activemq.ActiveMQResourceAdapter.MdbJmxControl",
-                "Allows to control a MDB (start/stop)",
-                new MBeanAttributeInfo[0],
-                new MBeanConstructorInfo[0],
-                new MBeanOperationInfo[]{
-                        new MBeanOperationInfo("start", "Ensure the listener is active.", new MBeanParameterInfo[0], "void", ACTION),
-                        new MBeanOperationInfo("stop", "Ensure the listener is not active.", new MBeanParameterInfo[0], "void", ACTION)
-                },
-                new MBeanNotificationInfo[0]);
-
-        private final ActiveMQEndpointWorker worker;
-
-        private MdbJmxControl(final ActiveMQEndpointWorker worker) {
-            this.worker = worker;
-        }
-
-        @Override
-        public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException {
-            switch (actionName) {
-                case "stop":
-                    try {
-                        worker.stop();
-                    } catch (final InterruptedException e) {
-                        Thread.interrupted();
-                    }
-                    break;
-                case "start":
-                    try {
-                        worker.start();
-                    } catch (ResourceException e) {
-                        throw new MBeanException(new IllegalStateException(e.getMessage()));
-                    }
-                    break;
-                default:
-                    throw new MBeanException(new IllegalStateException("unsupported operation: " + actionName));
-            }
-            return null;
-        }
-
-        @Override
-        public MBeanInfo getMBeanInfo() {
-            return INFO;
-        }
-
-        @Override
-        public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
-            throw new AttributeNotFoundException();
-        }
-
-        @Override
-        public void setAttribute(final Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
-            throw new AttributeNotFoundException();
-        }
-
-        @Override
-        public AttributeList getAttributes(final String[] attributes) {
-            return ATTRIBUTE_LIST;
-        }
-
-        @Override
-        public AttributeList setAttributes(final AttributeList attributes) {
-            return ATTRIBUTE_LIST;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/0472e39e/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterControlTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterControlTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterControlTest.java
new file mode 100644
index 0000000..3885dc5
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterControlTest.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.openejb.core.mdb;
+
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.oejb3.EjbDeployment;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.monitoring.LocalMBeanServer;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
+import org.apache.openejb.testng.PropertiesBuilder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.ejb.ActivationConfigProperty;
+import javax.ejb.MessageDriven;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.management.ObjectName;
+import java.util.Properties;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(ApplicationComposer.class)
+public class ResourceAdapterControlTest {
+    private static final Logger logger = Logger.getLogger(ResourceAdapterControlTest.class.getName());
+    @Resource(name = "ResourceAdapterControlTest/test/ejb/Mdb")
+    private Queue queue;
+
+    @Resource
+    private ConnectionFactory connectionFactory;
+
+    @Configuration
+    public Properties config() {
+        return new PropertiesBuilder()
+                .p("ra", "new://Resource?type=ActiveMQResourceAdapter")
+                .p("ra.brokerXmlConfig", "broker:(vm://localhost)?useJmx=false&persistent=false")
+                .p("ra.serverUrl", "vm://localhost")
+
+                .p("mdb", "new://Container?type=MESSAGE")
+                .p("mdb.resourceAdapter", "ra")
+                .p("mdb.InstanceLimit", "1")
+
+                .p("cf", "new://Resource?type=javax.jms.ConnectionFactory")
+                .p("cf.resourceAdapter", "ra")
+
+                .p("openejb.deploymentId.format", "{appId}/{ejbJarId}/{ejbName}")
+                .build();
+    }
+
+    @Module
+    @Classes(value = Mdb.class)
+    public EjbModule app() {
+        return new EjbModule(new EjbJar("test"), new OpenejbJar() {{
+            setId("test");
+            getEjbDeployment().add(new EjbDeployment() {{
+                setEjbName("ejb/Mdb");
+                getProperties().put("MdbActiveOnStartup", "false");
+                getProperties().put("MdbJMXControl", "default:type=test");
+            }});
+        }});
+    }
+
+    @Test
+    public void ensureControl() throws Exception {
+        assertFalse(Mdb.awaiter.message, sendAndWait("Will be received after", 10, TimeUnit.SECONDS));
+
+        setControl("start");
+        assertTrue(Mdb.awaiter.semaphore.tryAcquire(1, TimeUnit.MINUTES));
+        assertEquals("Will be received after", Mdb.awaiter.message);
+
+        final long start = System.currentTimeMillis();
+        assertTrue(sendAndWait("First", 1, TimeUnit.MINUTES));
+        assertEquals("First", Mdb.awaiter.message);
+        final long end = System.currentTimeMillis();
+
+        Mdb.awaiter.message = null;
+        setControl("stop");
+        // default would be wait 10s, but if machine is slow we compute it from the first msg stats
+        final long waitWithoutResponse = Math.max(10, 5 * (end - start) / 1000);
+        System.out.println("We'll wait " + waitWithoutResponse + "s to get a message on a stopped listener");
+        assertFalse(Mdb.awaiter.message, sendAndWait("Will be received after", waitWithoutResponse, TimeUnit.SECONDS));
+        assertNull(Mdb.awaiter.message);
+
+        setControl("start");
+        assertTrue(sendAndWait("Second", 1, TimeUnit.MINUTES));
+        assertEquals("Will be received after", Mdb.awaiter.message);
+
+        Mdb.awaiter.message = null;
+        assertTrue(Mdb.awaiter.semaphore.tryAcquire(1, TimeUnit.MINUTES));
+        assertEquals("Second", Mdb.awaiter.message);
+    }
+
+    private void setControl(final String action) throws Exception {
+        LocalMBeanServer.get().invoke(
+                new ObjectName("default:type=test"),
+                action, new Object[0], new String[0]);
+    }
+
+    private boolean sendAndWait(final String second, final long wait, final TimeUnit unit) throws JMSException {
+        doSend(second);
+        try {
+            return Mdb.awaiter.semaphore.tryAcquire(wait, unit);
+        } catch (final InterruptedException e) {
+            Thread.interrupted();
+            fail();
+            return false;
+        }
+    }
+
+    private void doSend(final String txt) throws JMSException {
+        Connection c = null;
+        try {
+            c = connectionFactory.createConnection();
+            Session session = null;
+            try {
+                session = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+                MessageProducer producer = null;
+                try {
+                    producer = session.createProducer(queue);
+                    producer.send(session.createTextMessage(txt));
+                } finally {
+                    if (producer != null) {
+                        producer.close();
+                    }
+                }
+            } finally {
+                if (session != null) {
+                    session.close();
+                }
+            }
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+    }
+
+    @MessageDriven(name = "ejb/Mdb", activationConfig = {
+            @ActivationConfigProperty(propertyName = "maxSessions", propertyValue = "1"),
+            @ActivationConfigProperty(propertyName = "maxMessagesPerBatch", propertyValue = "1")
+    })
+    public static class Mdb implements MessageListener {
+        static final MessageAwaiter awaiter = new MessageAwaiter();
+
+        @Override
+        public synchronized void onMessage(final Message message) {
+            try {
+                awaiter.message = TextMessage.class.cast(message).getText();
+            } catch (final JMSException e) {
+                throw new IllegalStateException(e);
+            } finally {
+                awaiter.semaphore.release();
+            }
+        }
+    }
+
+    public static class MessageAwaiter {
+        private final Semaphore semaphore = new Semaphore(0);
+        private volatile String message;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/0472e39e/container/openejb-core/src/test/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapterControlTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapterControlTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapterControlTest.java
deleted file mode 100644
index 7940cd4..0000000
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapterControlTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.openejb.resource.activemq;
-
-import org.apache.openejb.config.EjbModule;
-import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.oejb3.EjbDeployment;
-import org.apache.openejb.jee.oejb3.OpenejbJar;
-import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.monitoring.LocalMBeanServer;
-import org.apache.openejb.testing.Classes;
-import org.apache.openejb.testing.Configuration;
-import org.apache.openejb.testing.Module;
-import org.apache.openejb.testng.PropertiesBuilder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import javax.annotation.Resource;
-import javax.ejb.ActivationConfigProperty;
-import javax.ejb.MessageDriven;
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.management.ObjectName;
-import java.util.Properties;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-@RunWith(ApplicationComposer.class)
-public class ActiveMQResourceAdapterControlTest {
-    @Resource(name = "ActiveMQResourceAdapterControlTest/test/ejb/Mdb")
-    private Queue queue;
-
-    @Resource
-    private ConnectionFactory connectionFactory;
-
-    @Configuration
-    public Properties config() {
-        return new PropertiesBuilder()
-                .p("ra", "new://Resource?type=ActiveMQResourceAdapter")
-                .p("ra.brokerXmlConfig", "broker:(vm://localhost)?useJmx=false&persistent=false")
-                .p("ra.serverUrl", "vm://localhost")
-
-                .p("mdb", "new://Container?type=MESSAGE")
-                .p("mdb.resourceAdapter", "ra")
-                .p("mdb.InstanceLimit", "1")
-
-                .p("cf", "new://Resource?type=javax.jms.ConnectionFactory")
-                .p("cf.resourceAdapter", "ra")
-
-                .p("openejb.deploymentId.format", "{appId}/{ejbJarId}/{ejbName}")
-                .build();
-    }
-
-    @Module
-    @Classes(value = Mdb.class)
-    public EjbModule app() {
-        return new EjbModule(new EjbJar("test"), new OpenejbJar() {{
-            setId("test");
-            getEjbDeployment().add(new EjbDeployment() {{
-                setEjbName("ejb/Mdb");
-                getProperties().put("MdbActiveOnStartup", "false");
-                getProperties().put("MdbJMXControl", "default:type=test");
-            }});
-        }});
-    }
-
-    @Test
-    public void ensureControl() throws Exception {
-        assertFalse(Mdb.awaiter.message, sendAndWait("Will be received after", 10, TimeUnit.SECONDS));
-
-        setControl("start");
-        assertTrue(Mdb.awaiter.semaphore.tryAcquire(1, TimeUnit.MINUTES));
-        assertEquals("Will be received after", Mdb.awaiter.message);
-
-        final long start = System.currentTimeMillis();
-        assertTrue(sendAndWait("First", 1, TimeUnit.MINUTES));
-        assertEquals("First", Mdb.awaiter.message);
-        final long end = System.currentTimeMillis();
-
-        Mdb.awaiter.message = null;
-        setControl("stop");
-        // default would be wait 10s, but if machine is slow we compute it from the first msg stats
-        final long waitWithoutResponse = Math.max(10, 5 * (end - start) / 1000);
-        System.out.println("We'll wait " + waitWithoutResponse + "s to get a message on a stopped listener");
-        assertFalse(Mdb.awaiter.message, sendAndWait("Will be received after", waitWithoutResponse, TimeUnit.SECONDS));
-        assertNull(Mdb.awaiter.message);
-
-        setControl("start");
-        assertTrue(sendAndWait("Second", 1, TimeUnit.MINUTES));
-        assertEquals("Will be received after", Mdb.awaiter.message);
-
-        Mdb.awaiter.message = null;
-        assertTrue(Mdb.awaiter.semaphore.tryAcquire(1, TimeUnit.MINUTES));
-        assertEquals("Second", Mdb.awaiter.message);
-    }
-
-    private void setControl(final String action) throws Exception {
-        LocalMBeanServer.get().invoke(
-                new ObjectName("default:type=test"),
-                action, new Object[0], new String[0]);
-    }
-
-    private boolean sendAndWait(final String second, final long wait, final TimeUnit unit) throws JMSException {
-        doSend(second);
-        try {
-            return Mdb.awaiter.semaphore.tryAcquire(wait, unit);
-        } catch (final InterruptedException e) {
-            Thread.interrupted();
-            fail();
-            return false;
-        }
-    }
-
-    private void doSend(final String txt) throws JMSException {
-        Connection c = null;
-        try {
-            c = connectionFactory.createConnection();
-            Session session = null;
-            try {
-                session = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
-                MessageProducer producer = null;
-                try {
-                    producer = session.createProducer(queue);
-                    producer.send(session.createTextMessage(txt));
-                } finally {
-                    if (producer != null) {
-                        producer.close();
-                    }
-                }
-            } finally {
-                if (session != null) {
-                    session.close();
-                }
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-    }
-
-    @MessageDriven(name = "ejb/Mdb", activationConfig = {
-            @ActivationConfigProperty(propertyName = "maxSessions", propertyValue = "1"),
-            @ActivationConfigProperty(propertyName = "maxMessagesPerBatch", propertyValue = "1")
-    })
-    public static class Mdb implements MessageListener {
-        static final MessageAwaiter awaiter = new MessageAwaiter();
-
-        @Override
-        public synchronized void onMessage(final Message message) {
-            try {
-                awaiter.message = TextMessage.class.cast(message).getText();
-            } catch (final JMSException e) {
-                throw new IllegalStateException(e);
-            } finally {
-                awaiter.semaphore.release();
-            }
-        }
-    }
-
-    public static class MessageAwaiter {
-        private final Semaphore semaphore = new Semaphore(0);
-        private volatile String message;
-    }
-}


[2/8] tomee git commit: Merge remote-tracking branch 'apache/master' into mdb-activation-master

Posted by jg...@apache.org.
Merge remote-tracking branch 'apache/master' into mdb-activation-master


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/379739e0
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/379739e0
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/379739e0

Branch: refs/heads/master
Commit: 379739e0bbe858d2acb6250e7d29733dc2b32d0b
Parents: 0472e39 f42a82a
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 16:55:47 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 16:55:47 2017 +0100

----------------------------------------------------------------------
 .../openejb/arquillian/common/TestObserver.java | 44 +++++++++++++-----
 arquillian/arquillian-openejb-embedded/pom.xml  |  1 +
 .../openejb/OpenEJBDeployableContainer.java     | 27 +++++++----
 .../embedded/EmbeddedTomEEContainer.java        | 47 +++++++++++++-------
 .../openejb/config/DeploymentsResolver.java     |  2 +-
 pom.xml                                         |  2 +-
 .../tomee/catalina/TomEEWebappClassLoader.java  | 10 +++--
 7 files changed, 94 insertions(+), 39 deletions(-)
----------------------------------------------------------------------



[6/8] tomee git commit: Adding further logging, and a JMX attribute to show if the MDB has been started or not.

Posted by jg...@apache.org.
Adding further logging, and a JMX attribute to show if the MDB has been started or not.


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/09a98d69
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/09a98d69
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/09a98d69

Branch: refs/heads/master
Commit: 09a98d69bf94a47d121714d2cb024318a9589ca2
Parents: 5433e9c
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 16:16:00 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 16:57:58 2017 +0100

----------------------------------------------------------------------
 .../org/apache/openejb/core/mdb/MdbContainer.java   | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/09a98d69/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index 02c852e..82fca93 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -213,6 +213,8 @@ public class MdbContainer implements RpcContainer {
             final boolean activeOnStartup = Boolean.parseBoolean(beanContext.getProperties().getProperty("MdbActiveOnStartup", "true"));
             if (activeOnStartup) {
                 activationContext.start();
+            } else {
+                logger.info("Not auto-activating endpoint for " + beanContext.getDeploymentID());
             }
 
             final String jmxName = beanContext.getProperties().getProperty("MdbJMXControl", "true");
@@ -536,7 +538,7 @@ public class MdbContainer implements RpcContainer {
 
     private void addJMxControl(final BeanContext current, final String name, final MdbActivationContext activationContext) throws ResourceException {
         if (name == null || "false".equalsIgnoreCase(name)) {
-            logger.debug("Not adding JMX control for " + current.getDeploymentID() + "/" + current.getEjbName());
+            logger.debug("Not adding JMX control for " + current.getDeploymentID());
             return;
         }
 
@@ -617,7 +619,7 @@ public class MdbContainer implements RpcContainer {
             resourceAdapter.endpointActivation(endpointFactory, activationSpec);
             Thread.currentThread().setContextClassLoader(oldCl);
 
-            logger.info("Activated endpoint for " + beanContext.getDeploymentID() + "/" + beanContext.getEjbName());
+            logger.info("Activated endpoint for " + beanContext.getDeploymentID());
             started.set(true);
         }
 
@@ -632,6 +634,8 @@ public class MdbContainer implements RpcContainer {
             resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
 
             Thread.currentThread().setContextClassLoader(oldCl);
+
+            logger.info("Deactivated endpoint for " + beanContext.getDeploymentID());
             started.set(false);
         }
     }
@@ -641,7 +645,9 @@ public class MdbContainer implements RpcContainer {
         private static final MBeanInfo INFO = new MBeanInfo(
                 "org.apache.openejb.resource.activemq.ActiveMQResourceAdapter.MdbJmxControl",
                 "Allows to control a MDB (start/stop)",
-                new MBeanAttributeInfo[0],
+                new MBeanAttributeInfo[]{
+                        new MBeanAttributeInfo("started", "boolean", "started: boolean indicating whether this MDB endpoint has been activated.", true, false, true)
+                },
                 new MBeanConstructorInfo[0],
                 new MBeanOperationInfo[]{
                         new MBeanOperationInfo("start", "Ensure the listener is active.", new MBeanParameterInfo[0], "void", ACTION),
@@ -681,6 +687,10 @@ public class MdbContainer implements RpcContainer {
 
         @Override
         public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
+            if ("started".equals(attribute)) {
+                return activationContext.isStarted();
+            }
+
             throw new AttributeNotFoundException();
         }
 


[3/8] tomee git commit: Track the classloader (thanks for the pointer, Romain)

Posted by jg...@apache.org.
Track the classloader (thanks for the pointer, Romain)


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/242e7f01
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/242e7f01
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/242e7f01

Branch: refs/heads/master
Commit: 242e7f012b2ddba16558c4903b51a6e15ce23deb
Parents: 379739e
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 14:56:52 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 16:57:19 2017 +0100

----------------------------------------------------------------------
 .../org/apache/openejb/core/mdb/MdbContainer.java    | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/242e7f01/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index 724effd..8299713 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -207,7 +207,7 @@ public class MdbContainer implements RpcContainer {
         CURRENT.set(beanContext);
         try {
 
-            final MdbActivationContext activationContext = new MdbActivationContext(resourceAdapter, endpointFactory, activationSpec);
+            final MdbActivationContext activationContext = new MdbActivationContext(Thread.currentThread().getContextClassLoader(), resourceAdapter, endpointFactory, activationSpec);
             activationContexts.put(beanContext, activationContext);
 
             final boolean activeOnStartup = Boolean.parseBoolean(beanContext.getProperties().getProperty("MdbActiveOnStartup", "true"));
@@ -573,13 +573,15 @@ public class MdbContainer implements RpcContainer {
     }
 
     private static class MdbActivationContext {
+        private final ClassLoader classLoader;
         private final ResourceAdapter resourceAdapter;
         private final EndpointFactory endpointFactory;
         private final ActivationSpec activationSpec;
 
         private AtomicBoolean started = new AtomicBoolean(false);
 
-        public MdbActivationContext(final ResourceAdapter resourceAdapter, final EndpointFactory endpointFactory, final ActivationSpec activationSpec) {
+        public MdbActivationContext(ClassLoader classLoader, final ResourceAdapter resourceAdapter, final EndpointFactory endpointFactory, final ActivationSpec activationSpec) {
+            this.classLoader = classLoader;
             this.resourceAdapter = resourceAdapter;
             this.endpointFactory = endpointFactory;
             this.activationSpec = activationSpec;
@@ -606,7 +608,11 @@ public class MdbContainer implements RpcContainer {
                 return;
             }
 
+            final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+            Thread.currentThread().setContextClassLoader(classLoader);
+
             resourceAdapter.endpointActivation(endpointFactory, activationSpec);
+            Thread.currentThread().setContextClassLoader(oldCl);
             started.set(true);
         }
 
@@ -615,7 +621,12 @@ public class MdbContainer implements RpcContainer {
                 return;
             }
 
+            final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+            Thread.currentThread().setContextClassLoader(classLoader);
+
             resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
+
+            Thread.currentThread().setContextClassLoader(oldCl);
             started.set(false);
         }
     }


[7/8] tomee git commit: Incorporating further feedback from Romain's peer review of my PR. Specifically using compareAndSet() to avoid race conditions, and try/finally when resetting the classloader. Thanks Romain.

Posted by jg...@apache.org.
Incorporating further feedback from Romain's peer review of my PR. Specifically using compareAndSet() to avoid race conditions, and try/finally when resetting the classloader. Thanks Romain.


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/0f567f25
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/0f567f25
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/0f567f25

Branch: refs/heads/master
Commit: 0f567f25b0a5918d7f4fae908280fbda9477367e
Parents: 09a98d6
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 22:11:36 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 22:11:36 2017 +0100

----------------------------------------------------------------------
 .../apache/openejb/core/mdb/MdbContainer.java   | 32 ++++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/0f567f25/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index 82fca93..accb996 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -609,34 +609,34 @@ public class MdbContainer implements RpcContainer {
         }
 
         public void start() throws ResourceException {
-            if (started.get()) {
+            if (! started.compareAndSet(false, true)) {
                 return;
             }
 
             final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
-            Thread.currentThread().setContextClassLoader(classLoader);
-
-            resourceAdapter.endpointActivation(endpointFactory, activationSpec);
-            Thread.currentThread().setContextClassLoader(oldCl);
+            try {
+                Thread.currentThread().setContextClassLoader(classLoader);
+                resourceAdapter.endpointActivation(endpointFactory, activationSpec);
+                logger.info("Activated endpoint for " + beanContext.getDeploymentID());
+            } finally {
+                Thread.currentThread().setContextClassLoader(oldCl);
+            }
 
-            logger.info("Activated endpoint for " + beanContext.getDeploymentID());
-            started.set(true);
         }
 
         public void stop() {
-            if (! started.get()) {
+            if (! started.compareAndSet(true, false)) {
                 return;
             }
 
             final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
-            Thread.currentThread().setContextClassLoader(classLoader);
-
-            resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
-
-            Thread.currentThread().setContextClassLoader(oldCl);
-
-            logger.info("Deactivated endpoint for " + beanContext.getDeploymentID());
-            started.set(false);
+            try {
+                Thread.currentThread().setContextClassLoader(classLoader);
+                resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
+                logger.info("Deactivated endpoint for " + beanContext.getDeploymentID());
+            } finally {
+                Thread.currentThread().setContextClassLoader(oldCl);
+            }
         }
     }
 


[8/8] tomee git commit: Merge branch 'mdb-activation-master'

Posted by jg...@apache.org.
Merge branch 'mdb-activation-master'


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/04ab19ba
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/04ab19ba
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/04ab19ba

Branch: refs/heads/master
Commit: 04ab19bac4e8eb5c1a765f54f99ea68f045cfc79
Parents: 6557c43 0f567f2
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jul 5 10:36:49 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jul 5 10:36:49 2017 +0100

----------------------------------------------------------------------
 .../apache/openejb/core/mdb/MdbContainer.java   | 212 ++++++++++++++++++-
 .../activemq/ActiveMQResourceAdapter.java       | 148 -------------
 .../core/mdb/ResourceAdapterControlTest.java    | 194 +++++++++++++++++
 .../ActiveMQResourceAdapterControlTest.java     | 192 -----------------
 4 files changed, 402 insertions(+), 344 deletions(-)
----------------------------------------------------------------------



[4/8] tomee git commit: Added some basic logging when starting/stopping MDB endpoints

Posted by jg...@apache.org.
Added some basic logging when starting/stopping MDB endpoints


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/bc89940d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/bc89940d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/bc89940d

Branch: refs/heads/master
Commit: bc89940d306ec4729f27419db4bc27d540d0c955
Parents: 242e7f0
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 15:41:17 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 16:57:35 2017 +0100

----------------------------------------------------------------------
 .../java/org/apache/openejb/core/mdb/MdbContainer.java   | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/bc89940d/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index 8299713..58beed9 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -207,7 +207,7 @@ public class MdbContainer implements RpcContainer {
         CURRENT.set(beanContext);
         try {
 
-            final MdbActivationContext activationContext = new MdbActivationContext(Thread.currentThread().getContextClassLoader(), resourceAdapter, endpointFactory, activationSpec);
+            final MdbActivationContext activationContext = new MdbActivationContext(Thread.currentThread().getContextClassLoader(), beanContext, resourceAdapter, endpointFactory, activationSpec);
             activationContexts.put(beanContext, activationContext);
 
             final boolean activeOnStartup = Boolean.parseBoolean(beanContext.getProperties().getProperty("MdbActiveOnStartup", "true"));
@@ -574,14 +574,16 @@ public class MdbContainer implements RpcContainer {
 
     private static class MdbActivationContext {
         private final ClassLoader classLoader;
+        private final BeanContext beanContext;
         private final ResourceAdapter resourceAdapter;
         private final EndpointFactory endpointFactory;
         private final ActivationSpec activationSpec;
 
         private AtomicBoolean started = new AtomicBoolean(false);
 
-        public MdbActivationContext(ClassLoader classLoader, final ResourceAdapter resourceAdapter, final EndpointFactory endpointFactory, final ActivationSpec activationSpec) {
+        public MdbActivationContext(final ClassLoader classLoader, final BeanContext beanContext, final ResourceAdapter resourceAdapter, final EndpointFactory endpointFactory, final ActivationSpec activationSpec) {
             this.classLoader = classLoader;
+            this.beanContext = beanContext;
             this.resourceAdapter = resourceAdapter;
             this.endpointFactory = endpointFactory;
             this.activationSpec = activationSpec;
@@ -613,6 +615,8 @@ public class MdbContainer implements RpcContainer {
 
             resourceAdapter.endpointActivation(endpointFactory, activationSpec);
             Thread.currentThread().setContextClassLoader(oldCl);
+
+            logger.info("Activated endpoint for " + beanContext.getDeploymentID() + "/" + beanContext.getEjbName());
             started.set(true);
         }
 
@@ -659,7 +663,8 @@ public class MdbContainer implements RpcContainer {
                 try {
                     activationContext.start();
                 } catch (ResourceException e) {
-                    throw new MBeanException(new IllegalStateException(e.getMessage()));
+                    logger.error("Error invoking " + actionName + ": " + e.getMessage());
+                    throw new MBeanException(new IllegalStateException(e.getMessage(), e));
                 }
 
             } else {


[5/8] tomee git commit: Added trace where the JMX control is not added

Posted by jg...@apache.org.
Added trace where the JMX control is not added


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/5433e9c2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/5433e9c2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/5433e9c2

Branch: refs/heads/master
Commit: 5433e9c21ab06fe2552edb1637912d2aba5c1ab8
Parents: bc89940
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Jun 28 15:43:47 2017 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Jun 28 16:57:46 2017 +0100

----------------------------------------------------------------------
 .../src/main/java/org/apache/openejb/core/mdb/MdbContainer.java     | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/5433e9c2/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
index 58beed9..02c852e 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
@@ -536,6 +536,7 @@ public class MdbContainer implements RpcContainer {
 
     private void addJMxControl(final BeanContext current, final String name, final MdbActivationContext activationContext) throws ResourceException {
         if (name == null || "false".equalsIgnoreCase(name)) {
+            logger.debug("Not adding JMX control for " + current.getDeploymentID() + "/" + current.getEjbName());
             return;
         }