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