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 2018/09/14 15:22:35 UTC

[05/12] tomee git commit: Cleanup JMX object and add test

Cleanup JMX object and add test


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

Branch: refs/heads/master
Commit: d18fbc0ddf38a5c3023729f5426aa319d57c4047
Parents: 65768ea
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Mon Sep 3 20:22:33 2018 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Mon Sep 3 20:22:33 2018 +0100

----------------------------------------------------------------------
 .../openejb/assembler/classic/Assembler.java    |  21 ++-
 .../monitoring/ConnectionFactoryMonitor.java    | 169 +++++++++++++++++++
 .../classic/ConnectionFactoryJMXTest.java       | 133 +++++++++++++++
 3 files changed, 320 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/d18fbc0d/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index 76feebc..3b3d60f 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -2164,6 +2164,24 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
             } catch (final Exception e) {
                 logger.debug("Not processing resource on destroy: " + className, e);
             }
+
+            // remove associated JMX object
+            final ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+            jmxName.set("J2EEServer", "openejb");
+            jmxName.set("J2EEApplication", null);
+            jmxName.set("j2eeType", "");
+            jmxName.set("name",name);
+
+            final MBeanServer server = LocalMBeanServer.get();
+            try {
+                final ObjectName objectName = jmxName.set("j2eeType", "ConnectionFactory").build();
+                if (server.isRegistered(objectName)) {
+                    server.unregisterMBean(objectName);
+                }
+            } catch (final Exception e) {
+                logger.error("Unable to unregister MBean ", e);
+            }
+
         } else if (DestroyableResource.class.isInstance(object)) {
             try {
                 DestroyableResource.class.cast(object).destroyResource();
@@ -2834,9 +2852,6 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
         if (Container.class.isInstance(service) && LocalMBeanServer.isJMXActive()) {
             final ObjectName objectName = ObjectNameBuilder.uniqueName("containers", serviceInfo.id, service);
             try {
-
-                // TODO: is there anything further we want to include here?
-                // TODO: live state for MDB pool
                 LocalMBeanServer.get().registerMBean(new DynamicMBeanWrapper(new JMXContainer(serviceInfo, (Container) service)), objectName);
                 containerObjectNames.add(objectName);
             } catch (final Exception | NoClassDefFoundError e) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/d18fbc0d/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ConnectionFactoryMonitor.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ConnectionFactoryMonitor.java b/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ConnectionFactoryMonitor.java
new file mode 100644
index 0000000..2f57f89
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ConnectionFactoryMonitor.java
@@ -0,0 +1,169 @@
+/*
+ * 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.monitoring;
+
+import org.apache.geronimo.connector.outbound.GenericConnectionManager;
+import org.apache.geronimo.connector.outbound.connectionmanagerconfig.NoPool;
+import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PartitionedPool;
+import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
+import org.apache.geronimo.connector.outbound.connectionmanagerconfig.SinglePool;
+
+public class ConnectionFactoryMonitor {
+
+    private final String name;
+    private final GenericConnectionManager connectionManager;
+    private final String txSupport;
+
+    public ConnectionFactoryMonitor(final String name, final GenericConnectionManager connectionManager, final String txSupport) {
+        this.name = name;
+        this.connectionManager = connectionManager;
+        this.txSupport = txSupport;
+    }
+
+    private PoolingSupport getPooling() {
+        return connectionManager.getPooling();
+    }
+
+    @Managed
+    public int getMaxSize() {
+        final PoolingSupport pooling = getPooling();
+
+        if (PartitionedPool.class.isInstance(pooling)) {
+            return PartitionedPool.class.cast(pooling).getMaxSize();
+        } else if (SinglePool.class.isInstance(pooling)) {
+            return SinglePool.class.cast(pooling).getMaxSize();
+        } else if (NoPool.class.isInstance(pooling)) {
+            return 0;
+        } else {
+            return 0;
+        }
+    }
+
+    @Managed
+    public int getMinSize() {
+        final PoolingSupport pooling = getPooling();
+
+        if (PartitionedPool.class.isInstance(pooling)) {
+            return 0;
+        } else if (SinglePool.class.isInstance(pooling)) {
+            return SinglePool.class.cast(pooling).getMinSize();
+        } else if (NoPool.class.isInstance(pooling)) {
+            return 0;
+        } else {
+            return 0;
+        }
+    }
+
+    @Managed
+    public int getBlockingTimeoutMilliseconds() {
+        return connectionManager.getBlockingTimeoutMilliseconds();
+    }
+
+    @Managed
+    public int getIdleTimeoutMinutes() {
+        return connectionManager.getIdleTimeoutMinutes();
+    }
+
+    @Managed
+    public boolean isMatchAll() {
+        final PoolingSupport pooling = getPooling();
+
+        if (PartitionedPool.class.isInstance(pooling)) {
+            return PartitionedPool.class.cast(pooling).isMatchAll();
+        } else if (SinglePool.class.isInstance(pooling)) {
+            return SinglePool.class.cast(pooling).isMatchAll();
+        } else if (NoPool.class.isInstance(pooling)) {
+            return false;
+        } else {
+            return false;
+        }
+    }
+
+    @Managed
+    public String getPartitionStrategy() {
+        final PoolingSupport pooling = getPooling();
+
+        if (PartitionedPool.class.isInstance(pooling)) {
+            if (PartitionedPool.class.cast(pooling).isPartitionByConnectionRequestInfo()) {
+                return PartitionStrategy.BY_CONNECTOR_PROPERTIES.toString();
+            }
+
+            if (PartitionedPool.class.cast(pooling).isPartitionBySubject()) {
+                return PartitionStrategy.BY_SUBJECT.toString();
+            }
+
+            return PartitionStrategy.UNKNOWN.toString();
+        } else if (SinglePool.class.isInstance(pooling)) {
+            return PartitionStrategy.NONE.toString();
+        } else if (NoPool.class.isInstance(pooling)) {
+            return PartitionStrategy.NONE.toString();
+        } else {
+            return PartitionStrategy.NONE.toString();
+        }
+    }
+
+    @Managed
+    public String getTxSupport() {
+        return txSupport;
+    }
+
+    @Managed
+    public int getPartitionCount() {
+        return connectionManager.getPartitionCount();
+    }
+
+    @Managed
+    public int getPartitionMaxSize() {
+        return connectionManager.getPartitionMaxSize();
+    }
+
+    @Managed
+    public int getPartitionMinSize() {
+        return connectionManager.getPartitionMinSize();
+    }
+
+    @Managed
+    public int getIdleConnectionCount() {
+        return connectionManager.getIdleConnectionCount();
+    }
+
+    @Managed
+    public int getConnectionCount() {
+        return connectionManager.getConnectionCount();
+    }
+
+    @Managed
+    public String getName() {
+        return name;
+    }
+
+    public enum PartitionStrategy {
+        NONE("none"), BY_SUBJECT("by-subject"), BY_CONNECTOR_PROPERTIES("by-connector-properties"), UNKNOWN("unknown");
+
+        private final String name;
+
+        PartitionStrategy(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/d18fbc0d/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ConnectionFactoryJMXTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ConnectionFactoryJMXTest.java b/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ConnectionFactoryJMXTest.java
new file mode 100644
index 0000000..5490fa7
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ConnectionFactoryJMXTest.java
@@ -0,0 +1,133 @@
+/**
+ *
+ * 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.assembler.classic;
+
+import junit.framework.TestCase;
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.client.LocalInitialContextFactory;
+import org.apache.openejb.monitoring.LocalMBeanServer;
+
+import javax.annotation.Resource;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.util.Properties;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConnectionFactoryJMXTest extends TestCase {
+
+    public void test() throws Exception {
+        final ConfigurationFactory config = new ConfigurationFactory();
+        final Assembler assembler = new Assembler();
+
+        // System services
+        assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        // Fake connection factory
+        assembler.createResource(config.configureService("Default JMS Resource Adapter", ResourceInfo.class));
+        final ResourceInfo resourceInfo = config.configureService("Default JMS Connection Factory", ResourceInfo.class);
+        resourceInfo.id = "CF";
+        resourceInfo.properties.setProperty("TransactionSupport", "xa");
+        resourceInfo.properties.setProperty("MaxConnections", "5");
+        assembler.createResource(resourceInfo);
+
+        // generate ejb jar application
+        final EjbJar ejbJar = new EjbJar();
+        ejbJar.addEnterpriseBean(new StatelessBean("fakeBean", FakeStatelessBean.class));
+        final EjbModule ejbModule = new EjbModule(getClass().getClassLoader(), "FakeEjbJar", "fake.jar", ejbJar, null);
+
+        // configure and deploy it
+        final EjbJarInfo info = config.configureApplication(ejbModule);
+        assembler.createEjbJar(info);
+
+        check(new ObjectName("openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,j2eeType=ConnectionFactory,name=CF"), 0, 0);
+
+        final Properties p = new Properties();
+        p.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+        final FakeStateless fakeBeanLocal = (FakeStateless) new InitialContext(p).lookup("fakeBeanLocal");
+        fakeBeanLocal.doIt();
+
+        OpenEJB.destroy();
+
+        // ensure the bean is removed when the resource is undeployed
+        assertFalse(LocalMBeanServer.get().isRegistered(new ObjectName("openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,j2eeType=ConnectionFactory,name=CF")));
+    }
+
+    private static void check(ObjectName on, final int connectionCount, final int idleCount) throws InstanceNotFoundException, IntrospectionException, ReflectionException, MBeanException, AttributeNotFoundException {
+        assertNotNull(LocalMBeanServer.get().getMBeanInfo(on));
+
+        assertEquals(5000, LocalMBeanServer.get().getAttribute(on, "BlockingTimeoutMilliseconds"));
+        assertEquals(connectionCount, LocalMBeanServer.get().getAttribute(on, "ConnectionCount"));
+        assertEquals(idleCount, LocalMBeanServer.get().getAttribute(on, "IdleConnectionCount"));
+        assertEquals(15, LocalMBeanServer.get().getAttribute(on, "IdleTimeoutMinutes"));
+        assertEquals(false, LocalMBeanServer.get().getAttribute(on, "MatchAll"));
+        assertEquals(10, LocalMBeanServer.get().getAttribute(on, "MaxSize"));
+        assertEquals(0, LocalMBeanServer.get().getAttribute(on, "MinSize"));
+        assertEquals("CF", LocalMBeanServer.get().getAttribute(on, "Name"));
+        assertEquals(1, LocalMBeanServer.get().getAttribute(on, "PartitionCount"));
+        assertEquals(10, LocalMBeanServer.get().getAttribute(on, "PartitionMaxSize"));
+        assertEquals(0, LocalMBeanServer.get().getAttribute(on, "PartitionMinSize"));
+        assertEquals("none", LocalMBeanServer.get().getAttribute(on, "PartitionStrategy"));
+        assertEquals("xa", LocalMBeanServer.get().getAttribute(on, "TxSupport"));
+    }
+
+    public interface FakeStateless {
+        public void doIt();
+    }
+
+    public static class FakeStatelessBean implements FakeStateless {
+
+        @Resource
+        private ConnectionFactory cf;
+
+        @Override
+        public void doIt() {
+            try {
+                final Connection connection = cf.createConnection();
+
+                // check we see the connection and it is not idle
+                check(
+                        new ObjectName("openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,j2eeType=ConnectionFactory,name=CF"),
+                        1,
+                        0
+                );
+
+                connection.close();
+            } catch (Exception e) {
+                fail("Unexpected exception thrown " + e);
+            }
+
+
+        }
+    }
+}