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.local;
016    
017    import org.apache.oozie.CoordinatorEngine;
018    import org.apache.oozie.DagEngine;
019    import org.apache.oozie.LocalOozieClient;
020    import org.apache.oozie.LocalOozieClientCoord;
021    import org.apache.oozie.client.OozieClient;
022    import org.apache.oozie.service.CallbackService;
023    import org.apache.oozie.service.CoordinatorEngineService;
024    import org.apache.oozie.service.DagEngineService;
025    import org.apache.oozie.service.Services;
026    import org.apache.oozie.service.XLogService;
027    import org.apache.oozie.servlet.CallbackServlet;
028    import org.apache.oozie.test.EmbeddedServletContainer;
029    import org.apache.oozie.util.ParamChecker;
030    import org.apache.oozie.util.XLog;
031    
032    /**
033     * LocalOozie runs workflows in an embedded Oozie instance . <p/> LocalOozie is meant for development/debugging purposes
034     * only.
035     */
036    public class LocalOozie {
037        private static EmbeddedServletContainer container;
038        private static boolean localOozieActive = false;
039    
040        /**
041         * Start LocalOozie.
042         *
043         * @throws Exception if LocalOozie could not be started.
044         */
045        public synchronized static void start() throws Exception {
046            if (localOozieActive) {
047                throw new IllegalStateException("LocalOozie is already initialized");
048            }
049    
050            String log4jFile = System.getProperty(XLogService.LOG4J_FILE_ENV, null);
051            String oozieLocalLog = System.getProperty("oozielocal.log", null);
052            if (log4jFile == null) {
053                System.setProperty(XLogService.LOG4J_FILE_ENV, "localoozie-log4j.properties");
054            }
055            if (oozieLocalLog == null) {
056                System.setProperty("oozielocal.log", "./oozielocal.log");
057            }
058    
059            localOozieActive = true;
060            new Services().init();
061    
062            if (log4jFile != null) {
063                System.setProperty(XLogService.LOG4J_FILE_ENV, log4jFile);
064            }
065            else {
066                System.getProperties().remove(XLogService.LOG4J_FILE_ENV);
067            }
068            if (oozieLocalLog != null) {
069                System.setProperty("oozielocal.log", oozieLocalLog);
070            }
071            else {
072                System.getProperties().remove("oozielocal.log");
073            }
074    
075            container = new EmbeddedServletContainer("oozie");
076            container.addServletEndpoint("/callback", CallbackServlet.class);
077            container.start();
078            String callbackUrl = container.getServletURL("/callback");
079            Services.get().getConf().set(CallbackService.CONF_BASE_URL, callbackUrl);
080            XLog.getLog(LocalOozie.class).info("LocalOozie started callback set to [{0}]", callbackUrl);
081        }
082    
083        /**
084         * Stop LocalOozie.
085         */
086        public synchronized static void stop() {
087            RuntimeException thrown = null;
088            try {
089                if (container != null) {
090                    container.stop();
091                }
092            }
093            catch (RuntimeException ex) {
094                thrown = ex;
095            }
096            container = null;
097            XLog.getLog(LocalOozie.class).info("LocalOozie stopped");
098            try {
099                Services.get().destroy();
100            }
101            catch (RuntimeException ex) {
102                if (thrown != null) {
103                    thrown = ex;
104                }
105            }
106            localOozieActive = false;
107            if (thrown != null) {
108                throw thrown;
109            }
110        }
111    
112        /**
113         * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie. <p/> The returned instance is configured
114         * with the user name of the JVM (the value of the system property 'user.name'). <p/> The following methods of the
115         * client are NOP in the returned instance: {@link org.apache.oozie.client.OozieClient#validateWSVersion}, {@link
116         * org.apache.oozie.client.OozieClient#setHeader}, {@link org.apache.oozie.client.OozieClient#getHeader}, {@link
117         * org.apache.oozie.client.OozieClient#removeHeader}, {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
118         * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
119         *
120         * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
121         */
122        public static OozieClient getClient() {
123            return getClient(System.getProperty("user.name"));
124        }
125    
126        /**
127         * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
128         * <p/>
129         * The returned instance is configured with the user name of the JVM (the
130         * value of the system property 'user.name').
131         * <p/>
132         * The following methods of the client are NOP in the returned instance:
133         * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
134         * {@link org.apache.oozie.client.OozieClient#setHeader},
135         * {@link org.apache.oozie.client.OozieClient#getHeader},
136         * {@link org.apache.oozie.client.OozieClient#removeHeader},
137         * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
138         * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
139         *
140         * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
141         */
142        public static OozieClient getCoordClient() {
143            return getClientCoord(System.getProperty("user.name"));
144        }
145    
146        /**
147         * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for a given user.
148         * <p/>
149         * The following methods of the client are NOP in the returned instance: {@link org.apache.oozie.client.OozieClient#validateWSVersion},
150         * {@link org.apache.oozie.client.OozieClient#setHeader}, {@link org.apache.oozie.client.OozieClient#getHeader}, {@link org.apache.oozie.client.OozieClient#removeHeader},
151         * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and {@link org.apache.oozie.client.OozieClient#setSafeMode}.
152         *
153         * @param user user name to use in LocalOozie for running workflows.
154         * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for the given user.
155         */
156        public static OozieClient getClient(String user) {
157            if (!localOozieActive) {
158                throw new IllegalStateException("LocalOozie is not initialized");
159            }
160            ParamChecker.notEmpty(user, "user");
161            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user, "undef");
162            return new LocalOozieClient(dagEngine);
163        }
164    
165        /**
166         * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
167         * configured for a given user.
168         * <p/>
169         * The following methods of the client are NOP in the returned instance:
170         * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
171         * {@link org.apache.oozie.client.OozieClient#setHeader},
172         * {@link org.apache.oozie.client.OozieClient#getHeader},
173         * {@link org.apache.oozie.client.OozieClient#removeHeader},
174         * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
175         * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
176         *
177         * @param user user name to use in LocalOozie for running coordinator.
178         * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
179         *         configured for the given user.
180         */
181        public static OozieClient getClientCoord(String user) {
182            if (!localOozieActive) {
183                throw new IllegalStateException("LocalOozie is not initialized");
184            }
185            ParamChecker.notEmpty(user, "user");
186            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(user,
187                    "undef");
188            return new LocalOozieClientCoord(coordEngine);
189        }
190    
191    }