/* * * 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.tools.pulse.tests; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import org.apache.geode.tools.pulse.internal.data.PulseConstants; import org.apache.geode.security.TestSecurityManager; import org.apache.shiro.SecurityUtils; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.geode.internal.security.shiro.CustomAuthRealm; import org.apache.geode.internal.security.shiro.JMXShiroAuthenticator; import org.apache.geode.management.internal.security.AccessControlMBean; import org.apache.geode.management.internal.security.MBeanServerWrapper; import org.apache.geode.management.internal.security.ResourceConstants; public class Server { private static final String DEFAULT_HOST = "127.0.0.1"; // "localhost" private static final int DEFAULT_PORT = 9999; private final JMXServiceURL url; private MBeanServer mbs; private JMXConnectorServer cs; private String propFile = null; public Server(int port, String properties, String jsonAuthFile) throws Exception { this.propFile = properties; mbs = ManagementFactory.getPlatformMBeanServer(); url = new JMXServiceURL(formJMXServiceURLString(DEFAULT_HOST, port)); // Load the beans first, otherwise we get access denied loadMBeans(); if (jsonAuthFile != null) { System.setProperty("spring.profiles.active", "pulse.authentication.gemfire"); Map<String, Object> env = new HashMap<String, Object>(); // set up Shiro Security Manager Properties securityProperties = new Properties(); securityProperties.setProperty(TestSecurityManager.SECURITY_JSON, jsonAuthFile); Realm realm = new CustomAuthRealm(TestSecurityManager.class.getName(), securityProperties); SecurityManager securityManager = new DefaultSecurityManager(realm); SecurityUtils.setSecurityManager(securityManager); // register the AccessControll bean AccessControlMBean acc = new AccessControlMBean(); ObjectName accessControlMBeanON = new ObjectName(ResourceConstants.OBJECT_NAME_ACCESSCONTROL); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); platformMBeanServer.registerMBean(acc, accessControlMBeanON); // wire in the authenticator and authorizaton JMXShiroAuthenticator interceptor = new JMXShiroAuthenticator(); env.put(JMXConnectorServer.AUTHENTICATOR, interceptor); cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.setMBeanServerForwarder(new MBeanServerWrapper()); // set up the AccessControlMXBean } else { System.setProperty("spring.profiles.active", "pulse.authentication.default"); cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); } try { java.rmi.registry.LocateRegistry.createRegistry(port); System.out.println("RMI registry ready."); } catch (Exception e) { System.out.println("Exception starting RMI registry:"); e.printStackTrace(); } cs.start(); } private String formJMXServiceURLString(String host, int port) throws UnknownHostException { String jmxSerURL = ""; InetAddress inetAddr = InetAddress.getByName(host); if (inetAddr instanceof Inet4Address) { // Create jmx service url for IPv4 address jmxSerURL = "service:jmx:rmi://" + host + "/jndi/rmi://" + host + ":" + port + "/jmxrmi"; } else if (inetAddr instanceof Inet6Address) { // Create jmx service url for IPv6 address jmxSerURL = "service:jmx:rmi://[" + host + "]/jndi/rmi://[" + host + "]:" + port + "/jmxrmi"; } return jmxSerURL; } public void stop() throws IOException { cs.stop(); } private synchronized void loadMBeans() { JMXProperties props = JMXProperties.getInstance(); try { props.load(propFile); } catch (IOException e) { e.printStackTrace(); } // Add servers String[] servers = getArrayProperty(props, "servers"); for (String server : servers) { try { addServerMBean(server); } catch (InstanceAlreadyExistsException e) { e.printStackTrace(); } catch (MBeanRegistrationException e) { e.printStackTrace(); } catch (NotCompliantMBeanException e) { e.printStackTrace(); } catch (MalformedObjectNameException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } } // Add members String[] members = getArrayProperty(props, "members"); for (String m : members) { try { addMemberMBean(m); } catch (InstanceAlreadyExistsException e) { e.printStackTrace(); } catch (MBeanRegistrationException e) { e.printStackTrace(); } catch (NotCompliantMBeanException e) { e.printStackTrace(); } catch (MalformedObjectNameException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } } // Add regions String[] regions = getArrayProperty(props, "regions"); for (String reg : regions) { try { addRegionMBean(reg); } catch (InstanceAlreadyExistsException e) { e.printStackTrace(); } catch (MBeanRegistrationException e) { e.printStackTrace(); } catch (NotCompliantMBeanException e) { e.printStackTrace(); } catch (MalformedObjectNameException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } } } private void addMemberMBean(String m) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { Member m1 = new Member(m); mbs.registerMBean(m1, new ObjectName(Member.OBJECT_NAME + ",member=" + m)); } private void addRegionMBean(String reg) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException { Region regionObject = new Region(reg); mbs.registerMBean(regionObject, new ObjectName(Region.OBJECT_NAME + ",name=/" + reg)); for (String member : regionObject.getMembers()) { RegionOnMember regionOnMemberObject = new RegionOnMember(regionObject.getFullPath(), member); mbs.registerMBean(regionOnMemberObject, new ObjectName( PulseConstants.OBJECT_NAME_REGION_ON_MEMBER_REGION + regionObject.getFullPath() + PulseConstants.OBJECT_NAME_REGION_ON_MEMBER_MEMBER + member)); } } private void addServerMBean(String server) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException { ServerObject so = new ServerObject(server); mbs.registerMBean(so, new ObjectName(ServerObject.OBJECT_NAME)); } private String[] getArrayProperty(JMXProperties props, String propName) { String propVal = props.getProperty(propName, ""); return propVal.split(" "); } public static Server createServer(int port, String properties, String jsonAuthFile) { Server s = null; try { s = new Server(port, properties, jsonAuthFile); } catch (Exception e) { e.printStackTrace(); return null; } return s; } }