001/* 002 * (C) Copyright 2013-2014 Nuxeo SA (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-2.1.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 * slacoin 016 */ 017package org.nuxeo.dmk; 018 019import java.io.IOException; 020import java.lang.management.ManagementFactory; 021import java.net.MalformedURLException; 022import java.util.HashMap; 023import java.util.Map; 024 025import javax.management.InstanceAlreadyExistsException; 026import javax.management.InstanceNotFoundException; 027import javax.management.JMException; 028import javax.management.MBeanRegistrationException; 029import javax.management.MBeanServer; 030import javax.management.MalformedObjectNameException; 031import javax.management.NotCompliantMBeanException; 032import javax.management.ObjectName; 033import javax.management.remote.JMXConnectorServerFactory; 034import javax.management.remote.JMXServiceURL; 035 036import org.apache.commons.logging.Log; 037import org.apache.commons.logging.LogFactory; 038import org.nuxeo.runtime.model.ComponentContext; 039import org.nuxeo.runtime.model.ComponentInstance; 040import org.nuxeo.runtime.model.DefaultComponent; 041 042import com.sun.jdmk.comm.AuthInfo; 043import com.sun.jdmk.comm.GenericHttpConnectorServer; 044import com.sun.jdmk.comm.HtmlAdaptorServer; 045import com.sun.jdmk.comm.internal.JDMKServerConnector; 046 047public class DmkComponent extends DefaultComponent { 048 049 protected final Map<String, DmkProtocol> configs = new HashMap<>(); 050 051 protected HtmlAdaptorServer htmlAdaptor; 052 053 protected JDMKServerConnector httpConnector; 054 055 protected JDMKServerConnector httpsConnector; 056 057 protected final Log log = LogFactory.getLog(DmkComponent.class); 058 059 protected final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 060 061 protected HtmlAdaptorServer newAdaptor(DmkProtocol config) { 062 HtmlAdaptorServer adaptor = new HtmlAdaptorServer(); 063 adaptor.addUserAuthenticationInfo(new AuthInfo(config.user, config.password)); 064 adaptor.setPort(config.port); 065 try { 066 ObjectName name = new ObjectName("org.nuxeo:type=jmx-adaptor,format=html"); 067 mbs.registerMBean(adaptor, name); 068 } catch (JMException e) { 069 throw new RuntimeException(e); 070 } 071 return adaptor; 072 } 073 074 protected void destroyAdaptor(HtmlAdaptorServer adaptor) { 075 try { 076 ObjectName name = new ObjectName("org.nuxeo:type=jmx-adaptor,format=html"); 077 mbs.unregisterMBean(name); 078 } catch (JMException e) { 079 throw new RuntimeException(e); 080 } 081 if (!adaptor.isActive()) { 082 return; 083 } 084 adaptor.stop(); 085 } 086 087 protected JDMKServerConnector newConnector(DmkProtocol config) { 088 try { 089 String protocol = "jdmk-".concat(config.name); 090 JMXServiceURL httpURL = new JMXServiceURL(protocol, null, config.port); 091 JDMKServerConnector connector = (JDMKServerConnector) JMXConnectorServerFactory.newJMXConnectorServer( 092 httpURL, null, mbs); 093 GenericHttpConnectorServer server = (GenericHttpConnectorServer) connector.getWrapped(); 094 server.addUserAuthenticationInfo(new AuthInfo(config.user, config.password)); 095 ObjectName name = new ObjectName("org.nuxeo:type=jmx-connector,protocol=".concat(protocol)); 096 mbs.registerMBean(connector, name); 097 return connector; 098 } catch (JMException | IOException e) { 099 throw new RuntimeException(e); 100 } 101 } 102 103 protected void destroyConnector(JDMKServerConnector connector) { 104 String protocol = connector.getAddress().getProtocol(); 105 try { 106 ObjectName name = new ObjectName("org.nuxeo:type=jmx-connector,protocol=".concat(protocol)); 107 mbs.unregisterMBean(name); 108 } catch (JMException e) { 109 throw new RuntimeException(e); 110 } 111 if (!connector.isActive()) { 112 return; 113 } 114 try { 115 connector.stop(); 116 } catch (IOException e) { 117 throw new RuntimeException(e); 118 } 119 } 120 121 @Override 122 public void deactivate(ComponentContext arg0) { 123 if (htmlAdaptor != null) { 124 try { 125 destroyAdaptor(htmlAdaptor); 126 } finally { 127 htmlAdaptor = null; 128 } 129 } 130 131 if (httpConnector != null) { 132 133 try { 134 destroyConnector(httpConnector); 135 } finally { 136 httpConnector = null; 137 } 138 } 139 140 if (httpsConnector != null) { 141 try { 142 destroyConnector(httpsConnector); 143 } finally { 144 httpsConnector = null; 145 } 146 } 147 148 } 149 150 @Override 151 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 152 if ("protocols".equals(extensionPoint)) { 153 DmkProtocol protocol = (DmkProtocol) contribution; 154 configs.put(protocol.name, protocol); 155 } 156 } 157 158 @Override 159 public void applicationStarted(ComponentContext context) { 160 if (configs.containsKey("html")) { 161 htmlAdaptor = newAdaptor(configs.get("html")); 162 log.info("JMX HTML adaptor available at port 8081 (not active, to be started in JMX console)"); 163 } 164 if (configs.containsKey("http")) { 165 httpConnector = newConnector(configs.get("http")); 166 log.info("JMX HTTP connector available at " + httpConnector.getAddress() 167 + " (not active, to be started in JMX console)"); 168 } 169 if (configs.containsKey("https")) { 170 httpsConnector = newConnector(configs.get("https")); 171 log.info("JMX HTTPS connector available at " + httpConnector.getAddress() 172 + " (not active, to be started in JMX console)"); 173 } 174 } 175}