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