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    package org.apache.oozie.local;
019    
020    import org.apache.oozie.CoordinatorEngine;
021    import org.apache.oozie.DagEngine;
022    import org.apache.oozie.LocalOozieClient;
023    import org.apache.oozie.LocalOozieClientCoord;
024    import org.apache.oozie.client.OozieClient;
025    import org.apache.oozie.service.CallbackService;
026    import org.apache.oozie.service.CoordinatorEngineService;
027    import org.apache.oozie.service.DagEngineService;
028    import org.apache.oozie.service.Services;
029    import org.apache.oozie.service.XLogService;
030    import org.apache.oozie.servlet.CallbackServlet;
031    import org.apache.oozie.test.EmbeddedServletContainer;
032    import org.apache.oozie.util.ParamChecker;
033    import 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     */
039    public 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, "undef");
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                    "undef");
191            return new LocalOozieClientCoord(coordEngine);
192        }
193    
194    }