View Javadoc

1   /*
2    * Created on Feb 3, 2004
3    *
4    */
5   
6   package org.neo.swarm.config;
7   
8   import java.io.IOException;
9   import java.net.BindException;
10  import java.net.InetAddress;
11  import java.net.UnknownHostException;
12  import java.util.HashMap;
13  import java.util.Map;
14  
15  import javax.management.AttributeNotFoundException;
16  import javax.management.InstanceAlreadyExistsException;
17  import javax.management.InstanceNotFoundException;
18  import javax.management.MBeanException;
19  import javax.management.MBeanRegistrationException;
20  import javax.management.MBeanServer;
21  import javax.management.MBeanServerFactory;
22  import javax.management.MalformedObjectNameException;
23  import javax.management.NotCompliantMBeanException;
24  import javax.management.ObjectName;
25  import javax.management.ReflectionException;
26  import javax.management.remote.JMXConnectorServer;
27  import javax.management.remote.JMXConnectorServerFactory;
28  import javax.management.remote.JMXServiceURL;
29  import javax.naming.Context;
30  
31  import mx4j.adaptor.http.HttpAdaptor;
32  import mx4j.adaptor.http.XSLTProcessor;
33  import mx4j.log.Log;
34  
35  import org.neo.swarm.ApplicationContext;
36  import org.neo.swarm.SwarmContainer;
37  import org.neo.swarm.interceptor.jmx.Jmx;
38  
39  /***
40   * Same as SimpleConfig but uses JMX orthogonal aspects for JMX Management wih MX4J.
41   * 
42   * @author navery
43   */
44  public class JMXConfig extends DynamicConfig {
45  
46  	int jmxPort;
47  	InetAddress multicastAddress;
48  	int multicastPort = 5000;
49  	int bindSleepPeriod = 3 * 1000;
50  	private MBeanServer jmxServer;
51  	private int namingPort = 8999;
52  
53  	public JMXConfig(String uri, InetAddress myAddress, int myPort, int JmxPort, boolean loggingEabled) {
54  		super(uri, myAddress, myPort, loggingEabled);
55  		this.uri = uri;
56  		this.jmxPort = JmxPort;
57  		try {
58  			this.multicastAddress = InetAddress.getByName("225.0.0.1");
59  		} catch (UnknownHostException e) {
60  			e.printStackTrace();
61  		}
62  	}
63  
64  	/*
65  	 * (non-Javadoc)
66  	 * 
67  	 * @see org.neo.swarm.config.Config#setup()
68  	 */
69  	public SwarmContainer setup() throws Exception {
70          jmxServer = MBeanServerFactory.createMBeanServer();
71  
72  		super.setup();
73  
74  		startHttpAdaptor();
75  		startRMIAdaptor();
76  
77  
78  		ApplicationContext ac = container.getAppContext(uri);
79  		ac.addOrthogonalAspect(new Jmx("USER", "ASPECT", jmxServer)); // manage aspects on user components
80  		ac.addAspect(new Jmx("USER", "COMP", jmxServer)); // manage user components
81  		return container;
82  	}
83      protected void setupTcpService(ApplicationContext context) throws Exception  {
84          // manage System Aspects (on components)
85          container.addOrthogonalServiceAspect(new Jmx("SERVICE", "ASPECT", jmxServer));
86  
87          // control System Services via JMX
88          container.addServiceAspect(new Jmx("SERVICE", "MGMT", jmxServer));
89          super.setupTcpService(context);   
90      }
91  	/***
92  	 * Starts the http server on the configured port.
93  	 *  
94  	 */
95  	public void startHttpAdaptor() {
96  		try {
97  
98  			// Redirect MX4J logging to Log4J
99  //			Log.redirectTo(new Log4JLogger());
100 			Log.redirectTo(null);
101 
102 			XSLTProcessor xslt = new XSLTProcessor();
103 			ObjectName xsltName = new ObjectName("Server:serviceName=XSLTProcessor");
104 			jmxServer.registerMBean(xslt, xsltName);
105 			xslt.setUseCache(false);
106 			//		xslt.setPathInJar("/mx4j/adaptor/http/xsl");
107 			xslt.setLocaleString("en");
108 			//	xslt.setFile("src/resources/jmx/xsl");
109 
110 			HttpAdaptor adapter = new HttpAdaptor();
111 			ObjectName httpName = new ObjectName("Server:serviceName=HttpAdaptor");
112 
113 			adapter.setPort(this.jmxPort);
114 			adapter.setProcessorName(xsltName);
115 			jmxServer.registerMBean(adapter, httpName);
116 			adapter.start();
117 
118 			// drop the MBeanServer into the Services Container
119 			container.registerServiceInstance("mx4j", jmxServer);
120 		} catch (BindException e) {
121 			e.printStackTrace();
122 		} catch (Exception e) {
123 			e.printStackTrace();
124 		}
125 	}
126 
127 	/*** Class to use for the naming service. */
128 	private static final String NAMING_SERVICE_CLASS_NAME = "mx4j.tools.naming.NamingService";
129 	/*** The Jmx type string. */
130 	private static final String REGISTRY_OBJECT_NAME_STRING = "Naming:type=rmiregistry";
131 
132 	/*** com.sun.jndi.rmi.registry.RegistryContextFactory */
133 	String InitialContextFactoryClass = "com.sun.jndi.rmi.registry.RegistryContextFactory";
134 
135 	/***
136 	 * Support for MC4J to connect using RMI, see http://mc4j.sourceforge.net
137 	 */
138 	public void startRMIAdaptor() {
139 
140 		try {
141 			startMBeanNamingService();
142 
143             JMXServiceURL url = new JMXServiceURL("rmi", this.address.getHostName(), namingPort, "/jndi/jrmp");
144             Map environment = new HashMap();
145             environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
146             environment.put(Context.PROVIDER_URL, "rmi://localhost:" + namingPort);
147             
148 			JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, environment, null);    
149 			ObjectName connectorServerName = ObjectName.getInstance("connectors:protocol=" + url.getProtocol());
150           
151 			jmxServer.registerMBean(connectorServer, connectorServerName);
152 			connectorServer.start();
153 		} catch (NotCompliantMBeanException ex) {
154 			ex.printStackTrace();
155 		} catch (MalformedObjectNameException ex) {
156 			ex.printStackTrace();
157 		} catch (MBeanException ex) {
158 			ex.printStackTrace();
159 		} catch (InstanceAlreadyExistsException ex) {
160 			ex.printStackTrace();
161 		} catch (IOException ex) {
162 			System.out.println("Ignoring = RMI-IOException:" + ex);
163 		}
164 	}
165 
166 	private void startMBeanNamingService() {
167 		ObjectName namingName;
168 		try {
169 			namingName = new ObjectName(REGISTRY_OBJECT_NAME_STRING);
170     		jmxServer.createMBean(NAMING_SERVICE_CLASS_NAME, namingName, null);
171             jmxServer.invoke(namingName, "start", null, null);            
172             namingPort = ((Integer)jmxServer.getAttribute(namingName, "Port")).intValue();
173             System.out.println("Started naming service on port:"+namingPort);
174 //    		jmxServer.setAttribute(namingName, new Attribute("Port", new Integer(namingPort)));
175         } catch (MalformedObjectNameException e) {
176             e.printStackTrace();
177         } catch (InstanceAlreadyExistsException e) {
178 			e.printStackTrace();
179 		} catch (MBeanRegistrationException e) {
180 			e.printStackTrace();
181 		} catch (NotCompliantMBeanException e) {
182 			e.printStackTrace();
183 		} catch (InstanceNotFoundException e) {
184 			e.printStackTrace();
185 		} catch (ReflectionException e) {
186 			e.printStackTrace();
187 		} catch (MBeanException e) {
188             System.out.println("Ignoring MBeanException:"+e);
189 		} catch (AttributeNotFoundException e) {
190 			e.printStackTrace();
191 		}
192         System.out.println("Starting naming service on port:" + namingPort);
193 	}
194 }