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