Repository: tomee Updated Branches: refs/heads/master b2973d759 -> cb6baa010
Switch to activation properties for MdbActiveOnStartup and MdbJMXControl. Support DeliveryActive as an alternative config setting. Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/5dfa55c4 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/5dfa55c4 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/5dfa55c4 Branch: refs/heads/master Commit: 5dfa55c468511af39a770ccff1b2d4d19bd84253 Parents: c54c0ea Author: Jonathan Gallimore <[email protected]> Authored: Thu Jul 27 11:55:16 2017 +0100 Committer: Jonathan Gallimore <[email protected]> Committed: Thu Jul 27 11:55:16 2017 +0100 ---------------------------------------------------------------------- .../apache/openejb/core/mdb/MdbContainer.java | 21 ++- .../core/mdb/ResourceAdapterControlTest.java | 16 +- .../mdb/ResourceAdapterDeliveryActiveTest.java | 184 +++++++++++++++++++ 3 files changed, 212 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/5dfa55c4/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 579e7f2..eec59af 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 @@ -217,14 +217,28 @@ public class MdbContainer implements RpcContainer { 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")); + boolean activeOnStartup = true; + String activeOnStartupSetting = beanContext.getActivationProperties().get("MdbActiveOnStartup"); + + if (activeOnStartupSetting == null) { + activeOnStartupSetting = beanContext.getActivationProperties().get("DeliveryActive"); + } + + if (activeOnStartupSetting != null) { + activeOnStartup = Boolean.parseBoolean(activeOnStartupSetting); + } + if (activeOnStartup) { activationContext.start(); } else { logger.info("Not auto-activating endpoint for " + beanContext.getDeploymentID()); } - final String jmxName = beanContext.getProperties().getProperty("MdbJMXControl", "true"); + String jmxName = beanContext.getActivationProperties().get("MdbJMXControl"); + if (jmxName == null) { + jmxName = "true"; + } + addJMxControl(beanContext, jmxName, activationContext); } catch (final ResourceException e) { @@ -264,6 +278,9 @@ public class MdbContainer implements RpcContainer { unusedProperties.remove("destinationLookup"); unusedProperties.remove("connectionFactoryLookup"); unusedProperties.remove("beanClass"); + unusedProperties.remove("MdbActiveOnStartup"); + unusedProperties.remove("MdbJMXControl"); + unusedProperties.remove("DeliveryActive"); if (!unusedProperties.isEmpty()) { final String text = "No setter found for the activation spec properties: " + unusedProperties; http://git-wip-us.apache.org/repos/asf/tomee/blob/5dfa55c4/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 index 3885dc5..9019700 100644 --- 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 @@ -17,7 +17,9 @@ package org.apache.openejb.core.mdb; import org.apache.openejb.config.EjbModule; +import org.apache.openejb.jee.ActivationConfig; import org.apache.openejb.jee.EjbJar; +import org.apache.openejb.jee.MessageDrivenBean; import org.apache.openejb.jee.oejb3.EjbDeployment; import org.apache.openejb.jee.oejb3.OpenejbJar; import org.apache.openejb.junit.ApplicationComposer; @@ -83,14 +85,14 @@ public class ResourceAdapterControlTest { @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"); + return new EjbModule( + new EjbJar("test") {{ + addEnterpriseBean(new MessageDrivenBean("ejb/Mdb", Mdb.class) {{ + setActivationConfig(new ActivationConfig()); + getActivationConfig().addProperty("MdbActiveOnStartup", "false"); + getActivationConfig().addProperty("MdbJMXControl", "default:type=test"); + }}); }}); - }}); } @Test http://git-wip-us.apache.org/repos/asf/tomee/blob/5dfa55c4/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterDeliveryActiveTest.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterDeliveryActiveTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterDeliveryActiveTest.java new file mode 100644 index 0000000..f7bca70 --- /dev/null +++ b/container/openejb-core/src/test/java/org/apache/openejb/core/mdb/ResourceAdapterDeliveryActiveTest.java @@ -0,0 +1,184 @@ +/* + * 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.ActivationConfig; +import org.apache.openejb.jee.EjbJar; +import org.apache.openejb.jee.MessageDrivenBean; +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.*; +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.*; + +import java.lang.IllegalStateException; + +@RunWith(ApplicationComposer.class) +public class ResourceAdapterDeliveryActiveTest { + private static final Logger logger = Logger.getLogger(ResourceAdapterDeliveryActiveTest.class.getName()); + @Resource(name = "ResourceAdapterDeliveryActiveTest/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") {{ + addEnterpriseBean(new MessageDrivenBean("ejb/Mdb", Mdb.class) {{ + setActivationConfig(new ActivationConfig()); + getActivationConfig().addProperty("DeliveryActive", "false"); + getActivationConfig().addProperty("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; + } +}
