00001
00022 package org.objectweb.jonas.management;
00023
00024
00025 import java.util.Hashtable;
00026 import java.util.Properties;
00027
00028 import javax.management.JMException;
00029 import javax.management.MBeanServer;
00030 import javax.management.MBeanServerNotification;
00031 import javax.management.Notification;
00032 import javax.management.NotificationListener;
00033 import javax.management.ObjectName;
00034
00035 import org.objectweb.jonas.common.JProp;
00036 import org.objectweb.jonas.common.Log;
00037 import org.objectweb.jonas.jmx.JonasObjectName;
00038 import org.objectweb.util.monolog.api.BasicLevel;
00039 import org.objectweb.util.monolog.api.Logger;
00053 public class ReconfigManager implements ReconfigManagerMBean, NotificationListener {
00054
00058 private static Logger logger = null;
00059
00063 MBeanServer jmxServer = null;
00064
00065
00066
00067
00068 private static final String SERVICE_TYPE = "service";
00069
00070
00071 private static final String DATASOURCE_TYPE = "datasource";
00072
00073
00074
00075
00079 private static final String MAIL_RESOURCE_TYPE = "JavaMailResource";
00083 private static final String JTA_RESOURCE_TYPE = "JTAResource";
00087 private static final String JDBC_RESOURCE_TYPE = "JDBCDataSource";
00088
00092 private static final String SECURITYREALM_FACTORY = "securityfactory";
00093
00094
00098 private static final String SECURITYREALM_FILE = "jonas-realm.xml";
00099
00100
00101
00102 ObjectName reconfigManagerObectName = JonasObjectName.serverConfig();
00103
00104
00105
00106 Properties serverProperties = null;
00107 String serverConfigFileName = null;
00108
00109
00110
00111 Hashtable reconfigurators = new Hashtable();
00112
00118 public ReconfigManager(Properties serverProperties, MBeanServer jmxServer) throws ReconfigException {
00119
00120 logger = Log.getLogger(Log.JONAS_MANAGEMENT_PREFIX);
00121
00122 this.serverProperties = serverProperties;
00123 this.jmxServer = jmxServer;
00124 try {
00125 this.serverConfigFileName = JProp.getInstance().getPropFile();
00126 } catch (Exception e) {
00127 throw new ReconfigException("Can't initialize ReconfigManager because of exception: " + e.toString());
00128 }
00129
00130
00131
00132
00133 try {
00134 ObjectName delegate = new ObjectName("JMImplementation:type=MBeanServerDelegate");
00135 jmxServer.addNotificationListener(delegate, this, null, null);
00136 } catch (JMException me) {
00137
00138
00139 throw new ReconfigException("ReconfigManager can't listen to MBeanServerNotifications because of exception: " + me.toString());
00140 }
00141 logger.log(BasicLevel.DEBUG, "ReconfigManager MBean registered itself as listner to MBeanServerNotifications");
00142 }
00143
00150 public void handleNotification(Notification notification, java.lang.Object handback) {
00151 String notificationType = notification.getType();
00152 if (notification instanceof MBeanServerNotification) {
00153
00154 if (notificationType.equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
00155 try {
00156 handleRegistrationNotification((MBeanServerNotification) notification);
00157 } catch (ReconfigException re) {
00158 logger.log(BasicLevel.ERROR, "ReconfigManager error when trying to handle REGISTRATION_NOTIFICATION");
00159 }
00160 } else if (notificationType.equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
00161 logger.log(BasicLevel.DEBUG, "Received UNREGISTRATION_NOTIFICATION for MBean " + ((MBeanServerNotification) notification).getMBeanName().toString());
00162
00163 }
00164 } else {
00165
00166
00167 String name = notification.getMessage();
00168
00169 long sequence = notification.getSequenceNumber();
00170 if (notificationType.equals(ReconfigDispatcher.RECONFIG_TYPE)) {
00171
00172 Reconfigured reconfigured = (Reconfigured) notification.getUserData();
00173 if (reconfigured instanceof ReconfiguredProp) {
00174 ReconfiguredProp prop = (ReconfiguredProp) reconfigured;
00175 handleReconfig(name, sequence, prop);
00176 } else {
00177 ReconfiguredXml reconfiguredXml = (ReconfiguredXml) reconfigured;
00178 handleReconfig(name, sequence, reconfiguredXml);
00179 }
00180 } else if (notificationType.equals(ReconfigDispatcher.SAVE_RECONFIG_TYPE)) {
00181 handleSave(name, sequence);
00182 }
00183 }
00184 }
00185
00193 private void handleRegistrationNotification(MBeanServerNotification notification) throws ReconfigException {
00194 ObjectName notificationSender = notification.getMBeanName();
00195 String senderType = notificationSender.getKeyProperty("type");
00196 String senderName = notificationSender.getKeyProperty("name");
00197 String senderJ2eeType = notificationSender.getKeyProperty("j2eeType");
00198 Reconfigurator reconfig = null;
00199 if (senderJ2eeType != null) {
00200 senderType = senderJ2eeType;
00201 }
00202
00203 if (senderType == null) {
00204
00205 return;
00206 }
00207
00208 if (senderType.equals(SERVICE_TYPE)) {
00209
00210
00211
00212
00213 if (!senderName.equals("jonasServer")) {
00214 if (senderName.equals("log")) {
00215
00216 String configFileName = notificationSender.getKeyProperty("fname");
00217 try {
00218 reconfig = new ReconfiguratorProp(senderName, JProp.getInstance(configFileName).getPropFile(), JProp.getInstance(configFileName).getConfigFileEnv());
00219 } catch (Exception e) {
00220
00221
00222
00223 logger.log(BasicLevel.WARN, "Cannot do persistent reconfiguration for dynamically loaded resources!");
00224 }
00225 } else {
00226
00227 reconfig = new ReconfiguratorProp(senderName, serverConfigFileName, serverProperties);
00228 }
00229 }
00230 } else {
00231
00232
00233 String resourceName = null;
00234 try {
00235 if (senderType.equals(MAIL_RESOURCE_TYPE)) {
00236
00237 resourceName = (String) jmxServer.getAttribute(notificationSender, "FactoryName");
00238 } else if (senderType.equals(JDBC_RESOURCE_TYPE)) {
00239
00240 resourceName = (String) jmxServer.getAttribute(notificationSender, "name");
00241 } else if (senderType.equals(JTA_RESOURCE_TYPE)) {
00242
00243 reconfig = new ReconfiguratorProp(senderName, serverConfigFileName, serverProperties);
00244
00245 }
00246
00247
00248 if (senderType.equals(SECURITYREALM_FACTORY)) {
00249 JProp jprop = JProp.getInstance(SECURITYREALM_FILE);
00250 String propsFilename = jprop.getPropFile();
00251 String txt = jprop.getConfigFileXml();
00252
00253 reconfig = new ReconfiguratorXml(SECURITYREALM_FILE, propsFilename, txt);
00254 } else if (resourceName != null) {
00255 JProp jprop = JProp.getInstance(resourceName);
00256 String propsFilename = jprop.getPropFile();
00257 Properties props = JProp.getInstance(resourceName).getConfigFileEnv();
00258
00259 reconfig = new ReconfiguratorProp(resourceName, propsFilename, props);
00260 }
00261 } catch (JMException me) {
00262 logger.log(BasicLevel.ERROR, "Catched Exception when trying to treat reconfiguration of the following resource: " + me);
00263 throw new ReconfigException("Catched Exception when trying to treat reconfiguration of the following resource: " + me.toString());
00264 } catch (Exception e) {
00265
00266
00267 logger.log(BasicLevel.ERROR, "Catched Exception when calling JProp.getInstance(" + resourceName + "): " + e);
00268 throw new ReconfigException("Catched Exception when calling JProp.getInstance(" + resourceName + "): " + e.toString());
00269 }
00270 }
00271 if (reconfig != null) {
00272 try {
00273 jmxServer.addNotificationListener(notificationSender, reconfigManagerObectName, null, null);
00274 } catch (JMException me) {
00275 logger.log(BasicLevel.ERROR, "ReconfigManager can't listen to Notifications because of exception: " + me.toString());
00276 throw new ReconfigException("ReconfigManager can't listen to Notifications because of exception: " + me.toString());
00277 }
00278 reconfigurators.put(senderName, reconfig);
00279 logger.log(BasicLevel.DEBUG, "Received Registration Notification from " + notificationSender.toString());
00280 }
00281 }
00282
00289 private void handleReconfig(String name, long sequence, ReconfiguredProp prop) throws ReconfigException {
00290 logger.log(BasicLevel.DEBUG, "Received 'jonas.management.reconfiguration' notification concerning service or ressource: " + name);
00291 Reconfigurator reconfigurator = (ReconfiguratorProp) reconfigurators.get(name);
00292 if (reconfigurator == null) {
00293 throw new ReconfigException("Can't find Reconfigurator associated to service or resource " + name);
00294 } else {
00295 if (prop.getPropValue() != null) {
00296 logger.log(BasicLevel.DEBUG, "Try to reconfigure property : " + prop.getPropName() + " using value value : " + prop.getPropValue());
00297 if (prop.replaceProp()) {
00298 ((ReconfiguratorProp) reconfigurator).updateConfig(prop.getPropName(), prop.getPropValue(), sequence);
00299 } else {
00300 if (prop.addProp()) {
00301 logger.log(BasicLevel.DEBUG, "This value has to be added to the values sequence");
00302 } else {
00303 logger.log(BasicLevel.DEBUG, "This value has to be removed from the values sequence");
00304 }
00305 ((ReconfiguratorProp) reconfigurator).updateConfig(prop.getPropName(), prop.getPropValue(), prop.addProp(), sequence);
00306 }
00307 } else {
00308 logger.log(BasicLevel.DEBUG, "Reconfiguration made on a group of properties");
00309 ((ReconfiguratorProp) reconfigurator).updateConfig(prop.getProps(), sequence);
00310 }
00311 }
00312 }
00313
00320 private void handleReconfig(String name, long sequence, ReconfiguredXml reconfiguredXml) throws ReconfigException {
00321 logger.log(BasicLevel.DEBUG, "Received 'jonas.management.reconfiguration' notification concerning service or ressource: " + name);
00322 Reconfigurator reconfigurator = (ReconfiguratorXml) reconfigurators.get(name);
00323 if (reconfigurator == null) {
00324 throw new ReconfigException("Can't find Reconfigurator associated to service or resource " + name);
00325 } else {
00326 ((ReconfiguratorXml) reconfigurator).updateConfig(reconfiguredXml.getXml(), sequence);
00327 }
00328 }
00329
00330
00336 private void handleSave(String name, long sequence) throws ReconfigException {
00337 logger.log(BasicLevel.DEBUG, "Received 'jonas.management.reconfiguration.save' notification concerning service or ressource: " + name);
00338 Reconfigurator reconfigurator = (Reconfigurator) reconfigurators.get(name);
00339 if (reconfigurator == null) {
00340 throw new ReconfigException("Can't find Reconfigurator associated to service or resource " + name);
00341 } else {
00342 reconfigurator.saveConfig(sequence);
00343 }
00344 }
00345 }