View Javadoc

1   package cz.cuni.amis.pogamut.base.utils;
2   
3   import java.io.IOException;
4   import java.net.InetAddress;
5   import java.net.ServerSocket;
6   import java.rmi.registry.LocateRegistry;
7   import java.util.Properties;
8   import java.util.logging.Level;
9   
10  import javax.management.MBeanServer;
11  import javax.management.MBeanServerConnection;
12  import javax.management.remote.JMXConnector;
13  import javax.management.remote.JMXConnectorFactory;
14  import javax.management.remote.JMXConnectorServer;
15  import javax.management.remote.JMXConnectorServerFactory;
16  import javax.management.remote.JMXServiceURL;
17  
18  import cz.cuni.amis.pogamut.base.agent.module.comm.PogamutJVMComm;
19  import cz.cuni.amis.pogamut.base.utils.jmx.PogamutMBeanServer;
20  import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
21  import cz.cuni.amis.pogamut.base.utils.logging.NetworkLogManager;
22  import cz.cuni.amis.utils.configuration.PropertiesManager;
23  import cz.cuni.amis.utils.exception.PogamutException;
24  
25  /**
26   * Singleton for platform wide settings like: JMX, properties loading.
27   * @author Ik
28   */
29  public class DefaultPogamutPlatform implements PogamutPlatform {
30  
31      LogCategory log = new LogCategory("DefaultPogamutPlatform");
32      //public static PogamutPlatform
33      static PogamutMBeanServer mBeanServer = null;
34      static JMXConnectorServer cs = null;
35      JMXServiceURL jmxServiceURL = null;
36      PropertiesManager propertiesManager = new PropertiesManager();
37      
38      public DefaultPogamutPlatform() {
39      	log.addConsoleHandler();
40      }
41  
42      @Override
43      public JMXServiceURL getMBeanServerURL() throws PogamutException {
44          try {
45              String hostNameProp = getProperty(PogamutProperty.POGAMUT_JMX_SERVER_ADDRESS.getKey());
46              String hostName = hostNameProp != null ? hostNameProp : InetAddress.getLocalHost().getHostName();
47              return new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + getRMIPort() + "/server");
48          } catch (Exception ex) {
49              throw new PogamutException("Error creating the JMX service URL.", ex, this);
50          }
51      }
52  
53      protected int getRMIPort() throws PogamutException {
54          if (assignedPort == null) {
55              try {
56                  // TODO not working now
57                  // find free port, start with the desired port
58                  //assignedPort = Integer.parseInt(getProperty(PogamutProperty.POGAMUT_JMX_SERVER_RMI_PORT.getKey()));
59                  // find free port            	
60                  ServerSocket socket = new ServerSocket(0);
61                  assignedPort = socket.getLocalPort();
62                  socket.close();
63              } catch (IOException ex) {
64                  throw new PogamutException("Error while getting a port for RMI.", ex);
65              }
66          }
67          return assignedPort;
68      }
69      Integer assignedPort = null;
70      private boolean registryCreated = false;
71  
72      /**
73       * Returns MBeans server for the Pogamut Platform. All MBeans connected from
74       * the platform should be registered in this server. There is also default
75       * RMI connector for this server running on service:jmx:rmi:///jndi/rmi://localhost:9999/server
76       * @return
77       * @throws cz.cuni.amis.utils.exception.PogamutException
78       */
79      @Override
80      public synchronized MBeanServer getMBeanServer() throws PogamutException {
81          try {
82              if (!registryCreated) {
83                  if (log.isLoggable(Level.WARNING)) log.warning("Creating registry at " + getRMIPort() + " ...");
84                  LocateRegistry.createRegistry(getRMIPort());
85                  registryCreated = true;
86              }
87              if (mBeanServer == null) {
88                  if (log.isLoggable(Level.WARNING)) log.warning("Starting MBean server.");
89                  //start a RMI registry                
90                  mBeanServer = new PogamutMBeanServer();
91  
92                  // also create connector for this server, server without connector
93                  // would be unreachable outside this JVM
94                  cs = JMXConnectorServerFactory.newJMXConnectorServer(getMBeanServerURL(), null, mBeanServer);
95                  cs.start();
96  
97              }
98              return mBeanServer;
99          } catch (Exception ex) {
100             throw new PogamutException("Error during JMX initialization.", ex);
101         }
102     }
103 
104     @Override
105     public synchronized void close() throws PogamutException {
106         if (log.isLoggable(Level.WARNING)) log.warning("Closing the platform.");
107         try {
108             if (cs != null) {
109             	cs.stop();
110             }
111             cs = null;
112             if (mBeanServer != null) {
113             	mBeanServer.unregisterAll();
114             	mBeanServer.clearSaved();
115             }
116             mBeanServer = null;
117         } catch (Exception ex) {
118             throw new PogamutException("Could not shutdown the mBeanServer!", ex, log);
119         } finally {
120 		    try {
121 		    	NetworkLogManager.getNetworkLogManager().kill();
122 		    } catch (Exception ex2) {
123 		    	throw new PogamutException("Could not shutdown the log manager!", ex2, log);
124 		    } finally {
125 		    	PogamutJVMComm.platformClose();
126 		    }
127         }
128     }
129     /** Properties loaded from the platform property file. */
130     Properties platformProperties = null;
131 
132     /**
133      * @see DefaultPogamutPlatform.getProperty(String)
134      * @param key
135      * @param def
136      * @return
137      */
138     @Override
139     public String getProperty(String key, String def) {
140         String val = getProperty(key);
141         return val != null ? val : def;
142 
143     }
144 
145     /**
146      * Returns property value. The search order for finding the value is determined dynamicaly by the SPI.
147      * There are allways these sources of properties that are accesed in this order:
148      * <ol>
149      * <li>Get property from -D option supplied when running the JVM</li>
150      * <li>Get the property from system properties (eg. specified by <code>set MY_PROP=hello</code>)</li>
151      * <li>Load property from PogamutPlatformCustom.properties file in processe's working directory</li>
152      * <li>Load property from default platform property file inside Gavialib</li>
153      * </ol>
154      * However other sources may be added through SPI.
155      * @param key
156      * @return null if no such property was found
157      */
158     public String getProperty(String key) {
159         return propertiesManager.getProperty(key);
160     }
161 
162     protected MBeanServerConnection mbsc = null;
163 
164     /**
165      * @return Connection to a remote MBeanServer
166      * @throws cz.cuni.amis.utils.exception.PogamutException
167      */
168     public MBeanServerConnection getMBeanServerConnection() throws PogamutException {
169         // connect through RMI and get the proxy
170         try {
171             if (mbsc == null) {
172                 JMXServiceURL url = getMBeanServerURL();
173                 JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
174                 mbsc = jmxc.getMBeanServerConnection();
175             }
176             return mbsc;
177         } catch (IOException iOException) {
178             throw new PogamutException("IO exception occured while creating remote MBeanServer connector.",
179                     iOException);
180         }
181     }
182 
183     @Override
184     public int getIntProperty(String key) {
185     	String s = getProperty(key);
186     	if(s == null) return 0;
187         return Integer.parseInt(s);
188     }
189 
190 	@Override
191 	public boolean getBooleanProperty(String key) {
192 		String value = getProperty(key);
193 		if (value == null) return false;
194 		return value.equalsIgnoreCase("true");
195 	}
196 }