001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.service;
016    
017    import org.apache.hadoop.util.ReflectionUtils;
018    import org.apache.oozie.action.ActionExecutor;
019    import org.apache.oozie.service.Service;
020    import org.apache.oozie.service.ServiceException;
021    import org.apache.oozie.service.Services;
022    import org.apache.oozie.util.ParamChecker;
023    import org.apache.oozie.util.XLog;
024    import org.apache.oozie.ErrorCode;
025    
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    public class ActionService implements Service {
030    
031        public static final String CONF_ACTION_EXECUTOR_CLASSES = CONF_PREFIX + "ActionService.executor.classes";
032    
033        public static final String CONF_ACTION_EXECUTOR_EXT_CLASSES = CONF_PREFIX + "ActionService.executor.ext.classes";
034    
035        private Services services;
036        private Map<String, Class<? extends ActionExecutor>> executors;
037    
038        @SuppressWarnings("unchecked")
039        public void init(Services services) throws ServiceException {
040            this.services = services;
041            ActionExecutor.enableInit();
042            ActionExecutor.resetInitInfo();
043            ActionExecutor.disableInit();
044            executors = new HashMap<String, Class<? extends ActionExecutor>>();
045            Class<? extends ActionExecutor>[] classes =
046                    (Class<? extends ActionExecutor>[]) services.getConf().getClasses(CONF_ACTION_EXECUTOR_CLASSES);
047            registerExecutors(classes);
048    
049            classes = (Class<? extends ActionExecutor>[]) services.getConf().getClasses(CONF_ACTION_EXECUTOR_EXT_CLASSES);
050            registerExecutors(classes);
051        }
052    
053        private void registerExecutors(Class<? extends ActionExecutor>[] classes) throws ServiceException {
054            if (classes != null) {
055                for (Class<? extends ActionExecutor> executorClass : classes) {
056                    register(executorClass);
057                }
058            }
059        }
060    
061        public void destroy() {
062            ActionExecutor.enableInit();
063            ActionExecutor.resetInitInfo();
064            ActionExecutor.disableInit();
065            executors = null;
066        }
067    
068        public Class<? extends Service> getInterface() {
069            return ActionService.class;
070        }
071    
072        public void register(Class<? extends ActionExecutor> klass) throws ServiceException {
073            XLog log = XLog.getLog(getClass());
074            ActionExecutor executor = (ActionExecutor) ReflectionUtils.newInstance(klass, services.getConf());
075            if (executors.containsKey(executor.getType())) {
076                throw new ServiceException(ErrorCode.E0150, XLog.format(
077                        "Action executor for action type [{1}] already registered", executor.getType()));
078            }
079            ActionExecutor.enableInit();
080            executor.initActionType();
081            ActionExecutor.disableInit();
082            executors.put(executor.getType(), klass);
083            log.trace("Registered Action executor for action type [{0}] class [{1}]", executor.getType(), klass);
084        }
085    
086        public ActionExecutor getExecutor(String actionType) {
087            ParamChecker.notEmpty(actionType, "actionType");
088            Class<? extends ActionExecutor> executorClass = executors.get(actionType);
089            return (executorClass != null) ? (ActionExecutor) ReflectionUtils.newInstance(executorClass, null) : null;
090        }
091    
092    }