![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.oozie.service.Services Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. See accompanying LICENSE file.
*/
package org.apache.oozie.service;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.hadoop.util.VersionInfo;
import org.apache.oozie.client.OozieClient.SYSTEM_MODE;
import org.apache.oozie.util.XLog;
import org.apache.oozie.util.Instrumentable;
import org.apache.oozie.util.IOUtils;
import org.apache.oozie.ErrorCode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.io.File;
/**
* Services is a singleton that manages the lifecycle of all registered {@link Services}. It has 2 built in
* services: {@link XLogService} and {@link ConfigurationService}. The rest of the services are loaded from the
* {@link #CONF_SERVICE_CLASSES} configuration property. The services class names must be separated by commas (spaces
* and enters are allowed). The {@link #CONF_SYSTEM_MODE} configuration property is any of
* NORMAL/SAFEMODE/NOWEBSERVICE. Services are loaded and initialized in the order they are defined in the in
* configuration property. After all services are initialized, if the Instrumentation service is present, all
* services that implement the {@link Instrumentable} are instrumented. Services are destroyed in reverse order.
* If services initialization fail, initialized services are immediatly destroyed.
*/
public class Services {
private static final int MAX_SYSTEM_ID_LEN = 10;
/**
* Environment variable that indicates the location of the Oozie home directory.
* The Oozie home directory is used to pick up the conf/ directory from
*/
public static final String OOZIE_HOME_DIR = "oozie.home.dir";
public static final String CONF_SYSTEM_ID = "oozie.system.id";
public static final String CONF_SERVICE_CLASSES = "oozie.services";
public static final String CONF_SERVICE_EXT_CLASSES = "oozie.services.ext";
public static final String CONF_SYSTEM_MODE = "oozie.systemmode";
public static final String CONF_DELETE_RUNTIME_DIR = "oozie.delete.runtime.dir.on.shutdown";
private static Services SERVICES;
private SYSTEM_MODE systemMode;
private String runtimeDir;
private Configuration conf;
private Map, Service> services = new LinkedHashMap, Service>();
private String systemId;
private static String oozieHome;
public static void setOozieHome() throws ServiceException {
oozieHome = System.getProperty(OOZIE_HOME_DIR);
if (oozieHome == null) {
throw new ServiceException(ErrorCode.E0000);
}
if (!oozieHome.startsWith("/")) {
throw new ServiceException(ErrorCode.E0003, oozieHome);
}
File file = new File(oozieHome);
if (!file.exists()) {
throw new ServiceException(ErrorCode.E0004, oozieHome);
}
}
public static String getOozieHome() throws ServiceException {
return oozieHome;
}
/**
* Create a services. The built in services are initialized.
*
* @throws ServiceException thrown if any of the built in services could not initialize.
*/
public Services() throws ServiceException {
setOozieHome();
if (SERVICES != null) {
XLog log = XLog.getLog(getClass());
log.warn(XLog.OPS, "Previous services singleton active, destroying it");
SERVICES.destroy();
SERVICES = null;
}
setServiceInternal(XLogService.class, false);
setServiceInternal(ConfigurationService.class, true);
conf = get(ConfigurationService.class).getConf();
systemId = conf.get(CONF_SYSTEM_ID, ("oozie-" + System.getProperty("user.name")));
if (systemId.length() > MAX_SYSTEM_ID_LEN) {
systemId = systemId.substring(0, MAX_SYSTEM_ID_LEN);
XLog.getLog(getClass()).warn("System ID [{0}] exceeds maximum length [{1}], trimming", systemId,
MAX_SYSTEM_ID_LEN);
}
setSystemMode(SYSTEM_MODE.valueOf(conf.get(CONF_SYSTEM_MODE, SYSTEM_MODE.NORMAL.toString())));
runtimeDir = createRuntimeDir();
}
private String createRuntimeDir() throws ServiceException {
try {
File file = File.createTempFile(getSystemId(), ".dir");
file.delete();
if (!file.mkdir()) {
ServiceException ex = new ServiceException(ErrorCode.E0001, file.getAbsolutePath());
XLog.getLog(getClass()).fatal(ex);
throw ex;
}
XLog.getLog(getClass()).info("Initialized runtime directory [{0}]", file.getAbsolutePath());
return file.getAbsolutePath();
}
catch (IOException ex) {
ServiceException sex = new ServiceException(ErrorCode.E0001, ex);
XLog.getLog(getClass()).fatal(ex);
throw sex;
}
}
/**
* Return active system mode. .
*
* @return
*/
public SYSTEM_MODE getSystemMode() {
return systemMode;
}
/**
* Return the runtime directory of the Oozie instance. The directory is created under TMP and it is always a
* new directory per Services initialization.
*
* @return the runtime directory of the Oozie instance.
*/
public String getRuntimeDir() {
return runtimeDir;
}
/**
* Return the system ID, the value defined in the {@link #CONF_SYSTEM_ID} configuration property.
*
* @return the system ID, the value defined in the {@link #CONF_SYSTEM_ID} configuration property.
*/
public String getSystemId() {
return systemId;
}
/**
* Set and set system mode.
*
* @param sysMode system mode
*/
public synchronized void setSystemMode(SYSTEM_MODE sysMode) {
if (this.systemMode != sysMode) {
XLog log = XLog.getLog(getClass());
log.info(XLog.OPS, "Exiting " + this.systemMode + " Entering " + sysMode);
}
this.systemMode = sysMode;
}
/**
* Return the services configuration.
*
* @return services configuraiton.
*/
public Configuration getConf() {
return conf;
}
/**
* Initialize all services define in the {@link #CONF_SERVICE_CLASSES} configuration property.
*
* @throws ServiceException thrown if any of the services could not initialize.
*/
@SuppressWarnings("unchecked")
public void init() throws ServiceException {
XLog log = new XLog(LogFactory.getLog(getClass()));
log.trace("Initializing");
SERVICES = this;
try {
Class extends Service>[] serviceClasses = (Class extends Service>[]) conf.getClasses(
CONF_SERVICE_CLASSES);
if (serviceClasses != null) {
for (Class extends Service> serviceClass : serviceClasses) {
setService(serviceClass);
}
}
serviceClasses = (Class extends Service>[]) conf.getClasses(CONF_SERVICE_EXT_CLASSES);
if (serviceClasses != null) {
for (Class extends Service> serviceClass : serviceClasses) {
setService(serviceClass);
}
}
}
catch (RuntimeException ex) {
XLog.getLog(getClass()).fatal(ex.getMessage(), ex);
throw ex;
}
catch (ServiceException ex) {
SERVICES = null;
throw ex;
}
InstrumentationService instrService = get(InstrumentationService.class);
if (instrService != null) {
for (Service service : services.values()) {
if (service instanceof Instrumentable) {
((Instrumentable) service).instrument(instrService.get());
}
}
}
log.info("Initialized");
log.info("Running with JARs for Hadoop version [{0}]", VersionInfo.getVersion());
log.info("Oozie System ID [{0}] started!", getSystemId());
}
/**
* Destroy all services.
*/
public void destroy() {
XLog log = new XLog(LogFactory.getLog(getClass()));
log.trace("Shutting down");
boolean deleteRuntimeDir = false;
if (conf != null) {
deleteRuntimeDir = conf.getBoolean(CONF_DELETE_RUNTIME_DIR, false);
}
if (services != null) {
List list = new ArrayList(services.values());
Collections.reverse(list);
for (Service service : list) {
try {
log.trace("Destroying service[{0}]", service.getInterface());
if (service.getInterface() == XLogService.class) {
log.info("Shutdown");
}
service.destroy();
}
catch (Throwable ex) {
log.error("Error destroying service[{0}], {1}", service.getInterface(), ex.getMessage(), ex);
}
}
}
if (deleteRuntimeDir) {
try {
IOUtils.delete(new File(runtimeDir));
}
catch (IOException ex) {
log.error("Error deleting runtime directory [{0}], {1}", runtimeDir, ex.getMessage(), ex);
}
}
services = null;
conf = null;
SERVICES = null;
}
/**
* Return a service by its public interface.
*
* @param serviceKlass service public interface.
* @return the associated service, or null
if not define.
*/
@SuppressWarnings("unchecked")
public T get(Class serviceKlass) {
return (T) services.get(serviceKlass);
}
/**
* Set a service programmatically. The service will be initialized by the services. If a service is
* already defined with the same public interface it will be destroyed.
*
* @param klass service klass
* @throws ServiceException if the service could not be initialized, at this point all services have been
* destroyed.
*/
public void setService(Class extends Service> klass) throws ServiceException {
setServiceInternal(klass, true);
}
private void setServiceInternal(Class extends Service> klass, boolean logging) throws ServiceException {
try {
Service newService = (Service) ReflectionUtils.newInstance(klass, null);
Service oldService = services.get(newService.getInterface());
if (oldService != null) {
oldService.destroy();
}
if (logging) {
XLog log = new XLog(LogFactory.getLog(getClass()));
log.trace("Initializing service[{0}] class[{1}]", newService.getInterface(), newService.getClass());
}
newService.init(this);
services.put(newService.getInterface(), newService);
}
catch (ServiceException ex) {
XLog.getLog(getClass()).fatal(ex.getMessage(), ex);
destroy();
throw ex;
}
}
/**
* Return the services singleton.
*
* @return services singleton, null
if not initialized.
*/
public static Services get() {
return SERVICES;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy