/* * 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.geode.test.dunit.rules; import static org.junit.Assert.*; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.Query; import javax.management.QueryExp; 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. */ public class MBeanServerConnectionRule extends DescribedExternalResource { private final int jmxServerPort; private JMXConnector jmxConnector; private MBeanServerConnection con; /** * Rule constructor * * @param port The JMX server port to connect to */ public MBeanServerConnectionRule(int port) { this.jmxServerPort = port; } /** * Retrieve a new proxy MBean * * @return A new proxy MBean of the same type with which the class was constructed */ public <T> T getProxyMBean(Class<T> proxyClass, String beanQueryName) throws MalformedObjectNameException, IOException { ObjectName name = null; QueryExp query = null; if (proxyClass != null) { query = Query.isInstanceOf(Query.value(proxyClass.getName())); } if (beanQueryName != null) { name = ObjectName.getInstance(beanQueryName); } Set<ObjectInstance> beans = con.queryMBeans(name, query); assertEquals("failed to find only one instance of type " + proxyClass.getName() + " with name " + beanQueryName, 1, beans.size()); return JMX.newMXBeanProxy(con, ((ObjectInstance) beans.toArray()[0]).getObjectName(), proxyClass); } public AccessControlMXBean getAccessControlMBean() throws Exception { return JMX.newMXBeanProxy(con, new ObjectName("GemFire:service=AccessControl,type=Distributed"), AccessControlMXBean.class); } /** * Retrieve a new proxy MBean * * @return A new proxy MBean of the same type with which the class was constructed */ public <T> T getProxyMBean(Class<T> proxyClass) throws MalformedObjectNameException, IOException { return getProxyMBean(proxyClass, null); } public <T> T getProxyMBean(String beanQueryName) throws MalformedObjectNameException, IOException { return getProxyMBean(null, beanQueryName); } public MBeanServerConnection getMBeanServerConnection() throws IOException { return con; } protected void before(Description description) throws Throwable { ConnectionConfiguration config = description.getAnnotation(ConnectionConfiguration.class); 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(); } } /** * Override to tear down your specific external resource. */ protected void after(Description description) throws Throwable { if (jmxConnector != null) { jmxConnector.close(); jmxConnector = null; } con = null; } }