001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * matic 016 */ 017package org.nuxeo.runtime.management; 018 019import java.io.IOException; 020import java.lang.management.ManagementFactory; 021import java.net.InetAddress; 022import java.net.MalformedURLException; 023import java.net.UnknownHostException; 024import java.rmi.RemoteException; 025import java.rmi.registry.LocateRegistry; 026import java.util.HashMap; 027import java.util.Map; 028 029import javax.management.MBeanServer; 030import javax.management.MBeanServerFactory; 031import javax.management.ObjectName; 032import javax.management.remote.JMXServiceURL; 033import javax.management.remote.rmi.RMIConnectorServer; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.nuxeo.runtime.model.ComponentInstance; 038import org.nuxeo.runtime.model.DefaultComponent; 039 040public class ServerLocatorService extends DefaultComponent implements ServerLocator { 041 042 public static final String LOCATORS_EXT_KEY = "locators"; 043 044 private static final Log log = LogFactory.getLog(ServerLocatorService.class); 045 046 protected final Map<String, MBeanServer> servers = new HashMap<String, MBeanServer>(); 047 048 protected MBeanServer defaultServer = ManagementFactory.getPlatformMBeanServer(); 049 050 protected String hostname; 051 052 @Override 053 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 054 if (extensionPoint.equals(LOCATORS_EXT_KEY)) { 055 doRegisterLocator((ServerLocatorDescriptor) contribution); 056 } 057 } 058 059 @Override 060 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 061 if (extensionPoint.equals(LOCATORS_EXT_KEY)) { 062 doUnregisterLocator((ServerLocatorDescriptor) contribution); 063 } 064 } 065 066 protected void doRegisterLocator(ServerLocatorDescriptor descriptor) { 067 MBeanServer server = descriptor.isExisting ? doFindServer(descriptor.domainName) : doCreateServer(descriptor); 068 servers.put(descriptor.domainName, server); 069 if (descriptor.isDefault) { 070 defaultServer = server; 071 } 072 } 073 074 protected String doGetHostname() { 075 if (hostname != null) { 076 return hostname; 077 } 078 try { 079 InetAddress addr = InetAddress.getLocalHost(); 080 hostname = addr.getHostName(); 081 } catch (UnknownHostException e) { 082 hostname = "localhost"; 083 } 084 return hostname; 085 } 086 087 protected JMXServiceURL doFormatServerURL(ServerLocatorDescriptor descriptor) { 088 try { 089 return new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + descriptor.rmiPort + "/" 090 + descriptor.domainName + "/jmxrmi"); 091 } catch (MalformedURLException e) { 092 throw new ManagementRuntimeException("Cannot format url for " + descriptor.domainName); 093 } 094 } 095 096 protected String doFormatThreadName(ServerLocatorDescriptor descriptor) { 097 return "mbeanServer-" + descriptor.domainName; 098 } 099 100 protected MBeanServer doCreateServer(final ServerLocatorDescriptor descriptor) { 101 MBeanServer server = MBeanServerFactory.createMBeanServer(); 102 JMXServiceURL url = doFormatServerURL(descriptor); 103 if (!descriptor.remote) { 104 return server; 105 } 106 final RMIConnectorServer connector; 107 try { 108 connector = new RMIConnectorServer(url, null, server); 109 } catch (IOException e) { 110 throw new ManagementRuntimeException("Cannot start connector for " + descriptor.domainName, e); 111 } 112 try { 113 connector.start(); 114 } catch (IOException e) { 115 try { 116 LocateRegistry.createRegistry(descriptor.rmiPort); 117 } catch (RemoteException e2) { 118 throw new ManagementRuntimeException("Cannot start RMI connector for " + descriptor.domainName, e); 119 } 120 try { 121 connector.start(); 122 } catch (IOException e2) { 123 throw new ManagementRuntimeException("Cannot start RMI connector for " + descriptor.domainName, e2); 124 } 125 } 126 assert connector.isActive(); 127 log.info("Started a mbean server : " + url); 128 return server; 129 } 130 131 @SuppressWarnings("cast") 132 protected MBeanServer doFindServer(String domainName) { 133 for (MBeanServer server : MBeanServerFactory.findMBeanServer(null)) { 134 String domain = server.getDefaultDomain(); 135 if (domain == null || !domain.equals(domainName)) { 136 continue; 137 } 138 return server; 139 } 140 return defaultServer; 141 } 142 143 protected void doUnregisterLocator(ServerLocatorDescriptor descriptor) { 144 servers.remove(descriptor.domainName); 145 if (descriptor.isDefault) { 146 defaultServer = ManagementFactory.getPlatformMBeanServer(); 147 } 148 } 149 150 @Override 151 @SuppressWarnings("cast") 152 public MBeanServer lookupServer(ObjectName qualifiedName) { 153 if (defaultServer.isRegistered(qualifiedName)) { 154 return defaultServer; 155 } 156 for (MBeanServer server : MBeanServerFactory.findMBeanServer(null)) { 157 if (server.isRegistered(qualifiedName)) { 158 return server; 159 } 160 } 161 throw new ManagementRuntimeException(qualifiedName + " is not registered"); 162 } 163 164 @Override 165 public MBeanServer lookupServer() { 166 return defaultServer; 167 } 168 169 @Override 170 public MBeanServer lookupServer(String domainName) { 171 return doFindServer(domainName); 172 } 173 174 public void registerLocator(String domain, boolean isDefault) { 175 doRegisterLocator(new ServerLocatorDescriptor(domain, isDefault)); 176 } 177 178}