00001
00027 package org.objectweb.jonas.service;
00028
00029 import java.util.ArrayList;
00030 import java.util.Enumeration;
00031 import java.util.Hashtable;
00032 import java.util.List;
00033 import java.util.Map;
00034
00035 import javax.naming.Context;
00036 import javax.naming.NamingException;
00037
00038 import org.objectweb.jonas.common.JProp;
00039 import org.objectweb.jonas.common.Log;
00040 import org.objectweb.jonas.naming.CompNamingContext;
00041
00042 import org.objectweb.util.monolog.api.BasicLevel;
00043 import org.objectweb.util.monolog.api.Logger;
00044
00065 public class ServiceManager {
00066
00070 static final String SERVICES_PROP_NAME = JProp.JONASPREFIX + ".services";
00071
00075 static final String PREFIX_SERVICE_PROP_NAME = JProp.JONASPREFIX + ".service";
00076
00080 private static Logger logger = null;
00081
00085 private static ServiceManager unique = null;
00086
00090 private JProp props = null;
00091
00095 private static List services = null;
00096
00100 private Map servicesByName = null;
00101
00105 private Map contextsByService = null;
00106
00111 private ServiceManager() throws Exception {
00112 logger = Log.getLogger(Log.JONAS_SERVER_PREFIX);
00113
00114 props = JProp.getInstance();
00115
00116 readServices();
00117 }
00118
00125 public static ServiceManager getInstance() throws Exception {
00126 if (unique == null) {
00127 unique = new ServiceManager();
00128 }
00129 return unique;
00130 }
00131
00138 public Service getService(String name) throws ServiceException {
00139 if (servicesByName == null) {
00140 throw new ServiceException("No service has been initialized yet");
00141 }
00142 Service s = (Service) servicesByName.get(name);
00143 if (s == null) {
00144 throw new ServiceException("Unknown service '" + name + "'");
00145 }
00146 return s;
00147 }
00148
00154 public Service getEjbService() throws ServiceException {
00155 return getService("ejb");
00156 }
00157
00163 public Service getEarService() throws ServiceException {
00164 return getService("ear");
00165 }
00166
00172 public Service getRarService() throws ServiceException {
00173 return getService("resource");
00174 }
00175
00181 public Service getWebContainerService() throws ServiceException {
00182 return getService("web");
00183 }
00184
00190 public Service getWebServicesService() throws ServiceException {
00191 return getService("ws");
00192 }
00193
00199 public Service getMailService() throws ServiceException {
00200 return getService("mail");
00201 }
00202
00208 public Service getDataBaseService() throws ServiceException {
00209 return getService("dbm");
00210 }
00211
00217 public Service getTransactionService() throws ServiceException {
00218 return getService("jtm");
00219 }
00220
00226 public Service getJmsService() throws ServiceException {
00227 return getService("jms");
00228 }
00229
00235 public Service getSecurityService() throws ServiceException {
00236 return getService("security");
00237 }
00238
00244 public Service getJmxService() throws ServiceException {
00245 return getService("jmx");
00246 }
00247
00253 public Service getRegistryService() throws ServiceException {
00254 return getService("registry");
00255 }
00256
00262 public Service getResourceService() throws ServiceException {
00263 return getService("resource");
00264 }
00265
00270 public void startRegistry() throws ServiceException {
00271 logger.log(BasicLevel.DEBUG, "");
00272 Service reg = getRegistryService();
00273 try {
00274 reg.init((Context) contextsByService.get(reg));
00275 reg.start();
00276 logger.log(BasicLevel.INFO, "registry service started");
00277 } catch (ServiceException e) {
00278 throw new ServiceException("Cannot init/start registry" + e);
00279 }
00280 }
00281
00286 public void startJmx() throws ServiceException {
00287 logger.log(BasicLevel.DEBUG, "");
00288 Service jmxService = getJmxService();
00289 try {
00290 jmxService.init((Context) contextsByService.get(jmxService));
00291 jmxService.start();
00292 logger.log(BasicLevel.INFO, "jmx service started");
00293 } catch (ServiceException e) {
00294 throw e;
00295 }
00296 }
00297
00302 public void startServices() throws ServiceException {
00303 logger.log(BasicLevel.DEBUG, "");
00304 Service[] services = getServices();
00305 Context serviceContext = null;
00306
00307
00308 for (int i = 2; i < services.length; i++) {
00309 Service service = services[i];
00310 try {
00311 serviceContext = (Context) contextsByService.get(service);
00312 service.init(serviceContext);
00313 service.start();
00314 logger.log(BasicLevel.INFO, service.getName() + " service started");
00315 } catch (ServiceException e) {
00316 throw new ServiceException("Cannot init/start service '" + service.getName() + "': " + e.getMessage(), e);
00317 }
00318 }
00319 }
00320
00326 public Service[] getServices() throws ServiceException {
00327 Service[] ss = new Service[services.size()];
00328 for (int i = 0; i < services.size(); i++) {
00329 ss[i] = (Service) services.get(i);
00330 }
00331 return ss;
00332 }
00333
00338 public String[] getServiceNames() {
00339 logger.log(BasicLevel.DEBUG, "");
00340 String [] serviceNames;
00341 serviceNames = props.getValueAsArray(SERVICES_PROP_NAME);
00342 if (serviceNames == null) {
00343 return null;
00344 }
00345 if (serviceNames[0].equals("registry") && serviceNames[1].equals("jmx")) {
00346 return serviceNames;
00347 }
00348 ArrayList services = new ArrayList();
00349 services.add(0, "registry");
00350 services.add(1, "jmx");
00351 int nbServices = 2;
00352 for (int i = 0; i < serviceNames.length; i++) {
00353 if (!serviceNames[i].equals("registry") && !serviceNames[i].equals("jmx")) {
00354 services.add(serviceNames[i]);
00355 nbServices++;
00356 }
00357 }
00358 serviceNames = new String[nbServices];
00359 logger.log(BasicLevel.DEBUG, "Created new array of String of size " + services.size());
00360 for (int i = 0; i < nbServices; i++) {
00361 serviceNames[i] = (String) services.get(i);
00362 }
00363 return serviceNames;
00364 }
00365
00371 protected void readServices() throws ServiceException {
00372 logger.log(BasicLevel.DEBUG, "");
00373 services = new ArrayList();
00374 contextsByService = new Hashtable();
00375 servicesByName = new Hashtable();
00376 String [] serviceNames;
00377 serviceNames = getServiceNames();
00378 if (serviceNames == null) {
00379 throw new ServiceException("Property '" + SERVICES_PROP_NAME + "' is missing in '"
00380 + JProp.JONASPREFIX + "' properties file");
00381 }
00382 for (int i = 0; i < serviceNames.length; i++) {
00383 String serviceName = serviceNames[i];
00384 Service serviceObj = createServiceFrom(serviceName);
00385 if (serviceObj != null) {
00386 try {
00387 Context ctx = createServiceContextFor(serviceName);
00388 services.add(serviceObj);
00389 contextsByService.put(serviceObj, ctx);
00390 servicesByName.put(serviceName, serviceObj);
00391 } catch (NamingException e) {
00392 throw new ServiceException("cannot create the context name of the service '"
00393 + serviceName + "'",
00394 e);
00395 }
00396 }
00397 }
00398 }
00399
00407 protected Service createServiceFrom(String serviceName) throws ServiceException {
00408 logger.log(BasicLevel.DEBUG, serviceName);
00409 String prefixPropName = PREFIX_SERVICE_PROP_NAME + "." + serviceName;
00410 String serviceClassName = props.getValue(prefixPropName + ".class");
00411 if (serviceClassName == null) {
00412 throw new ServiceException("Property '" + prefixPropName + ".class' missing in '"
00413 + JProp.JONASPREFIX + "' properties file");
00414 }
00415 try {
00416 ClassLoader classLoader = this.getClass().getClassLoader();
00417 if (classLoader == null) {
00418 classLoader = Thread.currentThread().getContextClassLoader();
00419 }
00420 Class serviceClass = classLoader.loadClass(serviceClassName);
00421 Service service = (Service) serviceClass.newInstance();
00422 service.setName(serviceName);
00423 logger.log(BasicLevel.DEBUG, "class used: " + serviceClassName);
00424 return (service);
00425 } catch (NoClassDefFoundError ncdfe) {
00426 logger.log(BasicLevel.WARN, "WARNING : The service '" + serviceName
00427 + "' is disabled because a class for this service is missing."
00428 + " Check your services in jonas.properties file and your environment variables. Missing class : '"
00429 + ncdfe.getMessage() + "'", ncdfe);
00430
00431 return null;
00432 } catch (ClassNotFoundException cnfe) {
00433 logger.log(BasicLevel.WARN, "WARNING : The service '" + serviceName
00434 + "' is disabled because a class for this service is missing."
00435 + " Check your services in jonas.properties file and your environment variables. Missing class : '"
00436 + cnfe.getMessage() + "'", cnfe);
00437
00438 return null;
00439 } catch (Exception e) {
00440 throw new ServiceException("Error when creating the service '" + serviceName + "'", e);
00441 }
00442 }
00443
00452 protected Context createServiceContextFor(String serviceName) throws NamingException {
00453 logger.log(BasicLevel.DEBUG, serviceName);
00454 String prefixPropName = PREFIX_SERVICE_PROP_NAME + "." + serviceName;
00455 CompNamingContext ctx = new CompNamingContext(serviceName);
00456 for (Enumeration e = props.getEnv().propertyNames(); e.hasMoreElements();) {
00457 String propName = (String) e.nextElement();
00458 if (propName.startsWith(prefixPropName + ".")) {
00459 ctx.rebind(propName, props.getValue(propName));
00460 }
00461 }
00462
00463 ctx.rebind(JProp.JONAS_NAME, props.getValue(JProp.JONAS_NAME));
00464 ctx.rebind(JProp.DOMAIN_NAME, props.getValue(JProp.DOMAIN_NAME));
00465
00466
00467 if (serviceName.equals("jmx")) {
00468 String prop = props.getValue("host.name");
00469 if (prop != null) {
00470 ctx.rebind("host.name", prop);
00471 }
00472 prop = props.getValue("jmxconnector.port");
00473 if (prop != null) {
00474 ctx.rebind("jmxconnector.port", prop);
00475 }
00476 }
00477 return ctx;
00478 }
00479
00487 public void stopServices() throws ServiceException {
00488 String msgError = new String();
00489 String sepError = "";
00490 Service[] services = getServices();
00491 for (int i = services.length - 1; i >= 0; i--) {
00492 Service service = services[i];
00493 if (service.isStarted()) {
00494 try {
00495 service.stop();
00496 logger.log(BasicLevel.DEBUG, service.getName() + " service stopped");
00497 } catch (ServiceException e) {
00498 msgError = msgError.concat(sepError + "Cannot stop the service '"
00499 + service.getName() + "': " + e);
00500 sepError = "\n";
00501 }
00502 }
00503 }
00504 if (msgError.length() != 0) {
00505 throw new ServiceException(msgError);
00506 }
00507 }
00508 }