@Override
 public void run() {
   boolean outputFailed = false;
   try {
     InputStream in = input;
     OutputStream out = output;
     byte[] buf = new byte[256];
     while (true) {
       int read = in.read(buf);
       if (read == -1) {
         break;
       }
       if (outputFailed == false) {
         try {
           out.write(buf, 0, read);
         } catch (IOException e) {
           outputFailed = true;
           YSLOG.warn(e, "W99001");
         }
       }
     }
   } catch (IOException e) {
     YSLOG.warn(e, "W99002");
   } finally {
     if (closeInput) {
       close(input);
     }
     if (closeOutput) {
       close(output);
     }
   }
 }
 /**
  * Executes a target flow. If execution is failed except on {@link ExecutionPhase#SETUP setup},
  * {@link ExecutionPhase#FINALIZE finalize}, or {@link ExecutionPhase#CLEANUP cleanup}, then the
  * {@code finalize} phase will be executed for recovery before the target flow execution is
  * aborted. Execution ID for each flow will automatically generated.
  *
  * @param batchId target batch ID
  * @throws InterruptedException if interrupted during this execution
  * @throws IOException if failed to execute target batch
  * @throws IllegalArgumentException if some parameters were {@code null}
  */
 public void executeBatch(String batchId) throws InterruptedException, IOException {
   if (batchId == null) {
     throw new IllegalArgumentException("batchId must not be null"); // $NON-NLS-1$
   }
   ExecutorService executor = createJobflowExecutor(batchId);
   YSLOG.info("I01000", batchId);
   long start = System.currentTimeMillis();
   try {
     ExecutionLock lock = acquireExecutionLock(batchId);
     try {
       BatchScheduler batchScheduler = new BatchScheduler(batchId, script, lock, executor);
       batchScheduler.run();
     } finally {
       lock.close();
     }
     YSLOG.info("I01001", batchId);
   } catch (IOException e) {
     YSLOG.error(e, "E01001", batchId);
     throw e;
   } catch (InterruptedException e) {
     YSLOG.warn(e, "W01001", batchId);
     throw e;
   } finally {
     long end = System.currentTimeMillis();
     YSLOG.info("I01999", batchId, end - start);
   }
 }
 private static void close(OutputStream c) {
   try {
     c.close();
   } catch (IOException e) {
     YSLOG.warn(e, "W99003");
   }
 }
 void executeFlow(String batchId, FlowScript flow, String executionId)
     throws InterruptedException, IOException {
   assert batchId != null;
   assert flow != null;
   assert executionId != null;
   YSLOG.info("I02000", batchId, flow.getId(), executionId);
   long start = System.currentTimeMillis();
   try {
     if (skipFlows.contains(flow.getId())) {
       YSLOG.info("I02002", batchId, flow.getId(), executionId);
       return;
     }
     executePhase(batchId, flow, executionId, ExecutionPhase.SETUP);
     boolean succeed = false;
     try {
       executePhase(batchId, flow, executionId, ExecutionPhase.INITIALIZE);
       executePhase(batchId, flow, executionId, ExecutionPhase.IMPORT);
       executePhase(batchId, flow, executionId, ExecutionPhase.PROLOGUE);
       executePhase(batchId, flow, executionId, ExecutionPhase.MAIN);
       executePhase(batchId, flow, executionId, ExecutionPhase.EPILOGUE);
       executePhase(batchId, flow, executionId, ExecutionPhase.EXPORT);
       succeed = true;
     } finally {
       if (succeed) {
         executePhase(batchId, flow, executionId, ExecutionPhase.FINALIZE);
       } else {
         YSLOG.info("I02003", batchId, flow.getId(), executionId);
         try {
           executePhase(batchId, flow, executionId, ExecutionPhase.FINALIZE);
         } catch (Exception e) {
           YSLOG.warn(e, "W02002", batchId, flow.getId(), executionId);
         }
       }
     }
     try {
       executePhase(batchId, flow, executionId, ExecutionPhase.CLEANUP);
     } catch (Exception e) {
       YSLOG.warn(e, "W02003", batchId, flow.getId(), executionId);
     }
     YSLOG.info("I02001", batchId, flow.getId(), executionId);
   } catch (IOException e) {
     YSLOG.error(e, "E02001", batchId, flow.getId(), executionId);
     throw e;
   } catch (InterruptedException e) {
     YSLOG.warn(e, "W02001", batchId, flow.getId(), executionId);
     throw e;
   } finally {
     long end = System.currentTimeMillis();
     YSLOG.info("I02999", batchId, flow.getId(), executionId, end - start);
   }
 }
 private void executePhase(ExecutionContext context, Set<ExecutionScript> executions)
     throws InterruptedException, IOException {
   assert context != null;
   assert executions != null;
   YSLOG.info(
       "I03000",
       context.getBatchId(),
       context.getFlowId(),
       context.getExecutionId(),
       context.getPhase());
   long start = System.currentTimeMillis();
   try {
     if (skipFlows.contains(context.getFlowId())) {
       YSLOG.info(
           "I03002",
           context.getBatchId(),
           context.getFlowId(),
           context.getExecutionId(),
           context.getPhase());
       return;
     }
     List<? extends Job> jobs;
     ErrorHandler handler;
     switch (context.getPhase()) {
       case SETUP:
         jobs = buildSetupJobs(context);
         handler = JobScheduler.STRICT;
         break;
       case CLEANUP:
         jobs = buildCleanupJobs(context);
         handler = JobScheduler.BEST_EFFORT;
         break;
       case FINALIZE:
         jobs = buildExecutionJobs(context, executions);
         handler = JobScheduler.BEST_EFFORT;
         break;
       default:
         jobs = buildExecutionJobs(context, executions);
         handler = JobScheduler.STRICT;
         break;
     }
     PhaseMonitor monitor = obtainPhaseMonitor(context);
     try {
       scheduler.execute(monitor, context, jobs, handler);
     } finally {
       monitor.close();
     }
     YSLOG.info(
         "I03001",
         context.getBatchId(),
         context.getFlowId(),
         context.getExecutionId(),
         context.getPhase());
   } catch (IOException e) {
     YSLOG.error(
         e,
         "E03001",
         context.getBatchId(),
         context.getFlowId(),
         context.getExecutionId(),
         context.getPhase());
     throw e;
   } catch (InterruptedException e) {
     YSLOG.warn(
         e,
         "W03001",
         context.getBatchId(),
         context.getFlowId(),
         context.getExecutionId(),
         context.getPhase());
     throw e;
   } finally {
     long end = System.currentTimeMillis();
     YSLOG.info(
         "I03999",
         context.getBatchId(),
         context.getFlowId(),
         context.getExecutionId(),
         context.getPhase(),
         end - start);
   }
 }