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 */
018
019package org.apache.oozie.local;
020
021import org.apache.oozie.BundleEngine;
022import org.apache.oozie.CoordinatorEngine;
023import org.apache.oozie.DagEngine;
024import org.apache.oozie.LocalOozieClient;
025import org.apache.oozie.LocalOozieClientBundle;
026import org.apache.oozie.LocalOozieClientCoord;
027import org.apache.oozie.client.OozieClient;
028import org.apache.oozie.service.BundleEngineService;
029import org.apache.oozie.service.CallbackService;
030import org.apache.oozie.service.CoordinatorEngineService;
031import org.apache.oozie.service.DagEngineService;
032import org.apache.oozie.service.Services;
033import org.apache.oozie.service.XLogService;
034import org.apache.oozie.servlet.CallbackServlet;
035import org.apache.oozie.test.EmbeddedServletContainer;
036import org.apache.oozie.util.ParamChecker;
037import org.apache.oozie.util.XLog;
038
039/**
040 * LocalOozie runs workflows in an embedded Oozie instance . <p> LocalOozie is meant for development/debugging purposes
041 * only.
042 */
043public class LocalOozie {
044    private static EmbeddedServletContainer container;
045    private static boolean localOozieActive = false;
046
047    /**
048     * Start LocalOozie.
049     *
050     * @throws Exception if LocalOozie could not be started.
051     */
052    public synchronized static void start() throws Exception {
053        if (localOozieActive) {
054            throw new IllegalStateException("LocalOozie is already initialized");
055        }
056
057        String log4jFile = System.getProperty(XLogService.LOG4J_FILE, null);
058        String oozieLocalLog = System.getProperty("oozielocal.log", null);
059        if (log4jFile == null) {
060            System.setProperty(XLogService.LOG4J_FILE, "localoozie-log4j.properties");
061        }
062        if (oozieLocalLog == null) {
063            System.setProperty("oozielocal.log", "./oozielocal.log");
064        }
065
066        localOozieActive = true;
067        new Services().init();
068
069        if (log4jFile != null) {
070            System.setProperty(XLogService.LOG4J_FILE, log4jFile);
071        }
072        else {
073            System.getProperties().remove(XLogService.LOG4J_FILE);
074        }
075        if (oozieLocalLog != null) {
076            System.setProperty("oozielocal.log", oozieLocalLog);
077        }
078        else {
079            System.getProperties().remove("oozielocal.log");
080        }
081
082        container = new EmbeddedServletContainer("oozie");
083        container.addServletEndpoint("/callback", CallbackServlet.class);
084        container.start();
085        String callbackUrl = container.getServletURL("/callback");
086        Services.get().getConf().set(CallbackService.CONF_BASE_URL, callbackUrl);
087        XLog.getLog(LocalOozie.class).info("LocalOozie started callback set to [{0}]", callbackUrl);
088    }
089
090    /**
091     * Stop LocalOozie.
092     */
093    public synchronized static void stop() {
094        RuntimeException thrown = null;
095        try {
096            if (container != null) {
097                container.stop();
098            }
099        }
100        catch (RuntimeException ex) {
101            thrown = ex;
102        }
103        container = null;
104        XLog.getLog(LocalOozie.class).info("LocalOozie stopped");
105        try {
106            Services.get().destroy();
107        }
108        catch (RuntimeException ex) {
109            if (thrown != null) {
110                thrown = ex;
111            }
112        }
113        localOozieActive = false;
114        if (thrown != null) {
115            throw thrown;
116        }
117    }
118
119    /**
120     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
121     * <p>
122     *     The returned instance is configured
123     *     with the user name of the JVM (the value of the system property 'user.name').
124     * <p>
125     * The following methods of the client are NOP in the returned instance:
126     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
127     * {@link org.apache.oozie.client.OozieClient#setHeader},
128     * {@link org.apache.oozie.client.OozieClient#getHeader},
129     * {@link org.apache.oozie.client.OozieClient#removeHeader},
130     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
131     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
132     * {@link org.apache.oozie.client.OozieClient#getHeaders},
133     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
134     *
135     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
136     */
137    public static OozieClient getClient() {
138        return getClient(System.getProperty("user.name"));
139    }
140
141    /**
142     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
143     * <p>
144     * The returned instance is configured with the user name of the JVM (the
145     * value of the system property 'user.name').
146     * <p>
147     * The following methods of the client are NOP in the returned instance:
148     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
149     * {@link org.apache.oozie.client.OozieClient#setHeader},
150     * {@link org.apache.oozie.client.OozieClient#getHeader},
151     * {@link org.apache.oozie.client.OozieClient#removeHeader},
152     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
153     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
154     * {@link org.apache.oozie.client.OozieClient#getHeaders},
155     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
156     *
157     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
158     */
159    public static OozieClient getCoordClient() {
160        return getClientCoord(System.getProperty("user.name"));
161    }
162
163    /**
164     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for a given user.
165     * <p>
166     * The following methods of the client are NOP in the returned instance:
167     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
168     * {@link org.apache.oozie.client.OozieClient#setHeader},
169     * {@link org.apache.oozie.client.OozieClient#getHeader},
170     * {@link org.apache.oozie.client.OozieClient#removeHeader},
171     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
172     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
173     * {@link org.apache.oozie.client.OozieClient#getHeaders},
174     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
175     *
176     * @param user user name to use in LocalOozie for running workflows.
177     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie configured for the given user.
178     */
179    public static OozieClient getClient(String user) {
180        if (!localOozieActive) {
181            throw new IllegalStateException("LocalOozie is not initialized");
182        }
183        ParamChecker.notEmpty(user, "user");
184        DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user);
185        return new LocalOozieClient(dagEngine);
186    }
187
188    /**
189     * Return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
190     * configured for a given user.
191     * <p>
192     * The following methods of the client are NOP in the returned instance:
193     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
194     * {@link org.apache.oozie.client.OozieClient#setHeader},
195     * {@link org.apache.oozie.client.OozieClient#getHeader},
196     * {@link org.apache.oozie.client.OozieClient#removeHeader},
197     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
198     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
199     * {@link org.apache.oozie.client.OozieClient#getHeaders},
200     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
201     *
202     * @param user user name to use in LocalOozie for running coordinator.
203     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie
204     *         configured for the given user.
205     */
206    public static OozieClient getClientCoord(String user) {
207        if (!localOozieActive) {
208            throw new IllegalStateException("LocalOozie is not initialized");
209        }
210        ParamChecker.notEmpty(user, "user");
211        CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(user);
212        return new LocalOozieClientCoord(coordEngine);
213    }
214
215    /**
216     * <p>
217     * The returned instance is configured with the user name of the JVM (the
218     * value of the system property 'user.name').
219     * <p>
220     * The following methods of the client are NOP in the returned instance:
221     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
222     * {@link org.apache.oozie.client.OozieClient#setHeader},
223     * {@link org.apache.oozie.client.OozieClient#getHeader},
224     * {@link org.apache.oozie.client.OozieClient#removeHeader},
225     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
226     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
227     * {@link org.apache.oozie.client.OozieClient#getHeaders},
228     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
229     *
230     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
231     */
232    public static OozieClient getClientBundle() {
233        return getClientBundle(System.getProperty("user.name"));
234    }
235
236    /**
237     * <p>
238     * The returned instance is configured with the user name of the JVM (the
239     * value of the system property 'user.name').
240     * <p>
241     * The following methods of the client are NOP in the returned instance:
242     * {@link org.apache.oozie.client.OozieClient#validateWSVersion},
243     * {@link org.apache.oozie.client.OozieClient#setHeader},
244     * {@link org.apache.oozie.client.OozieClient#getHeader},
245     * {@link org.apache.oozie.client.OozieClient#removeHeader},
246     * {@link org.apache.oozie.client.OozieClient#getHeaderNames},
247     * {@link org.apache.oozie.client.OozieClient#setSystemMode(OozieClient.SYSTEM_MODE)},
248     * {@link org.apache.oozie.client.OozieClient#getHeaders},
249     * {@link org.apache.oozie.client.OozieClient#getClientBuildVersion}.
250     *
251     * @return a {@link org.apache.oozie.client.OozieClient} for LocalOozie.
252     */
253    public static OozieClient getClientBundle(String user) {
254        if (!localOozieActive) {
255            throw new IllegalStateException("LocalOozie is not initialized");
256        }
257        ParamChecker.notEmpty(user, "user");
258        BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(user);
259        return new LocalOozieClientBundle(bundleEngine);
260    }
261}