001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 * 
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.oozie.local;
019
020import org.apache.oozie.CoordinatorEngine;
021import org.apache.oozie.DagEngine;
022import org.apache.oozie.LocalOozieClient;
023import org.apache.oozie.LocalOozieClientCoord;
024import org.apache.oozie.client.OozieClient;
025import org.apache.oozie.service.CallbackService;
026import org.apache.oozie.service.CoordinatorEngineService;
027import org.apache.oozie.service.DagEngineService;
028import org.apache.oozie.service.Services;
029import org.apache.oozie.service.XLogService;
030import org.apache.oozie.servlet.CallbackServlet;
031import org.apache.oozie.test.EmbeddedServletContainer;
032import org.apache.oozie.util.ParamChecker;
033import org.apache.oozie.util.XLog;
034
035/**
036 * LocalOozie runs workflows in an embedded Oozie instance . <p/> LocalOozie is meant for development/debugging purposes
037 * only.
038 */
039public class LocalOozie {
040    private static EmbeddedServletContainer container;
041    private static boolean localOozieActive = false;
042
043    /**
044     * Start LocalOozie.
045     *
046     * @throws Exception if LocalOozie could not be started.
047     */
048    public synchronized static void start() throws Exception {
049        if (localOozieActive) {
050            throw new IllegalStateException("LocalOozie is already initialized");
051        }
052
053        String log4jFile = System.getProperty(XLogService.LOG4J_FILE, null);
054        String oozieLocalLog = System.getProperty("oozielocal.log", null);
055        if (log4jFile == null) {
056            System.setProperty(XLogService.LOG4J_FILE, "localoozie-log4j.properties");
057        }
058        if (oozieLocalLog == null) {
059            System.setProperty("oozielocal.log", "./oozielocal.log");
060        }
061
062        localOozieActive = true;
063        new Services().init();
064
065        if (log4jFile != null) {
066            System.setProperty(XLogService.LOG4J_FILE, log4jFile);
067        }
068        else {
069            System.getProperties().remove(XLogService.LOG4J_FILE);
070        }
071        if (oozieLocalLog != null) {
072            System.setProperty("oozielocal.log", oozieLocalLog);
073        }
074        else {
075            System.getProperties().remove("oozielocal.log");
076        }
077
078        container = new EmbeddedServletContainer("oozie");
079        container.addServletEndpoint("/callback", CallbackServlet.class);
080        container.start();
081        String callbackUrl = container.getServletURL("/callback");
082        Services.get().getConf().set(CallbackService.CONF_BASE_URL, callbackUrl);
083        XLog.getLog(LocalOozie.class).info("LocalOozie started callback set to [{0}]", callbackUrl);
084    }
085
086    /**
087     * Stop LocalOozie.
088     */
089    public synchronized static void stop() {
090        RuntimeException thrown = null;
091        try {
092            if (container != null) {
093                container.stop();
094            }
095        }
096        catch (RuntimeException ex) {
097            thrown = ex;
098        }
099        container = null;
100        XLog.getLog(LocalOozie.class).info("LocalOozie stopped");
101        try {
102            Services.get().destroy();
103        }
104        catch (RuntimeException ex) {
105            if (thrown != null) {
106                thrown = ex;
107            }
108        }
109        localOozieActive = false;
110        if (thrown != null) {
111            throw thrown;
112        }
113    }
114
115    /**
116     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie. <p/> The returned instance is configured
117     * with the user name of the JVM (the value of the system property 'user.name'). <p/> The following methods of the
118     * client are NOP in the returned instance: {@link org.apache.oozie.client.OozieClient#validateWSVersion}, {@link
119     * org.apache.oozie.client.OozieClient#setHeader}, {@link org.apache.oozie.client.OozieClient#getHeader}, {@link
120     * org.apache.oozie.client.OozieClient#removeHeader}, {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
121     * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
122     *
123     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
124     */
125    public static OozieClient getClient() {
126        return getClient(System.getProperty("user.name"));
127    }
128
129    /**
130     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
131     * <p/>
132     * The returned instance is configured with the user name of the JVM (the
133     * value of the system property 'user.name').
134     * <p/>
135     * The following methods of the client are NOP in the returned instance:
136     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
137     * {@link org.apache.oozie.client.OozieClient#setHeader},
138     * {@link org.apache.oozie.client.OozieClient#getHeader},
139     * {@link org.apache.oozie.client.OozieClient#removeHeader},
140     * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
141     * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
142     *
143     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
144     */
145    public static OozieClient getCoordClient() {
146        return getClientCoord(System.getProperty("user.name"));
147    }
148
149    /**
150     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for a given user.
151     * <p/>
152     * The following methods of the client are NOP in the returned instance: {@link org.apache.oozie.client.OozieClient#validateWSVersion},
153     * {@link org.apache.oozie.client.OozieClient#setHeader}, {@link org.apache.oozie.client.OozieClient#getHeader}, {@link org.apache.oozie.client.OozieClient#removeHeader},
154     * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and {@link org.apache.oozie.client.OozieClient#setSafeMode}.
155     *
156     * @param user user name to use in LocalOozie for running workflows.
157     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for the given user.
158     */
159    public static OozieClient getClient(String user) {
160        if (!localOozieActive) {
161            throw new IllegalStateException("LocalOozie is not initialized");
162        }
163        ParamChecker.notEmpty(user, "user");
164        DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user);
165        return new LocalOozieClient(dagEngine);
166    }
167
168    /**
169     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
170     * configured for a given user.
171     * <p/>
172     * The following methods of the client are NOP in the returned instance:
173     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
174     * {@link org.apache.oozie.client.OozieClient#setHeader},
175     * {@link org.apache.oozie.client.OozieClient#getHeader},
176     * {@link org.apache.oozie.client.OozieClient#removeHeader},
177     * {@link org.apache.oozie.client.OozieClient#getHeaderNames} and
178     * {@link org.apache.oozie.client.OozieClient#setSafeMode}.
179     *
180     * @param user user name to use in LocalOozie for running coordinator.
181     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
182     *         configured for the given user.
183     */
184    public static OozieClient getClientCoord(String user) {
185        if (!localOozieActive) {
186            throw new IllegalStateException("LocalOozie is not initialized");
187        }
188        ParamChecker.notEmpty(user, "user");
189        CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(user);
190        return new LocalOozieClientCoord(coordEngine);
191    }
192
193}