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.servlet; 020 021import java.io.IOException; 022import java.util.List; 023import java.util.Locale; 024 025import javax.servlet.ServletInputStream; 026import javax.servlet.http.HttpServletRequest; 027import javax.servlet.http.HttpServletResponse; 028 029import com.google.common.base.Strings; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.oozie.*; 032import org.apache.oozie.client.WorkflowAction; 033import org.apache.oozie.client.WorkflowJob; 034import org.apache.oozie.client.rest.*; 035import org.apache.oozie.command.CommandException; 036import org.apache.oozie.coord.CoordUtils; 037import org.apache.oozie.service.BundleEngineService; 038import org.apache.oozie.service.ConfigurationService; 039import org.apache.oozie.service.CoordinatorEngineService; 040import org.apache.oozie.service.DagEngineService; 041import org.apache.oozie.service.Services; 042import org.apache.oozie.service.UUIDService; 043import org.apache.oozie.util.Instrumentation; 044import org.apache.oozie.util.graph.GraphGenerator; 045import org.apache.oozie.util.XLog; 046import org.apache.oozie.util.graph.GraphRenderer; 047import org.apache.oozie.util.graph.GraphvizRenderer; 048import org.apache.oozie.util.graph.OutputFormat; 049import org.json.simple.JSONArray; 050import org.json.simple.JSONObject; 051 052 053@SuppressWarnings("serial") 054public class V1JobServlet extends BaseJobServlet { 055 056 private static final String INSTRUMENTATION_NAME = "v1job"; 057 public static final String COORD_ACTIONS_DEFAULT_LENGTH = "oozie.coord.actions.default.length"; 058 059 final static String NOT_SUPPORTED_MESSAGE = "Not supported in v1"; 060 061 062 public V1JobServlet() { 063 super(INSTRUMENTATION_NAME); 064 } 065 066 protected V1JobServlet(String instrumentation_name){ 067 super(instrumentation_name); 068 } 069 070 /* 071 * protected method to start a job 072 */ 073 @Override 074 protected void startJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 075 IOException { 076 /* 077 * Configuration conf = new XConfiguration(request.getInputStream()); 078 * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath = 079 * conf.get(OozieClient.COORDINATOR_APP_PATH); 080 * 081 * ServletUtilities.ValidateAppPath(wfPath, coordPath); 082 */ 083 String jobId = getResourceName(request); 084 if (jobId.endsWith("-W")) { 085 startWorkflowJob(request, response); 086 } 087 else if (jobId.endsWith("-B")) { 088 startBundleJob(request, response); 089 } 090 else { 091 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303, RestConstants.ACTION_PARAM, 092 RestConstants.JOB_ACTION_START); 093 } 094 095 } 096 097 /* 098 * protected method to resume a job 099 */ 100 @Override 101 protected void resumeJob(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 resumeWorkflowJob(request, response); 113 } 114 else if (jobId.endsWith("-B")) { 115 resumeBundleJob(request, response); 116 } 117 else { 118 resumeCoordinatorJob(request, response); 119 } 120 } 121 122 /* 123 * protected method to suspend a job 124 */ 125 @Override 126 protected void suspendJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 127 IOException { 128 /* 129 * Configuration conf = new XConfiguration(request.getInputStream()); 130 * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath = 131 * conf.get(OozieClient.COORDINATOR_APP_PATH); 132 * 133 * ServletUtilities.ValidateAppPath(wfPath, coordPath); 134 */ 135 String jobId = getResourceName(request); 136 if (jobId.endsWith("-W")) { 137 suspendWorkflowJob(request, response); 138 } 139 else if (jobId.endsWith("-B")) { 140 suspendBundleJob(request, response); 141 } 142 else { 143 suspendCoordinatorJob(request, response); 144 } 145 } 146 147 /* 148 * protected method to kill a job 149 */ 150 @Override 151 protected JSONObject killJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 152 IOException { 153 /* 154 * Configuration conf = new XConfiguration(request.getInputStream()); 155 * String wfPath = conf.get(OozieClient.APP_PATH); String coordPath = 156 * conf.get(OozieClient.COORDINATOR_APP_PATH); 157 * 158 * ServletUtilities.ValidateAppPath(wfPath, coordPath); 159 */ 160 String jobId = getResourceName(request); 161 JSONObject json = null; 162 if (jobId.endsWith("-W")) { 163 killWorkflowJob(request, response); 164 } 165 else if (jobId.endsWith("-B")) { 166 killBundleJob(request, response); 167 } 168 else { 169 json = killCoordinator(request, response); 170 } 171 return json; 172 } 173 174 /** 175 * protected method to change a coordinator job 176 * @param request request object 177 * @param response response object 178 * @throws XServletException 179 * @throws IOException 180 */ 181 @Override 182 protected void changeJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 183 IOException { 184 String jobId = getResourceName(request); 185 if (jobId.endsWith("-B")) { 186 changeBundleJob(request, response); 187 } 188 else { 189 changeCoordinatorJob(request, response); 190 } 191 } 192 @Override 193 protected JSONObject ignoreJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, IOException { 194 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 195 } 196 197 /* 198 * protected method to reRun a job 199 * 200 * @seeorg.apache.oozie.servlet.BaseJobServlet#reRunJob(javax.servlet.http. 201 * HttpServletRequest, javax.servlet.http.HttpServletResponse, 202 * org.apache.hadoop.conf.Configuration) 203 */ 204 @Override 205 protected JSONObject reRunJob(HttpServletRequest request, HttpServletResponse response, Configuration conf) 206 throws XServletException, IOException { 207 JSONObject json = null; 208 String jobId = getResourceName(request); 209 if (jobId.endsWith("-W")) { 210 reRunWorkflowJob(request, response, conf); 211 } 212 else if (jobId.endsWith("-B")) { 213 rerunBundleJob(request, response, conf); 214 } 215 else { 216 json = reRunCoordinatorActions(request, response, conf); 217 } 218 return json; 219 } 220 221 /* 222 * protected method to get a job in JsonBean representation 223 */ 224 @Override 225 protected JsonBean getJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 226 IOException, BaseEngineException { 227 ServletInputStream is = request.getInputStream(); 228 byte[] b = new byte[101]; 229 while (is.readLine(b, 0, 100) != -1) { 230 XLog.getLog(getClass()).warn("Printing :" + new String(b)); 231 } 232 233 JsonBean jobBean = null; 234 String jobId = getResourceName(request); 235 if (jobId.endsWith("-B")) { 236 jobBean = getBundleJob(request, response); 237 } 238 else { 239 if (jobId.endsWith("-W")) { 240 jobBean = getWorkflowJob(request, response); 241 } 242 else { 243 if (jobId.contains("-W@")) { 244 jobBean = getWorkflowAction(request, response); 245 } 246 else { 247 if (jobId.contains("-C@")) { 248 jobBean = getCoordinatorAction(request, response); 249 } 250 else { 251 jobBean = getCoordinatorJob(request, response); 252 } 253 } 254 } 255 } 256 257 return jobBean; 258 } 259 260 /* 261 * protected method to get a job definition in String format 262 */ 263 @Override 264 protected String getJobDefinition(HttpServletRequest request, HttpServletResponse response) 265 throws XServletException, IOException { 266 String jobDefinition = null; 267 String jobId = getResourceName(request); 268 if (jobId.endsWith("-W")) { 269 jobDefinition = getWorkflowJobDefinition(request, response); 270 } 271 else if (jobId.endsWith("-B")) { 272 jobDefinition = getBundleJobDefinition(request, response); 273 } 274 else { 275 jobDefinition = getCoordinatorJobDefinition(request, response); 276 } 277 return jobDefinition; 278 } 279 280 /* 281 * protected method to stream a job log into response object 282 */ 283 @Override 284 protected void streamJobLog(HttpServletRequest request, HttpServletResponse response) throws XServletException, 285 IOException { 286 try { 287 String jobId = getResourceName(request); 288 if (jobId.endsWith("-W")) { 289 streamWorkflowJobLog(request, response); 290 } 291 else if (jobId.endsWith("-B")) { 292 streamBundleJobLog(request, response); 293 } 294 else { 295 streamCoordinatorJobLog(request, response); 296 } 297 } 298 catch (Exception e) { 299 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0307, e.getMessage()); 300 } 301 } 302 303 @Override 304 protected void streamJobGraph(HttpServletRequest request, HttpServletResponse response) 305 throws XServletException, IOException { 306 String jobId = getResourceName(request); 307 if (jobId.endsWith("-W")) { 308 try { 309 310 final String showKillParameter = request.getParameter(RestConstants.JOB_SHOW_KILL_PARAM); 311 final boolean showKill = isShowKillSet(showKillParameter); 312 313 final String formatParameter = request.getParameter(RestConstants.JOB_FORMAT_PARAM); 314 final OutputFormat outputFormat = getOutputFormat(formatParameter); 315 316 final String contentType = getContentType(outputFormat); 317 318 response.setContentType(contentType); 319 320 final Instrumentation.Cron cron = new Instrumentation.Cron(); 321 cron.start(); 322 323 final GraphRenderer graphRenderer = new GraphvizRenderer(); 324 325 new GraphGenerator( 326 getWorkflowJobDefinition(request, response), 327 (WorkflowJobBean)getWorkflowJob(request, response), 328 showKill, 329 graphRenderer).write(response.getOutputStream(), outputFormat); 330 331 cron.stop(); 332 instrument(outputFormat, cron); 333 } 334 catch (final Exception e) { 335 throw new XServletException(HttpServletResponse.SC_NOT_FOUND, ErrorCode.E0307, e.getMessage(), e); 336 } 337 } 338 else { 339 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0306); 340 } 341 } 342 343 private boolean isShowKillSet(final String showKillParameter) { 344 return showKillParameter != null && 345 (showKillParameter.equalsIgnoreCase("yes") || 346 showKillParameter.equals("1") || 347 showKillParameter.equalsIgnoreCase("true")); 348 } 349 350 private OutputFormat getOutputFormat(final String formatParameter) { 351 final OutputFormat outputFormat; 352 if (Strings.isNullOrEmpty(formatParameter)) { 353 outputFormat = OutputFormat.PNG; 354 } 355 else { 356 outputFormat = OutputFormat.valueOf(formatParameter.toUpperCase(Locale.getDefault())); 357 } 358 return outputFormat; 359 } 360 361 private String getContentType(final OutputFormat outputFormat) { 362 final String contentType; 363 364 switch (outputFormat) { 365 case PNG: 366 contentType = RestConstants.PNG_IMAGE_CONTENT_TYPE; 367 break; 368 case DOT: 369 contentType = RestConstants.TEXT_CONTENT_TYPE; 370 break; 371 case SVG: 372 contentType = RestConstants.SVG_IMAGE_CONTENT_TYPE; 373 break; 374 default: 375 throw new IllegalArgumentException("Unknown output format, cannot get content type: " + outputFormat); 376 } 377 378 return contentType; 379 } 380 381 private void instrument(final OutputFormat outputFormat, final Instrumentation.Cron cron) { 382 addCron(INSTRUMENTATION_NAME + "-graph", cron); 383 incrCounter(INSTRUMENTATION_NAME + "-graph", 1); 384 addCron(INSTRUMENTATION_NAME + "-graph-" + outputFormat.toString().toLowerCase(Locale.getDefault()), cron); 385 incrCounter(INSTRUMENTATION_NAME + "-graph-" + outputFormat.toString().toLowerCase(Locale.getDefault()), 1); 386 } 387 388 /** 389 * Start wf job 390 * 391 * @param request servlet request 392 * @param response servlet response 393 * @throws XServletException 394 */ 395 private void startWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 396 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 397 398 String jobId = getResourceName(request); 399 try { 400 dagEngine.start(jobId); 401 } 402 catch (DagEngineException ex) { 403 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 404 } 405 } 406 407 /** 408 * Start bundle job 409 * 410 * @param request servlet request 411 * @param response servlet response 412 * @throws XServletException 413 */ 414 private void startBundleJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 415 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 416 String jobId = getResourceName(request); 417 try { 418 bundleEngine.start(jobId); 419 } 420 catch (BundleEngineException ex) { 421 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 422 } 423 } 424 425 /** 426 * Resume workflow job 427 * 428 * @param request servlet request 429 * @param response servlet response 430 * @throws XServletException 431 */ 432 private void resumeWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 433 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 434 435 String jobId = getResourceName(request); 436 try { 437 dagEngine.resume(jobId); 438 } 439 catch (DagEngineException ex) { 440 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 441 } 442 } 443 444 /** 445 * Resume bundle job 446 * 447 * @param request servlet request 448 * @param response servlet response 449 * @throws XServletException 450 */ 451 private void resumeBundleJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 452 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 453 String jobId = getResourceName(request); 454 try { 455 bundleEngine.resume(jobId); 456 } 457 catch (BundleEngineException ex) { 458 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 459 } 460 } 461 462 /** 463 * Resume coordinator job 464 * 465 * @param request servlet request 466 * @param response servlet response 467 * @throws XServletException 468 * @throws CoordinatorEngineException 469 */ 470 private void resumeCoordinatorJob(HttpServletRequest request, HttpServletResponse response) 471 throws XServletException { 472 String jobId = getResourceName(request); 473 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 474 getUser(request)); 475 try { 476 coordEngine.resume(jobId); 477 } 478 catch (CoordinatorEngineException ex) { 479 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 480 } 481 } 482 483 /** 484 * Suspend a wf job 485 * 486 * @param request servlet request 487 * @param response servlet response 488 * @throws XServletException 489 */ 490 private void suspendWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 491 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 492 493 String jobId = getResourceName(request); 494 try { 495 dagEngine.suspend(jobId); 496 } 497 catch (DagEngineException ex) { 498 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 499 } 500 } 501 502 /** 503 * Suspend bundle job 504 * 505 * @param request servlet request 506 * @param response servlet response 507 * @throws XServletException 508 */ 509 private void suspendBundleJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 510 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 511 String jobId = getResourceName(request); 512 try { 513 bundleEngine.suspend(jobId); 514 } 515 catch (BundleEngineException ex) { 516 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 517 } 518 } 519 520 /** 521 * Suspend coordinator job 522 * 523 * @param request servlet request 524 * @param response servlet response 525 * @throws XServletException 526 */ 527 private void suspendCoordinatorJob(HttpServletRequest request, HttpServletResponse response) 528 throws XServletException { 529 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 530 getUser(request)); 531 String jobId = getResourceName(request); 532 try { 533 coordEngine.suspend(jobId); 534 } 535 catch (CoordinatorEngineException ex) { 536 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 537 } 538 } 539 540 /** 541 * Kill a wf job 542 * @param request servlet request 543 * @param response servlet response 544 * @throws XServletException 545 */ 546 private void killWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 547 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 548 549 String jobId = getResourceName(request); 550 try { 551 dagEngine.kill(jobId); 552 } 553 catch (DagEngineException ex) { 554 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 555 } 556 } 557 558 /** 559 * Kill a coord job 560 * 561 * @param request servlet request 562 * @param response servlet response 563 * @throws XServletException 564 */ 565 @SuppressWarnings("unchecked") 566 private JSONObject killCoordinator(HttpServletRequest request, HttpServletResponse response) throws XServletException { 567 String jobId = getResourceName(request); 568 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class) 569 .getCoordinatorEngine(getUser(request)); 570 JSONObject json = null; 571 String rangeType = request.getParameter(RestConstants.JOB_COORD_RANGE_TYPE_PARAM); 572 String scope = request.getParameter(RestConstants.JOB_COORD_SCOPE_PARAM); 573 574 try { 575 if (rangeType != null && scope != null) { 576 XLog.getLog(getClass()).info( 577 "Kill coordinator actions for jobId=" + jobId + ", rangeType=" + rangeType + ",scope=" + scope); 578 579 json = new JSONObject(); 580 CoordinatorActionInfo coordInfo = coordEngine.killActions(jobId, rangeType, scope); 581 List<CoordinatorActionBean> coordActions; 582 if (coordInfo != null) { 583 coordActions = coordInfo.getCoordActions(); 584 } 585 else { 586 coordActions = CoordUtils.getCoordActions(rangeType, jobId, scope, true); 587 } 588 json.put(JsonTags.COORDINATOR_ACTIONS, CoordinatorActionBean.toJSONArray(coordActions, "GMT")); 589 } 590 else { 591 coordEngine.kill(jobId); 592 } 593 } 594 catch (CoordinatorEngineException ex) { 595 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 596 } 597 catch (CommandException ex) { 598 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 599 } 600 return json; 601 } 602 603 /** 604 * Kill bundle job 605 * 606 * @param request servlet request 607 * @param response servlet response 608 * @throws XServletException 609 */ 610 private void killBundleJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 611 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 612 String jobId = getResourceName(request); 613 try { 614 bundleEngine.kill(jobId); 615 } 616 catch (BundleEngineException ex) { 617 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 618 } 619 } 620 621 /** 622 * Change a coordinator job 623 * 624 * @param request servlet request 625 * @param response servlet response 626 * @throws XServletException 627 */ 628 private void changeCoordinatorJob(HttpServletRequest request, HttpServletResponse response) 629 throws XServletException { 630 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 631 getUser(request)); 632 String jobId = getResourceName(request); 633 String changeValue = request.getParameter(RestConstants.JOB_CHANGE_VALUE); 634 try { 635 coordEngine.change(jobId, changeValue); 636 } 637 catch (CoordinatorEngineException ex) { 638 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 639 } 640 } 641 642 /** 643 * Change a bundle job 644 * 645 * @param request servlet request 646 * @param response servlet response 647 * @throws XServletException 648 */ 649 private void changeBundleJob(HttpServletRequest request, HttpServletResponse response) 650 throws XServletException { 651 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 652 String jobId = getResourceName(request); 653 String changeValue = request.getParameter(RestConstants.JOB_CHANGE_VALUE); 654 try { 655 bundleEngine.change(jobId, changeValue); 656 } 657 catch (BundleEngineException ex) { 658 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 659 } 660 } 661 662 /** 663 * Rerun a wf job 664 * 665 * @param request servlet request 666 * @param response servlet response 667 * @param conf configuration object 668 * @throws XServletException 669 */ 670 private void reRunWorkflowJob(HttpServletRequest request, HttpServletResponse response, Configuration conf) 671 throws XServletException { 672 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 673 674 String jobId = getResourceName(request); 675 try { 676 dagEngine.reRun(jobId, conf); 677 } 678 catch (DagEngineException ex) { 679 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 680 } 681 } 682 683 /** 684 * Rerun bundle job 685 * 686 * @param request servlet request 687 * @param response servlet response 688 * @param conf configration object 689 * @throws XServletException 690 */ 691 private void rerunBundleJob(HttpServletRequest request, HttpServletResponse response, Configuration conf) 692 throws XServletException { 693 JSONObject json = new JSONObject(); 694 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 695 String jobId = getResourceName(request); 696 697 String coordScope = request.getParameter(RestConstants.JOB_BUNDLE_RERUN_COORD_SCOPE_PARAM); 698 String dateScope = request.getParameter(RestConstants.JOB_BUNDLE_RERUN_DATE_SCOPE_PARAM); 699 String refresh = request.getParameter(RestConstants.JOB_COORD_RERUN_REFRESH_PARAM); 700 String noCleanup = request.getParameter(RestConstants.JOB_COORD_RERUN_NOCLEANUP_PARAM); 701 702 XLog.getLog(getClass()).info( 703 "Rerun Bundle for jobId=" + jobId + ", coordScope=" + coordScope + ", dateScope=" + dateScope + ", refresh=" 704 + refresh + ", noCleanup=" + noCleanup); 705 706 try { 707 bundleEngine.reRun(jobId, coordScope, dateScope, Boolean.valueOf(refresh), Boolean.valueOf(noCleanup)); 708 } 709 catch (BaseEngineException ex) { 710 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 711 } 712 } 713 714 /** 715 * Rerun coordinator actions 716 * 717 * @param request servlet request 718 * @param response servlet response 719 * @param conf configuration object 720 * @throws XServletException 721 */ 722 @SuppressWarnings("unchecked") 723 private JSONObject reRunCoordinatorActions(HttpServletRequest request, HttpServletResponse response, 724 Configuration conf) throws XServletException { 725 JSONObject json = new JSONObject(); 726 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(getUser(request)); 727 728 String jobId = getResourceName(request); 729 730 String rerunType = request.getParameter(RestConstants.JOB_COORD_RANGE_TYPE_PARAM); 731 String scope = request.getParameter(RestConstants.JOB_COORD_SCOPE_PARAM); 732 String refresh = request.getParameter(RestConstants.JOB_COORD_RERUN_REFRESH_PARAM); 733 String noCleanup = request.getParameter(RestConstants.JOB_COORD_RERUN_NOCLEANUP_PARAM); 734 String failed = request.getParameter(RestConstants.JOB_COORD_RERUN_FAILED_PARAM); 735 736 XLog.getLog(getClass()).info( 737 "Rerun coordinator for jobId=" + jobId + ", rerunType=" + rerunType + ",scope=" + scope + ",refresh=" 738 + refresh + ", noCleanup=" + noCleanup); 739 740 try { 741 if (!(rerunType.equals(RestConstants.JOB_COORD_SCOPE_DATE) || rerunType 742 .equals(RestConstants.JOB_COORD_SCOPE_ACTION))) { 743 throw new CommandException(ErrorCode.E1018, "date or action expected."); 744 } 745 CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh), 746 Boolean.valueOf(noCleanup), Boolean.valueOf(failed), conf); 747 List<CoordinatorActionBean> coordActions; 748 if (coordInfo != null) { 749 coordActions = coordInfo.getCoordActions(); 750 } 751 else { 752 coordActions = CoordUtils.getCoordActions(rerunType, jobId, scope, false); 753 } 754 json.put(JsonTags.COORDINATOR_ACTIONS, CoordinatorActionBean.toJSONArray(coordActions, "GMT")); 755 } 756 catch (BaseEngineException ex) { 757 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 758 } 759 catch (CommandException ex) { 760 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 761 } 762 763 return json; 764 } 765 766 767 768 /** 769 * Get workflow job 770 * 771 * @param request servlet request 772 * @param response servlet response 773 * @return JsonBean WorkflowJobBean 774 * @throws XServletException 775 */ 776 protected JsonBean getWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException { 777 JsonBean jobBean = getWorkflowJobBean(request, response); 778 // for backward compatibility (OOZIE-1231) 779 swapMRActionID((WorkflowJob)jobBean); 780 return jobBean; 781 } 782 783 /** 784 * Get workflow job 785 * 786 * @param request servlet request 787 * @param response servlet response 788 * @return JsonBean WorkflowJobBean 789 * @throws XServletException 790 */ 791 protected JsonBean getWorkflowJobBean(HttpServletRequest request, HttpServletResponse response) throws XServletException { 792 JsonBean jobBean = null; 793 String jobId = getResourceName(request); 794 String startStr = request.getParameter(RestConstants.OFFSET_PARAM); 795 String lenStr = request.getParameter(RestConstants.LEN_PARAM); 796 int start = (startStr != null) ? Integer.parseInt(startStr) : 1; 797 start = (start < 1) ? 1 : start; 798 int len = (lenStr != null) ? Integer.parseInt(lenStr) : 0; 799 len = (len < 1) ? Integer.MAX_VALUE : len; 800 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 801 try { 802 jobBean = (JsonBean) dagEngine.getJob(jobId, start, len); 803 } 804 catch (DagEngineException ex) { 805 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 806 } 807 return jobBean; 808 } 809 810 private void swapMRActionID(WorkflowJob wjBean) { 811 List<WorkflowAction> actions = wjBean.getActions(); 812 if (actions != null) { 813 for (WorkflowAction wa : actions) { 814 swapMRActionID(wa); 815 } 816 } 817 } 818 819 private void swapMRActionID(WorkflowAction waBean) { 820 if (waBean.getType().equals("map-reduce")) { 821 String childId = waBean.getExternalChildIDs(); 822 if (childId != null && !childId.equals("")) { 823 String consoleBase = getConsoleBase(waBean.getConsoleUrl()); 824 ((WorkflowActionBean) waBean).setConsoleUrl(consoleBase + childId); 825 ((WorkflowActionBean) waBean).setExternalId(childId); 826 ((WorkflowActionBean) waBean).setExternalChildIDs(""); 827 } 828 } 829 } 830 831 private String getConsoleBase(String url) { 832 String consoleBase = null; 833 if (url.indexOf("application") != -1) { 834 consoleBase = url.split("application_[0-9]+_[0-9]+")[0]; 835 } 836 else { 837 consoleBase = url.split("job_[0-9]+_[0-9]+")[0]; 838 } 839 return consoleBase; 840 } 841 842 /** 843 * Get wf action info 844 * 845 * @param request servlet request 846 * @param response servlet response 847 * @return JsonBean WorkflowActionBean 848 * @throws XServletException 849 */ 850 protected JsonBean getWorkflowAction(HttpServletRequest request, HttpServletResponse response) 851 throws XServletException { 852 853 JsonBean actionBean = getWorkflowActionBean(request, response); 854 // for backward compatibility (OOZIE-1231) 855 swapMRActionID((WorkflowAction)actionBean); 856 return actionBean; 857 } 858 859 protected JsonBean getWorkflowActionBean(HttpServletRequest request, HttpServletResponse response) 860 throws XServletException { 861 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 862 863 JsonBean actionBean = null; 864 String actionId = getResourceName(request); 865 try { 866 actionBean = dagEngine.getWorkflowAction(actionId); 867 } 868 catch (BaseEngineException ex) { 869 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 870 } 871 return actionBean; 872 } 873 874 /** 875 * Get coord job info 876 * 877 * @param request servlet request 878 * @param response servlet response 879 * @return JsonBean CoordinatorJobBean 880 * @throws XServletException 881 * @throws BaseEngineException 882 */ 883 protected JsonBean getCoordinatorJob(HttpServletRequest request, HttpServletResponse response) 884 throws XServletException, BaseEngineException { 885 JsonBean jobBean = null; 886 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 887 getUser(request)); 888 String jobId = getResourceName(request); 889 String startStr = request.getParameter(RestConstants.OFFSET_PARAM); 890 String lenStr = request.getParameter(RestConstants.LEN_PARAM); 891 String filter = request.getParameter(RestConstants.JOB_FILTER_PARAM); 892 String orderStr = request.getParameter(RestConstants.ORDER_PARAM); 893 boolean order = (orderStr != null && orderStr.equals("desc")) ? true : false; 894 int offset = (startStr != null) ? Integer.parseInt(startStr) : 1; 895 offset = (offset < 1) ? 1 : offset; 896 // Get default number of coordinator actions to be retrieved 897 int defaultLen = ConfigurationService.getInt(COORD_ACTIONS_DEFAULT_LENGTH); 898 int len = (lenStr != null) ? Integer.parseInt(lenStr) : 0; 899 len = getCoordinatorJobLength(defaultLen, len); 900 try { 901 CoordinatorJobBean coordJob = coordEngine.getCoordJob(jobId, filter, offset, len, order); 902 jobBean = coordJob; 903 } 904 catch (CoordinatorEngineException ex) { 905 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 906 } 907 908 return jobBean; 909 } 910 911 /** 912 * Given the requested length and the default length, determine how many coordinator jobs to return. 913 * Used by {@link #getCoordinatorJob(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} 914 * 915 * @param defaultLen The default length 916 * @param len The requested length 917 * @return The length to use 918 */ 919 protected int getCoordinatorJobLength(int defaultLen, int len) { 920 return (len < 1) ? defaultLen : len; 921 } 922 923 /** 924 * Get bundle job info 925 * 926 * @param request servlet request 927 * @param response servlet response 928 * @return JsonBean bundle job bean 929 * @throws XServletException 930 * @throws BaseEngineException 931 */ 932 private JsonBean getBundleJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, 933 BaseEngineException { 934 JsonBean jobBean = null; 935 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 936 String jobId = getResourceName(request); 937 938 try { 939 jobBean = (JsonBean) bundleEngine.getBundleJob(jobId); 940 941 return jobBean; 942 } 943 catch (BundleEngineException ex) { 944 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 945 } 946 } 947 948 /** 949 * Get coordinator action 950 * 951 * @param request servlet request 952 * @param response servlet response 953 * @return JsonBean CoordinatorActionBean 954 * @throws XServletException 955 * @throws BaseEngineException 956 */ 957 private JsonBean getCoordinatorAction(HttpServletRequest request, HttpServletResponse response) 958 throws XServletException, BaseEngineException { 959 JsonBean actionBean = null; 960 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 961 getUser(request)); 962 String actionId = getResourceName(request); 963 try { 964 actionBean = coordEngine.getCoordAction(actionId); 965 } 966 catch (CoordinatorEngineException ex) { 967 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 968 } 969 970 return actionBean; 971 } 972 973 /** 974 * Get wf job definition 975 * 976 * @param request servlet request 977 * @param response servlet response 978 * @return String wf definition 979 * @throws XServletException 980 */ 981 private String getWorkflowJobDefinition(HttpServletRequest request, HttpServletResponse response) 982 throws XServletException { 983 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 984 985 String wfDefinition; 986 String jobId = getResourceName(request); 987 try { 988 wfDefinition = dagEngine.getDefinition(jobId); 989 } 990 catch (DagEngineException ex) { 991 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 992 } 993 return wfDefinition; 994 } 995 996 /** 997 * Get bundle job definition 998 * 999 * @param request servlet request 1000 * @param response servlet response 1001 * @return String bundle definition 1002 * @throws XServletException 1003 */ 1004 private String getBundleJobDefinition(HttpServletRequest request, HttpServletResponse response) throws XServletException { 1005 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 1006 String bundleDefinition; 1007 String jobId = getResourceName(request); 1008 try { 1009 bundleDefinition = bundleEngine.getDefinition(jobId); 1010 } 1011 catch (BundleEngineException ex) { 1012 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1013 } 1014 return bundleDefinition; 1015 } 1016 1017 /** 1018 * Get coordinator job definition 1019 * 1020 * @param request servlet request 1021 * @param response servlet response 1022 * @return String coord definition 1023 * @throws XServletException 1024 */ 1025 private String getCoordinatorJobDefinition(HttpServletRequest request, HttpServletResponse response) 1026 throws XServletException { 1027 1028 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 1029 getUser(request)); 1030 1031 String jobId = getResourceName(request); 1032 1033 String coordDefinition = null; 1034 try { 1035 coordDefinition = coordEngine.getDefinition(jobId); 1036 } 1037 catch (BaseEngineException ex) { 1038 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1039 } 1040 return coordDefinition; 1041 } 1042 1043 /** 1044 * Stream wf job log 1045 * 1046 * @param request servlet request 1047 * @param response servlet response 1048 * @throws XServletException 1049 * @throws IOException 1050 */ 1051 private void streamWorkflowJobLog(HttpServletRequest request, HttpServletResponse response) 1052 throws XServletException, IOException { 1053 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request)); 1054 String jobId = getResourceName(request); 1055 try { 1056 dagEngine.streamLog(jobId, response.getWriter(), request.getParameterMap()); 1057 } 1058 catch (BaseEngineException ex) { 1059 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1060 } 1061 } 1062 1063 /** 1064 * Stream bundle job log 1065 * 1066 * @param request servlet request 1067 * @param response servlet response 1068 * @throws XServletException 1069 */ 1070 private void streamBundleJobLog(HttpServletRequest request, HttpServletResponse response) 1071 throws XServletException, IOException { 1072 BundleEngine bundleEngine = Services.get().get(BundleEngineService.class).getBundleEngine(getUser(request)); 1073 String jobId = getResourceName(request); 1074 try { 1075 bundleEngine.streamLog(jobId, response.getWriter(), request.getParameterMap()); 1076 } 1077 catch (BaseEngineException ex) { 1078 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1079 } 1080 } 1081 1082 /** 1083 * Stream coordinator job log 1084 * 1085 * @param request servlet request 1086 * @param response servlet response 1087 * @throws XServletException 1088 * @throws IOException 1089 */ 1090 private void streamCoordinatorJobLog(HttpServletRequest request, HttpServletResponse response) 1091 throws XServletException, IOException { 1092 1093 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine( 1094 getUser(request)); 1095 String jobId = getResourceName(request); 1096 String logRetrievalScope = request.getParameter(RestConstants.JOB_LOG_SCOPE_PARAM); 1097 String logRetrievalType = request.getParameter(RestConstants.JOB_LOG_TYPE_PARAM); 1098 try { 1099 coordEngine.streamLog(jobId, logRetrievalScope, logRetrievalType, response.getWriter(), request.getParameterMap()); 1100 } 1101 catch (BaseEngineException ex) { 1102 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1103 } 1104 catch (CommandException ex) { 1105 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1106 } 1107 } 1108 1109 @Override 1110 protected String getJMSTopicName(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1111 IOException { 1112 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1113 } 1114 1115 @Override 1116 protected JSONObject getJobsByParentId(HttpServletRequest request, HttpServletResponse response) 1117 throws XServletException, IOException { 1118 JSONObject json = new JSONObject(); 1119 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class) 1120 .getCoordinatorEngine(getUser(request)); 1121 String coordActionId; 1122 String type = request.getParameter(RestConstants.JOB_COORD_RANGE_TYPE_PARAM); 1123 String scope = request.getParameter(RestConstants.JOB_COORD_SCOPE_PARAM); 1124 // for getting allruns for coordinator action - 2 alternate endpoints 1125 if (type != null && type.equals(RestConstants.JOB_COORD_SCOPE_ACTION) && scope != null) { 1126 // endpoint - oozie/v2/coord-job-id?type=action&scope=action-num&show=allruns 1127 String jobId = getResourceName(request); 1128 coordActionId = Services.get().get(UUIDService.class).generateChildId(jobId, scope); 1129 } 1130 else { 1131 // endpoint - oozie/v2/coord-action-id?show=allruns 1132 coordActionId = getResourceName(request); 1133 } 1134 try { 1135 List<WorkflowJobBean> wfs = coordEngine.getReruns(coordActionId); 1136 JSONArray array = new JSONArray(); 1137 if (wfs != null) { 1138 for (WorkflowJobBean wf : wfs) { 1139 JSONObject json1 = new JSONObject(); 1140 json1.put(JsonTags.WORKFLOW_ID, wf.getId()); 1141 json1.put(JsonTags.WORKFLOW_STATUS, wf.getStatus().toString()); 1142 json1.put(JsonTags.WORKFLOW_START_TIME, JsonUtils.formatDateRfc822(wf.getStartTime(), "GMT")); 1143 json1.put(JsonTags.WORKFLOW_ACTION_END_TIME, JsonUtils.formatDateRfc822(wf.getEndTime(), "GMT")); 1144 array.add(json1); 1145 } 1146 } 1147 json.put(JsonTags.WORKFLOWS_JOBS, array); 1148 return json; 1149 } 1150 catch (CoordinatorEngineException ex) { 1151 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex); 1152 } 1153 } 1154 /** 1155 * not supported for v1 1156 */ 1157 @Override 1158 protected JSONObject updateJob(HttpServletRequest request, HttpServletResponse response, Configuration conf) 1159 throws XServletException, IOException { 1160 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1161 } 1162 1163 @Override 1164 protected String getJobStatus(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1165 IOException { 1166 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1167 } 1168 1169 @Override 1170 protected void streamJobErrorLog(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1171 IOException { 1172 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1173 } 1174 @Override 1175 protected void streamJobAuditLog(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1176 IOException { 1177 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1178 } 1179 @Override 1180 void slaEnableAlert(HttpServletRequest request, HttpServletResponse response) throws XServletException, IOException { 1181 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1182 } 1183 1184 @Override 1185 void slaDisableAlert(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1186 IOException { 1187 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1188 } 1189 1190 @Override 1191 void slaChange(HttpServletRequest request, HttpServletResponse response) throws XServletException, IOException { 1192 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1193 } 1194 1195 @Override 1196 JSONObject getCoordActionMissingDependencies(HttpServletRequest request, HttpServletResponse response) 1197 throws XServletException, IOException { 1198 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1199 } 1200 1201 @Override 1202 JSONArray getActionRetries(HttpServletRequest request, HttpServletResponse response) throws XServletException, 1203 IOException { 1204 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, NOT_SUPPORTED_MESSAGE); 1205 } 1206}