GEODE-1716: refactor JMXMBeanDunitTest * refactor MBeanServerConnectRule for easier usage. * refactor LocatorServerStartupRule to be able to start up locator/server in VM out of sequence
Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/f19ccfd0 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/f19ccfd0 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/f19ccfd0 Branch: refs/heads/feature/GEODE-2449 Commit: f19ccfd07d3a6e81203f94c6630645ea729d243f Parents: 652e9a5 Author: Jinmei Liao <jil...@pivotal.io> Authored: Fri Feb 10 22:31:50 2017 -0800 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Mon Feb 13 11:21:21 2017 -0800 ---------------------------------------------------------------------- .../geode/management/JMXMBeanDUnitTest.java | 380 +++++++------------ .../dunit/rules/LocatorServerStartupRule.java | 14 +- .../dunit/rules/MBeanServerConnectionRule.java | 101 +++-- 3 files changed, 219 insertions(+), 276 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/f19ccfd0/geode-core/src/test/java/org/apache/geode/management/JMXMBeanDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/JMXMBeanDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/JMXMBeanDUnitTest.java index 0feb4c2..ebc3f17 100644 --- a/geode-core/src/test/java/org/apache/geode/management/JMXMBeanDUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/JMXMBeanDUnitTest.java @@ -14,290 +14,178 @@ */ package org.apache.geode.management; -import static org.apache.geode.distributed.ConfigurationProperties.*; -import static org.assertj.core.api.Assertions.*; -import static org.junit.Assert.*; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import javax.management.JMX; -import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; -import javax.rmi.ssl.SslRMIClientSocketFactory; +import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_CIPHERS; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_ENABLED; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_KEYSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_KEYSTORE_PASSWORD; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_KEYSTORE_TYPE; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_PROTOCOLS; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_TRUSTSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_TRUSTSTORE_PASSWORD; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_JMX_ALIAS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_TYPE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.Maps; +import org.apache.geode.internal.AvailablePortHelper; +import org.apache.geode.internal.security.SecurableCommunicationChannel; +import org.apache.geode.test.dunit.rules.LocatorServerStartupRule; +import org.apache.geode.test.dunit.rules.MBeanServerConnectionRule; +import org.apache.geode.test.junit.categories.DistributedTest; +import org.apache.geode.util.test.TestUtil; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.apache.geode.distributed.LocatorLauncher; -import org.apache.geode.internal.AvailablePortHelper; -import org.apache.geode.internal.security.SecurableCommunicationChannel; -import org.apache.geode.test.dunit.DistributedTestCase; -import org.apache.geode.test.dunit.DistributedTestUtils; -import org.apache.geode.test.dunit.Host; -import org.apache.geode.test.dunit.NetworkUtils; -import org.apache.geode.test.dunit.VM; -import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties; -import org.apache.geode.test.junit.categories.FlakyTest; -import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder; -import org.apache.geode.util.test.TestUtil; - -public class JMXMBeanDUnitTest extends DistributedTestCase { - - private Host host; - private VM locator; - private VM jmxClient; - private String serverHostName; - private int locatorPort; - private int jmxPort; - - private static LocatorLauncher locatorLauncher; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import javax.management.MBeanServerConnection; +import javax.rmi.ssl.SslRMIClientSocketFactory; +/** + * All the non-ssl enabled locators need to be in a different VM than the ssl enabled locators in + * these tests, otherwise, some tests would fail. Seems like dunit vm tear down did not clean up the + * ssl settings cleanly. + */ +@Category(DistributedTest.class) +public class JMXMBeanDUnitTest { @Rule - public DistributedRestoreSystemProperties distributedRestoreSystemProperties = - new DistributedRestoreSystemProperties(); + public LocatorServerStartupRule lsRule = new LocatorServerStartupRule(); @Rule - public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder(); + public MBeanServerConnectionRule jmxConnector = new MBeanServerConnectionRule(); + + private int jmxPort; + private Properties locatorProperties = null; + private Map<String, Object> clientEnv = null; + private static Properties legacySSLProperties, sslProperties, sslPropertiesWithMultiKey; + private static String singleKeystore, multiKeystore, multiKeyTruststore; + + + @BeforeClass + public static void beforeClass() { + singleKeystore = TestUtil.getResourcePath(JMXMBeanDUnitTest.class, "/ssl/trusted.keystore"); + multiKeystore = TestUtil.getResourcePath(JMXMBeanDUnitTest.class, + "/org/apache/geode/internal/net/multiKey.jks"); + multiKeyTruststore = TestUtil.getResourcePath(JMXMBeanDUnitTest.class, + "/org/apache/geode/internal/net/multiKeyTrust.jks"); + + // setting up properties used to set the ssl properties used by the locators + legacySSLProperties = new Properties(); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_CIPHERS, "any"); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_PROTOCOLS, "any"); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_ENABLED, "true"); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_KEYSTORE, singleKeystore); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_KEYSTORE_PASSWORD, "password"); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_KEYSTORE_TYPE, "JKS"); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_TRUSTSTORE, singleKeystore); + legacySSLProperties.setProperty(JMX_MANAGER_SSL_TRUSTSTORE_PASSWORD, "password"); + + sslProperties = new Properties(); + sslProperties.setProperty(SSL_CIPHERS, "any"); + sslProperties.setProperty(SSL_KEYSTORE_PASSWORD, "password"); + sslProperties.setProperty(SSL_TRUSTSTORE_PASSWORD, "password"); + sslProperties.setProperty(SSL_KEYSTORE, singleKeystore); + sslProperties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); + sslProperties.setProperty(SSL_TRUSTSTORE, singleKeystore); + sslProperties.setProperty(SSL_ENABLED_COMPONENTS, + SecurableCommunicationChannel.JMX.getConstant()); + sslProperties.setProperty(SSL_PROTOCOLS, "TLSv1.2,TLSv1.1"); + + sslPropertiesWithMultiKey = new Properties(); + sslPropertiesWithMultiKey.putAll(Maps.fromProperties(sslProperties)); + sslPropertiesWithMultiKey.setProperty(SSL_KEYSTORE, multiKeystore); + sslPropertiesWithMultiKey.setProperty(SSL_TRUSTSTORE, multiKeyTruststore); + sslPropertiesWithMultiKey.setProperty(SSL_JMX_ALIAS, "jmxkey"); + } @Before public void before() { - host = Host.getHost(0); - locator = host.getVM(0); - jmxClient = host.getVM(1); - - int[] randomAvailableTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2); - locatorPort = randomAvailableTCPPorts[0]; - jmxPort = randomAvailableTCPPorts[1]; - serverHostName = NetworkUtils.getServerHostName(host); + jmxPort = AvailablePortHelper.getRandomAvailableTCPPort(); + locatorProperties = new Properties(); + locatorProperties.put(JMX_MANAGER_PORT, jmxPort + ""); + locatorProperties.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); + clientEnv = new HashMap<>(); } @Test - public void testJMXOverSSLWithoutJMXAlias() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, true, false, true); - locator.invoke("Configure and start Locator", () -> { - System.setProperty("javax.ssl.debug", "true"); - configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties); - }); - - jmxClient.invoke("Configure and start JMX Client", () -> { - System.setProperty("javax.ssl.debug", "true"); - connectAndValidateAsJmxClient(jmxPort, serverHostName, true, true); - }); + public void testJMXOverNonSSL() throws Exception { + lsRule.startLocatorVM(1, locatorProperties); + jmxConnector.connect(jmxPort); + validateJmxConnection(); } @Test - public void testJMXOverSSLWithJMXAlias() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, true, false, true); - locator.invoke("Configure and start Locator", () -> { - System.setProperty("javax.ssl.debug", "true"); - configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties); - }); + public void testJMXOverNonSSLWithClientUsingIncorrectPort() throws Exception { + lsRule.startLocatorVM(1, locatorProperties); - jmxClient.invoke("Configure and start JMX Client", () -> { - System.setProperty("javax.ssl.debug", "true"); - connectAndValidateAsJmxClient(jmxPort, serverHostName, true, true); - }); + assertThatThrownBy(() -> jmxConnector.connect(9999)) + .hasRootCauseExactlyInstanceOf(java.net.ConnectException.class); } @Test public void testJMXOverSSL() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, true, false, true); - - locator.invoke("Configure and start Locator", () -> { - System.setProperty("javax.ssl.debug", "true"); - configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties); - }); + locatorProperties.putAll(Maps.fromProperties(sslProperties)); + lsRule.startLocatorVM(0, locatorProperties); + clientEnv = getClientEnvironment(false); + jmxConnector.connect(jmxPort, clientEnv); - jmxClient.invoke("Configure and start JMX Client", () -> { - System.setProperty("javax.ssl.debug", "true"); - connectAndValidateAsJmxClient(jmxPort, serverHostName, true); - }); + validateJmxConnection(); } - @Test - @Category(FlakyTest.class) - // To be fixed in GEODE-1716 - public void testJMXOverLegacySSL() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, true, true, false); - locator.invoke("Configure and start Locator", () -> { - System.setProperty("javax.ssl.debug", "true"); - configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties); - }); - - jmxClient.invoke("Configure and start JMX Client", () -> { - System.setProperty("javax.ssl.debug", "true"); - connectAndValidateAsJmxClient(jmxPort, serverHostName, true); - }); - } @Test - public void testJMXOverNonSSL() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, false, false, false); - locator.invoke("Configure and start Locator", - () -> configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties)); - jmxClient.invoke("Configure and start JMX Client", - () -> connectAndValidateAsJmxClient(jmxPort, serverHostName, false)); + public void testJMXOverSSLWithMultiKey() throws Exception { + locatorProperties.putAll(Maps.fromProperties(sslPropertiesWithMultiKey)); + lsRule.startLocatorVM(0, locatorProperties); + clientEnv = getClientEnvironment(true); + jmxConnector.connect(jmxPort, clientEnv); + validateJmxConnection(); } @Test - public void testJMXOverNonSSLWithClientUsingIncorrectPort() throws Exception { - Properties properties = - configureLocatorProperties(new Properties(), jmxPort, serverHostName, false, false, false); - locator.invoke("Configure and start Locator", - () -> configureAndStartLocator(locatorPort, jmxPort, serverHostName, properties)); - - assertThatThrownBy(() -> jmxClient.invoke("Configure and start JMX Client", - () -> connectAndValidateAsJmxClient(9999, serverHostName, false))) - .hasCauseExactlyInstanceOf(IOException.class) - .hasRootCauseExactlyInstanceOf(java.net.ConnectException.class); - } - - - private void connectAndValidateAsJmxClient(final int jmxPort, final String serverHostName, - final boolean useSSL) throws Exception { - connectAndValidateAsJmxClient(jmxPort, serverHostName, useSSL, false); + public void testJMXOverLegacySSL() throws Exception { + locatorProperties.putAll(Maps.fromProperties(legacySSLProperties)); + lsRule.startLocatorVM(0, locatorProperties); + clientEnv = getClientEnvironment(false); + jmxConnector.connect(jmxPort, clientEnv); + validateJmxConnection(); } - private void connectAndValidateAsJmxClient(final int jmxPort, final String serverHostName, - final boolean useSSL, final boolean useMulti) throws Exception { - // JMX RMI + private Map<String, Object> getClientEnvironment(boolean withAlias) { + System.setProperty("javax.net.ssl.keyStore", withAlias ? multiKeystore : singleKeystore); + System.setProperty("javax.net.ssl.keyStoreType", "JKS"); + System.setProperty("javax.net.ssl.keyStorePassword", "password"); + System.setProperty("javax.net.ssl.trustStore", withAlias ? multiKeyTruststore : singleKeystore); + System.setProperty("javax.net.ssl.trustStoreType", "JKS"); + System.setProperty("javax.net.ssl.trustStorePassword", "password"); Map<String, Object> environment = new HashMap(); - - if (useSSL) { - System.setProperty("javax.net.ssl.keyStore", - useMulti ? getMultiKeyKeystore() : getSimpleSingleKeyKeystore()); - System.setProperty("javax.net.ssl.keyStoreType", "JKS"); - System.setProperty("javax.net.ssl.keyStorePassword", "password"); - System.setProperty("javax.net.ssl.trustStore", - useMulti ? getMultiKeyTruststore() : getSimpleSingleKeyKeystore()); - System.setProperty("javax.net.ssl.trustStoreType", "JKS"); - System.setProperty("javax.net.ssl.trustStorePassword", "password"); - environment.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); - } - - JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + serverHostName + ":" + jmxPort - + "/jndi/rmi://" + serverHostName + ":" + jmxPort + "/jmxrmi"); - JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment); - - - try { - MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection(); - - ObjectName mbeanName = new ObjectName("GemFire:service=System,type=Distributed"); - - // Get MBean proxy instance that will be used to make calls to registered MBean - DistributedSystemMXBean distributedSystemMXBean = - JMX.newMBeanProxy(mbeanServerConnection, mbeanName, DistributedSystemMXBean.class, true); - - assertEquals(1, distributedSystemMXBean.getMemberCount()); - assertEquals(1, distributedSystemMXBean.getLocatorCount()); - - } finally { - jmxConnector.close(); - } - } - - private void configureAndStartLocator(final int locatorPort, final int jmxPort, - final String serverHostName, final Properties properties) throws IOException { - configureAndStartLocator(locatorPort, serverHostName, properties); + environment.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); + return environment; } - private void configureAndStartLocator(final int locatorPort, final String serverHostName, - final Properties properties) throws IOException { - DistributedTestUtils.deleteLocatorStateFile(); - - final String memberName = getUniqueName() + "-locator"; - final File workingDirectory = temporaryFolder.newFolder(memberName); - - LocatorLauncher.Builder builder = new LocatorLauncher.Builder(); - - for (String propertyName : properties.stringPropertyNames()) { - builder.set(propertyName, properties.getProperty(propertyName)); - } - locatorLauncher = builder.setBindAddress(serverHostName).setHostnameForClients(serverHostName) - .setMemberName(memberName).setPort(locatorPort) - .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); - locatorLauncher.start(); - - } - - private Properties configureJMXSSLProperties(final Properties properties, final boolean isLegacy, - final boolean useMultiKey) { - if (isLegacy) { - properties.setProperty(JMX_MANAGER_SSL_CIPHERS, "any"); - properties.setProperty(JMX_MANAGER_SSL_PROTOCOLS, "any"); - properties.setProperty(JMX_MANAGER_SSL_ENABLED, "true"); - properties.setProperty(JMX_MANAGER_SSL_KEYSTORE, getSimpleSingleKeyKeystore()); - properties.setProperty(JMX_MANAGER_SSL_KEYSTORE_PASSWORD, "password"); - properties.setProperty(JMX_MANAGER_SSL_TRUSTSTORE, getSimpleSingleKeyKeystore()); - properties.setProperty(JMX_MANAGER_SSL_TRUSTSTORE_PASSWORD, "password"); - } else { - { - properties.setProperty(SSL_CIPHERS, "any"); - properties.setProperty(SSL_PROTOCOLS, "any"); - properties.setProperty(SSL_KEYSTORE_PASSWORD, "password"); - properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "password"); - properties.setProperty(SSL_KEYSTORE, getSimpleSingleKeyKeystore()); - properties.setProperty(SSL_TRUSTSTORE, getSimpleSingleKeyKeystore()); - properties.setProperty(SSL_ENABLED_COMPONENTS, - SecurableCommunicationChannel.JMX.getConstant()); - - if (useMultiKey) { - properties.setProperty(SSL_KEYSTORE, getMultiKeyKeystore()); - properties.setProperty(SSL_TRUSTSTORE, getMultiKeyTruststore()); - properties.setProperty(SSL_JMX_ALIAS, "jmxkey"); - } - } - } - return properties; - } - - private String getSimpleSingleKeyKeystore() { - return TestUtil.getResourcePath(getClass(), "/ssl/trusted.keystore"); - } - - private String getMultiKeyKeystore() { - return TestUtil.getResourcePath(getClass(), "/org/apache/geode/internal/net/multiKey.jks"); - } - - private String getMultiKeyTruststore() { - return TestUtil.getResourcePath(getClass(), "/org/apache/geode/internal/net/multiKeyTrust.jks"); - } - - private Properties configureLocatorProperties(final Properties properties, final int jmxPort, - final String serverHostName, final boolean useSSL, final boolean useLegacySSL, - final boolean useMultiKeyKeystore) { - configureCommonProperties(properties); - properties.setProperty(JMX_MANAGER, "true"); - properties.setProperty(JMX_MANAGER_START, "true"); - properties.setProperty(JMX_MANAGER_PORT, String.valueOf(jmxPort)); - properties.setProperty(JMX_MANAGER_BIND_ADDRESS, serverHostName); - properties.setProperty(JMX_MANAGER_HOSTNAME_FOR_CLIENTS, serverHostName); - - if (useSSL) { - configureJMXSSLProperties(properties, useLegacySSL, useMultiKeyKeystore); - } - return properties; - } - private Properties configureCommonProperties(final Properties properties) { - properties.setProperty(MCAST_PORT, "0"); - properties.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); - properties.setProperty(USE_CLUSTER_CONFIGURATION, "false"); - return properties; + private void validateJmxConnection() throws Exception { + MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection(); + // Get MBean proxy instance that will be used to make calls to registered MBean + DistributedSystemMXBean distributedSystemMXBean = + jmxConnector.getProxyMBean(DistributedSystemMXBean.class); + assertEquals(1, distributedSystemMXBean.getMemberCount()); + assertEquals(1, distributedSystemMXBean.getLocatorCount()); } } http://git-wip-us.apache.org/repos/asf/geode/blob/f19ccfd0/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java index 6c1b496..6844720 100644 --- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java +++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java @@ -29,8 +29,6 @@ import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; import java.util.Properties; @@ -56,7 +54,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial new DistributedRestoreSystemProperties(); private TemporaryFolder temporaryFolder = new SerializableTemporaryFolder(); - private List<Member> members; + private Member[] members; public LocatorServerStartupRule() { DUnitLauncher.launchIfNeeded(); @@ -67,7 +65,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial restoreSystemProperties.before(); temporaryFolder.create(); Invoke.invokeInEveryVM("Stop each VM", this::cleanupVm); - members = new ArrayList<>(4); + members = new Member[4]; } @Override @@ -97,7 +95,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial return locatorStarter.locator.getPort(); }); Locator locator = new Locator(locatorVM, locatorPort, workingDir, name); - members.add(index, locator); + members[index] = locator; return locator; } @@ -124,7 +122,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial return locatorStarter.locator.getPort(); }); Locator locator = new Locator(locatorVM, locatorPort, workingDir, name); - members.add(index, locator); + members[index] = locator; return locator; } @@ -163,7 +161,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial return serverStarter.server.getPort(); }); Server server = new Server(serverVM, port, workingDir, name); - members.add(index, server); + members[index] = server; return server; } @@ -171,7 +169,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial * Returns the {@link Member} running inside the VM with the specified {@code index} */ public Member getMember(int index) { - return members.get(index); + return members[index]; } public TemporaryFolder getTempFolder() { http://git-wip-us.apache.org/repos/asf/geode/blob/f19ccfd0/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MBeanServerConnectionRule.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MBeanServerConnectionRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MBeanServerConnectionRule.java index d85975f..9c6f81e 100644 --- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MBeanServerConnectionRule.java +++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MBeanServerConnectionRule.java @@ -15,13 +15,18 @@ package org.apache.geode.test.dunit.rules; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; + +import org.apache.geode.management.internal.security.AccessControlMXBean; +import org.apache.geode.test.junit.rules.DescribedExternalResource; +import org.awaitility.Awaitility; +import org.junit.runner.Description; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; - +import java.util.concurrent.TimeUnit; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; @@ -33,22 +38,22 @@ import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; -import org.junit.runner.Description; - -import org.apache.geode.management.internal.security.AccessControlMXBean; -import org.apache.geode.test.junit.rules.DescribedExternalResource; - /** - * Class which eases the creation of MBeans for security testing. When combined with - * {@link ConnectionConfiguration} it allows for the creation of per-test connections with different - * user/password combinations. + * This rules handles connection to the MBean Server. If used with {@link ConnectionConfiguration}, + * you will need to construct the rule with a port number, then the rule will call connect for you + * before running your test. + * + * If constructed with no port number, you can connect to any port in your test at anytime, and the + * rule will handle the closing of the connection for you. */ public class MBeanServerConnectionRule extends DescribedExternalResource { - private final int jmxServerPort; + private int jmxServerPort = -1; private JMXConnector jmxConnector; private MBeanServerConnection con; + public MBeanServerConnectionRule() {} + /** * Rule constructor * @@ -107,31 +112,83 @@ public class MBeanServerConnectionRule extends DescribedExternalResource { return con; } + @Override protected void before(Description description) throws Throwable { + // do not auto connect if port is not set + if (jmxServerPort < 0) + return; + + // do not auto connect if no ConnectionConfiguration is defined. ConnectionConfiguration config = description.getAnnotation(ConnectionConfiguration.class); + if (config == null) + return; + Map<String, String[]> env = new HashMap<>(); - if (config != null) { - String user = config.user(); - String password = config.password(); - env.put(JMXConnector.CREDENTIALS, new String[] {user, password}); - - JMXServiceURL url = - new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:" + jmxServerPort + "/jmxrmi"); - jmxConnector = JMXConnectorFactory.connect(url, env); - con = jmxConnector.getMBeanServerConnection(); + String user = config.user(); + String password = config.password(); + env.put(JMXConnector.CREDENTIALS, new String[] {user, password}); + connect(null, jmxServerPort, env); + } + + public void connect(int jmxPort) throws Exception { + connect(null, jmxPort, null); + } + + public void connect(int jmxPort, Map<String, ?> environment) throws Exception { + connect(null, jmxPort, environment); + } + + public void connect(String jmxServer, int jmxPort) throws Exception { + connect(jmxServer, jmxPort, null); + } + + public void connect(String jmxServer, int jmxPort, final Map<String, ?> environment) + throws Exception { + if (jmxServer == null) { + jmxServer = ""; } + + // ServiceUrl: service:jmx:rmi:///jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi + JMXServiceURL url = + new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + jmxServer + ":" + jmxPort + "/jmxrmi"); + + // same as GfshShellConnectorRule: if we connect before the RMI server is ready, we get "Failed + // to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is + // java.rmi.NoSuchObjectException: no such object in table]" Exception + // Have to implement a wait mechanism here. We can use Awaitility here + Awaitility.await().atMost(2, TimeUnit.MINUTES).pollDelay(2, TimeUnit.SECONDS).until(() -> { + Map<String, ?> env = new HashMap<>(); + if (environment != null) { + env = new HashMap<>(environment); + } + try { + jmxConnector = JMXConnectorFactory.connect(url, env); + } catch (Exception e) { + if (e.getMessage().contains("no such object in table")) { + // keep waiting + return false; + } + throw e; + } + return true; + }); + con = jmxConnector.getMBeanServerConnection(); } /** * Override to tear down your specific external resource. */ + @Override protected void after(Description description) throws Throwable { + disconnect(); + } + + public void disconnect() throws Exception { if (jmxConnector != null) { jmxConnector.close(); + con = null; jmxConnector = null; } - - con = null; } }