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.servlet;
016    
017    import java.io.IOException;
018    import java.util.List;
019    
020    import javax.servlet.ServletInputStream;
021    import javax.servlet.http.HttpServletRequest;
022    import javax.servlet.http.HttpServletResponse;
023    
024    import org.apache.hadoop.conf.Configuration;
025    import org.apache.oozie.BaseEngineException;
026    import org.apache.oozie.CoordinatorActionBean;
027    import org.apache.oozie.CoordinatorActionInfo;
028    import org.apache.oozie.CoordinatorEngine;
029    import org.apache.oozie.CoordinatorEngineException;
030    import org.apache.oozie.DagEngine;
031    import org.apache.oozie.DagEngineException;
032    import org.apache.oozie.ErrorCode;
033    import org.apache.oozie.client.rest.JsonBean;
034    import org.apache.oozie.client.rest.JsonCoordinatorJob;
035    import org.apache.oozie.client.rest.JsonTags;
036    import org.apache.oozie.client.rest.RestConstants;
037    import org.apache.oozie.service.CoordinatorEngineService;
038    import org.apache.oozie.service.DagEngineService;
039    import org.apache.oozie.service.Services;
040    import org.apache.oozie.util.XLog;
041    import org.json.simple.JSONObject;
042    
043    @SuppressWarnings("serial")
044    public class V1JobServlet extends BaseJobServlet {
045    
046        private static final String INSTRUMENTATION_NAME = "v1job";
047    
048        public V1JobServlet() {
049            super(INSTRUMENTATION_NAME);
050        }
051    
052        /*
053         * protected method to start a job
054         */
055        @Override
056        protected void startJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
057                IOException {
058            /*
059             * Configuration conf = new XConfiguration(request.getInputStream());
060             * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath =
061             * conf.get(OozieClient.COORDINATOR_APP_PATH);
062             *
063             * ServletUtilities.ValidateAppPath(wfPath, coordPath);
064             */
065            String jobId = getResourceName(request);
066            if (jobId.endsWith("-W")) {
067                startWorkflowJob(request, response);
068            }
069            else {
070                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303);
071            }
072    
073        }
074    
075        /*
076         * protected method to resume a job
077         */
078        @Override
079        protected void resumeJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
080                IOException {
081            /*
082             * Configuration conf = new XConfiguration(request.getInputStream());
083             * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath =
084             * conf.get(OozieClient.COORDINATOR_APP_PATH);
085             *
086             * ServletUtilities.ValidateAppPath(wfPath, coordPath);
087             */
088            String jobId = getResourceName(request);
089            if (jobId.endsWith("-W")) {
090                resumeWorkflowJob(request, response);
091            }
092            else {
093                resumeCoordinatorJob(request, response);
094            }
095        }
096    
097        /*
098         * protected method to suspend a job
099         */
100        @Override
101        protected void suspendJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
102                IOException {
103            /*
104             * Configuration conf = new XConfiguration(request.getInputStream());
105             * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath =
106             * conf.get(OozieClient.COORDINATOR_APP_PATH);
107             *
108             * ServletUtilities.ValidateAppPath(wfPath, coordPath);
109             */
110            String jobId = getResourceName(request);
111            if (jobId.endsWith("-W")) {
112                suspendWorkflowJob(request, response);
113            }
114            else {
115                suspendCoordinatorJob(request, response);
116            }
117        }
118    
119        /*
120         * protected method to kill a job
121         */
122        @Override
123        protected void killJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
124                IOException {
125            /*
126             * Configuration conf = new XConfiguration(request.getInputStream());
127             * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath =
128             * conf.get(OozieClient.COORDINATOR_APP_PATH);
129             *
130             * ServletUtilities.ValidateAppPath(wfPath, coordPath);
131             */
132            String jobId = getResourceName(request);
133            if (jobId.endsWith("-W")) {
134                killWorkflowJob(request, response);
135            }
136            else {
137                killCoordinatorJob(request, response);
138            }
139        }
140    
141        /**
142         * protected method to change a coordinator job
143         * @param request request object
144         * @param response response object
145         * @throws XServletException
146         * @throws IOException
147         */
148        protected void changeJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
149                IOException {
150            changeCoordinatorJob(request, response);
151        }
152    
153        /*
154         * protected method to reRun a job
155         *
156         * @seeorg.apache.oozie.servlet.BaseJobServlet#reRunJob(javax.servlet.http.
157         * HttpServletRequest, javax.servlet.http.HttpServletResponse,
158         * org.apache.hadoop.conf.Configuration)
159         */
160        @Override
161        protected JSONObject reRunJob(HttpServletRequest request, HttpServletResponse response, Configuration conf)
162                throws XServletException, IOException {
163            JSONObject json = null;
164            String jobId = getResourceName(request);
165            if (jobId.endsWith("-W")) {
166                reRunWorkflowJob(request, response, conf);
167            }
168            else {
169                json = reRunCoordinatorActions(request, response, conf);
170            }
171            return json;
172        }
173    
174        /*
175         * protected method to get a job in JsonBean representation
176         */
177        @Override
178        protected JsonBean getJob(HttpServletRequest request, HttpServletResponse response) throws XServletException,
179                IOException, BaseEngineException {
180            ServletInputStream is = request.getInputStream();
181            byte[] b = new byte[101];
182            while (is.readLine(b, 0, 100) != -1) {
183                XLog.getLog(getClass()).warn("Printing :" + new String(b));
184            }
185            /*
186             * Configuration conf = new XConfiguration(request.getInputStream());
187             * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath =
188             * conf.get(OozieClient.COORDINATOR_APP_PATH);
189             *
190             * ServletUtilities.ValidateAppPath(wfPath, coordPath);
191             */
192            JsonBean jobBean = null;
193            String jobId = getResourceName(request);
194            if (jobId.endsWith("-W")) {
195                jobBean = getWorkflowJob(request, response);
196            }
197            else {
198                if (jobId.contains("-W@")) {
199                    jobBean = getWorkflowAction(request, response);
200                }
201                else {
202                    if (jobId.contains("-C@")) {
203                        jobBean = getCoordinatorAction(request, response);
204                    }
205                    else {
206                        // jobBean = new JsonCoordinatorJob(getCoordinatorJob(request, response));
207                        jobBean = getCoordinatorJob(request, response);
208                    }
209                }
210            }
211    
212            return jobBean;
213        }
214    
215        /*
216         * protected method to get a job definition in String format
217         */
218        @Override
219        protected String getJobDefinition(HttpServletRequest request, HttpServletResponse response)
220                throws XServletException, IOException {
221            String jobDefinition = null;
222            String jobId = getResourceName(request);
223            if (jobId.endsWith("-W")) {
224                jobDefinition = getWorkflowJobDefinition(request, response);
225            }
226            else {
227                jobDefinition = getCoordinatorJobDefinition(request, response);
228            }
229            return jobDefinition;
230        }
231    
232        /*
233         * protected method to stream a job log into response object
234         */
235        @Override
236        protected void streamJobLog(HttpServletRequest request, HttpServletResponse response) throws XServletException,
237                IOException {
238            String jobId = getResourceName(request);
239            if (jobId.endsWith("-W")) {
240                streamWorkflowJobLog(request, response);
241            }
242            else {
243                streamCoordinatorJobLog(request, response);
244            }
245        }
246    
247        /**
248         * @param request
249         * @param response
250         * @throws XServletException
251         */
252        private void startWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
253            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
254                                                                                          getAuthToken(request));
255    
256            String jobId = getResourceName(request);
257            try {
258                dagEngine.start(jobId);
259            }
260            catch (DagEngineException ex) {
261                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
262            }
263        }
264    
265        /**
266         * @param request
267         * @param response
268         * @throws XServletException
269         */
270        private void resumeWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
271            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
272                                                                                          getAuthToken(request));
273    
274            String jobId = getResourceName(request);
275            try {
276                dagEngine.resume(jobId);
277            }
278            catch (DagEngineException ex) {
279                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
280            }
281        }
282    
283        /**
284         * @param request
285         * @param response
286         * @throws XServletException
287         * @throws CoordinatorEngineException
288         */
289        private void resumeCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
290                throws XServletException {
291            String jobId = getResourceName(request);
292            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
293                    getUser(request), getAuthToken(request));
294            try {
295                coordEngine.resume(jobId);
296            }
297            catch (CoordinatorEngineException ex) {
298                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
299            }
300        }
301    
302        /**
303         * @param request
304         * @param response
305         * @throws XServletException
306         */
307        private void suspendWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
308            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
309                                                                                          getAuthToken(request));
310    
311            String jobId = getResourceName(request);
312            try {
313                dagEngine.suspend(jobId);
314            }
315            catch (DagEngineException ex) {
316                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
317            }
318        }
319    
320        /**
321         * @param request
322         * @param response
323         * @throws XServletException
324         */
325        private void suspendCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
326                throws XServletException {
327            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
328                    getUser(request), getAuthToken(request));
329            String jobId = getResourceName(request);
330            try {
331                coordEngine.suspend(jobId);
332            }
333            catch (CoordinatorEngineException ex) {
334                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
335            }
336        }
337    
338        /**
339         * @param request
340         * @param response
341         * @throws XServletException
342         */
343        private void killWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
344            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
345                                                                                          getAuthToken(request));
346    
347            String jobId = getResourceName(request);
348            try {
349                dagEngine.kill(jobId);
350            }
351            catch (DagEngineException ex) {
352                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
353            }
354        }
355    
356        /**
357         * @param request
358         * @param response
359         * @throws XServletException
360         */
361        private void killCoordinatorJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
362            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
363                    getUser(request), getAuthToken(request));
364            String jobId = getResourceName(request);
365            try {
366                coordEngine.kill(jobId);
367            }
368            catch (CoordinatorEngineException ex) {
369                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
370            }
371        }
372    
373        /**
374         * Rerun workflow job
375         *
376         * @param request
377         * @param response
378         * @throws XServletException
379         */
380        private void changeCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
381                throws XServletException {
382            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
383                    getUser(request), getAuthToken(request));
384            String jobId = getResourceName(request);
385            String changeValue = request.getParameter(RestConstants.JOB_CHANGE_VALUE);
386            try {
387                coordEngine.change(jobId, changeValue);
388            }
389            catch (CoordinatorEngineException ex) {
390                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
391            }
392        }
393    
394        /**
395         * @param request
396         * @param response
397         * @param conf
398         * @throws XServletException
399         */
400        private void reRunWorkflowJob(HttpServletRequest request, HttpServletResponse response, Configuration conf)
401                throws XServletException {
402            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
403                                                                                          getAuthToken(request));
404    
405            String jobId = getResourceName(request);
406            try {
407                dagEngine.reRun(jobId, conf);
408            }
409            catch (DagEngineException ex) {
410                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
411            }
412        }
413    
414        /**
415         * Rerun coordinator actions
416         *
417         * @param request
418         * @param response
419         * @param conf
420         * @throws XServletException
421         */
422        @SuppressWarnings("unchecked")
423        private JSONObject reRunCoordinatorActions(HttpServletRequest request, HttpServletResponse response,
424                Configuration conf)
425                throws XServletException {
426            JSONObject json = new JSONObject();
427            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(getUser(request),
428                    getAuthToken(request));
429    
430            String jobId = getResourceName(request);
431    
432            String rerunType = request.getParameter(RestConstants.JOB_COORD_RERUN_TYPE_PARAM);
433            String scope = request.getParameter(RestConstants.JOB_COORD_RERUN_SCOPE_PARAM);
434            String refresh = request.getParameter(RestConstants.JOB_COORD_RERUN_REFRESH_PARAM);
435            String noCleanup = request.getParameter(RestConstants.JOB_COORD_RERUN_NOCLEANUP_PARAM);
436    
437            XLog.getLog(getClass()).info(
438                    "Rerun coordinator for jobId=" + jobId + ", rerunType=" + rerunType + ",scope=" + scope + ",refresh="
439                            + refresh + ", noCleanup=" + noCleanup);
440    
441            try {
442                CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh),
443                        Boolean.valueOf(noCleanup));
444                List<CoordinatorActionBean> actions = coordInfo.getCoordActions();
445                json.put(JsonTags.COORDINATOR_ACTIONS, CoordinatorActionBean.toJSONArray(actions));
446            }
447            catch (BaseEngineException ex) {
448                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
449            }
450    
451            return json;
452        }
453    
454        /**
455         * Get workflow job
456         *
457         * @param request
458         * @param response
459         * @return JsonBean WorkflowJobBean
460         * @throws XServletException
461         */
462        private JsonBean getWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
463            JsonBean jobBean = null;
464            String jobId = getResourceName(request);
465            String startStr = request.getParameter(RestConstants.OFFSET_PARAM);
466            String lenStr = request.getParameter(RestConstants.LEN_PARAM);
467            int start = (startStr != null) ? Integer.parseInt(startStr) : 1;
468            start = (start < 1) ? 1 : start;
469            int len = (lenStr != null) ? Integer.parseInt(lenStr) : 0;
470            len = (len < 1) ? Integer.MAX_VALUE : len;
471            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
472                                                                                          getAuthToken(request));
473            try {
474                jobBean = (JsonBean) dagEngine.getJob(jobId, start, len);
475            }
476            catch (DagEngineException ex) {
477                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
478            }
479    
480            return jobBean;
481        }
482    
483        /**
484         * @param request
485         * @param response
486         * @return JsonBean WorkflowActionBean
487         * @throws XServletException
488         */
489        private JsonBean getWorkflowAction(HttpServletRequest request, HttpServletResponse response)
490                throws XServletException {
491            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
492                                                                                          getAuthToken(request));
493    
494            JsonBean actionBean = null;
495            String actionId = getResourceName(request);
496            try {
497                actionBean = dagEngine.getWorkflowAction(actionId);
498            }
499            catch (BaseEngineException ex) {
500                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
501            }
502    
503            return actionBean;
504        }
505    
506        /**
507         * @param request
508         * @param response
509         * @return JsonBean CoordinatorJobBean
510         * @throws XServletException
511         * @throws BaseEngineException
512         */
513        //private JSONObject getCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
514        private JsonBean getCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
515                throws XServletException, BaseEngineException {
516            JsonBean jobBean = null;
517            // JSONObject json = new JSONObject();
518            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
519                    getUser(request), getAuthToken(request));
520            String jobId = getResourceName(request);
521            String startStr = request.getParameter(RestConstants.OFFSET_PARAM);
522            String lenStr = request.getParameter(RestConstants.LEN_PARAM);
523            int start = (startStr != null) ? Integer.parseInt(startStr) : 1;
524            start = (start < 1) ? 1 : start;
525            int len = (lenStr != null) ? Integer.parseInt(lenStr) : 0;
526            len = (len < 1) ? Integer.MAX_VALUE : len;
527            try {
528                JsonCoordinatorJob coordJob = coordEngine.getCoordJob(jobId, start, len);
529                // coordJob.setOffset(start);
530                // coordJob.setLen(len);
531                jobBean = coordJob;
532                // jobBean = (JsonBean) coordEngine.getCoordJob(jobId, start, len);
533            }
534            catch (CoordinatorEngineException ex) {
535                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
536            }
537    
538            return jobBean;
539            //return json;
540        }
541    
542        /**
543         * @param request
544         * @param response
545         * @return JsonBean CoordinatorActionBean
546         * @throws XServletException
547         * @throws BaseEngineException
548         */
549        private JsonBean getCoordinatorAction(HttpServletRequest request, HttpServletResponse response)
550                throws XServletException, BaseEngineException {
551            JsonBean actionBean = null;
552            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
553                    getUser(request), getAuthToken(request));
554            String actionId = getResourceName(request);
555            try {
556                actionBean = coordEngine.getCoordAction(actionId);
557            }
558            catch (CoordinatorEngineException ex) {
559                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
560            }
561    
562            return actionBean;
563        }
564    
565        /**
566         * @param request
567         * @param response
568         * @return String wf definition
569         * @throws XServletException
570         */
571        private String getWorkflowJobDefinition(HttpServletRequest request, HttpServletResponse response)
572                throws XServletException {
573            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
574                                                                                          getAuthToken(request));
575    
576            String wfDefinition;
577            String jobId = getResourceName(request);
578            try {
579                wfDefinition = dagEngine.getDefinition(jobId);
580            }
581            catch (DagEngineException ex) {
582                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
583            }
584            return wfDefinition;
585        }
586    
587        /**
588         * @param request
589         * @param response
590         * @return String coord definition
591         * @throws XServletException
592         */
593        private String getCoordinatorJobDefinition(HttpServletRequest request, HttpServletResponse response)
594                throws XServletException {
595    
596            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
597                    getUser(request), getAuthToken(request));
598    
599            String jobId = getResourceName(request);
600    
601            String coordDefinition = null;
602            try {
603                coordDefinition = coordEngine.getDefinition(jobId);
604            }
605            catch (BaseEngineException ex) {
606                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
607            }
608            return coordDefinition;
609        }
610    
611        /**
612         * @param request
613         * @param response
614         * @throws XServletException
615         * @throws IOException
616         */
617        private void streamWorkflowJobLog(HttpServletRequest request, HttpServletResponse response)
618                throws XServletException, IOException {
619            DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
620                                                                                          getAuthToken(request));
621    
622            String jobId = getResourceName(request);
623            try {
624                dagEngine.streamLog(jobId, response.getWriter());
625            }
626            catch (DagEngineException ex) {
627                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
628            }
629        }
630    
631        /**
632         * @param request
633         * @param response
634         * @throws XServletException
635         * @throws IOException
636         */
637        private void streamCoordinatorJobLog(HttpServletRequest request, HttpServletResponse response)
638                throws XServletException, IOException {
639    
640            CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
641                    getUser(request), getAuthToken(request));
642    
643            String jobId = getResourceName(request);
644    
645            try {
646                coordEngine.streamLog(jobId, response.getWriter());
647            }
648            catch (BaseEngineException ex) {
649                throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
650            }
651    
652        }
653    }