From 40375a25ef7a64d81badd6a1b59a15b4bbac8b0e Mon Sep 17 00:00:00 2001 From: Florian Reisecker Date: Tue, 24 May 2016 16:34:30 +0200 Subject: [PATCH 1/2] Add README.md from description of offical site --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4451d2 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Apache JBatch +Apache BatchEE is a project providing an implementation of JBatch (aka jsr-352) and a set of useful extension for this specification. + +The JBatch implementation is based on a fork of the Reference Implementation provided by IBM but it has now a set of enhancements. + +## Get started + +To learn more about BatchEE you can visit its [modules page](http://batchee.incubator.apache.org/modules.html). + +If you want to learn about JBatch extensions please visit our [extensions page](http://batchee.incubator.apache.org/extensions.html). + +If you are more interested in a GUI solution, have a look to [gui](http://batchee.incubator.apache.org/gui.html) page. + +Finally if you want to control your batches from Maven just open the maven plugin page. \ No newline at end of file From 607d904d69a9cb5f2f6d52def6065ae2d4d691ca Mon Sep 17 00:00:00 2001 From: Florian Reisecker Date: Wed, 8 Jun 2016 14:13:38 +0200 Subject: [PATCH 2/2] BATCHEE-99 add batch metrics to simplerest Ensure proper column of values even if metrics are not received in correct quantity and order. --- .../batchee/servlet/SimpleRestController.java | 103 ++++++++++++++++-- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/SimpleRestController.java b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/SimpleRestController.java index b86239f..41dc6d1 100644 --- a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/SimpleRestController.java +++ b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/SimpleRestController.java @@ -16,12 +16,6 @@ */ package org.apache.batchee.servlet; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Map; -import java.util.Properties; - import javax.batch.operations.JobExecutionAlreadyCompleteException; import javax.batch.operations.JobExecutionNotRunningException; import javax.batch.operations.JobOperator; @@ -29,20 +23,37 @@ import javax.batch.operations.NoSuchJobExecutionException; import javax.batch.runtime.BatchStatus; import javax.batch.runtime.JobExecution; +import javax.batch.runtime.Metric; +import javax.batch.runtime.StepExecution; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; /** * Simple REST api for JBatch */ public class SimpleRestController { public static final String REST_CONTENT_TYPE = "text/plain"; + public static final String NOT_FOUND_STRING = "-"; + public static final char CSV_DELIMITER = ';'; public static final String OP_START = "start/"; public static final String OP_STATUS = "status/"; + public static final String OP_METRICS = "metrics/"; + public static final String OP_STOP = "stop/"; public static final String OP_RESTART = "restart/"; - public static final long NO_JOB_ID = -1L; private final JobOperator jobOperator; @@ -62,6 +73,8 @@ public void dispatch(HttpServletRequest req, HttpServletResponse resp, String pa startBatch(path.substring(OP_START.length()), req, resp); } else if (path != null && path.startsWith(OP_STATUS)) { batchStatus(path.substring(OP_STATUS.length()), req, resp); + } else if (path != null && path.startsWith(OP_METRICS)) { + batchMetrics(path.substring(OP_METRICS.length()), req, resp); } else if (path != null && path.startsWith(OP_STOP)) { batchStop(path.substring(OP_STOP.length()), req, resp); } else if (path != null && path.startsWith(OP_RESTART)) { @@ -106,6 +119,28 @@ private void batchStatus(String batchId, HttpServletRequest req, HttpServletResp } } + private void batchMetrics(String batchId, HttpServletRequest req, HttpServletResponse resp) { + Long executionId = extractExecutionId(batchId, resp); + if (executionId == null) { + return; + } + + try { + JobExecution jobExecution = jobOperator.getJobExecution(executionId); + BatchStatus batchStatus = jobExecution.getBatchStatus(); + + List stepExecutions = jobOperator.getStepExecutions(executionId); + reportSuccess(executionId, resp, batchStatus.name()); + reportMetricsCsv(resp, stepExecutions); + } catch (NoSuchJobExecutionException noSuchJob) { + reportFailure(executionId, resp, "NoSuchJob"); + } catch (Exception generalException) { + StringBuilder msg = new StringBuilder("Failure in BatchExecution"); + appendExceptionMsg(msg, generalException); + reportFailure(executionId, resp, msg.toString()); + } + } + private void batchStop(String batchId, HttpServletRequest req, HttpServletResponse resp) { Long executionId = extractExecutionId(batchId, resp); if (executionId == null) { @@ -166,6 +201,10 @@ private void unknownCommand(String path, HttpServletResponse resp) { msg.append(" Sample: http://localhost:8080/myapp/jbatch/rest/status/23\n"); msg.append(" will return the state of executionId 23\n\n"); + msg.append("* ").append(OP_METRICS).append(" - query the current metrics \n"); + msg.append(" Sample: http://localhost:8080/myapp/jbatch/rest/metrics/23\n"); + msg.append(" will return the metrics of executionId 23\n\n"); + msg.append("* ").append(OP_STOP).append(" - stop the job with the given executionId \n"); msg.append(" Sample: http://localhost:8080/myapp/jbatch/rest/stop/23\n"); msg.append(" will stop the job with executionId 23\n\n"); @@ -228,6 +267,56 @@ private void reportFailure(long jobId, HttpServletResponse resp, String content) writeContent(resp, content); } + private void reportMetricsCsv(HttpServletResponse resp, List stepExecutions) { + StringBuilder stringBuilder = new StringBuilder(200); + stringBuilder.append("\n"); + + // append csv header to stringbuilder + joinCsv(stringBuilder, Arrays.asList("STEP_EXECUTION_ID", "STEP_NAME")); + stringBuilder.append(CSV_DELIMITER); + joinCsv(stringBuilder, Arrays.asList(Metric.MetricType.values())); + stringBuilder.append("\n"); + + Collections.sort(stepExecutions, new Comparator() { + @Override + public int compare(StepExecution o1, StepExecution o2) { + return Long.compare(o1.getStepExecutionId(), o2.getStepExecutionId()); + } + }); + // append csv values to stringbuilder, one stepExecution per line + for (StepExecution stepExecution : stepExecutions) { + stringBuilder.append(stepExecution.getStepExecutionId()); + stringBuilder.append(CSV_DELIMITER); + stringBuilder.append(stepExecution.getStepName()); + stringBuilder.append(CSV_DELIMITER); + + Metric[] metricsArray = stepExecution.getMetrics(); + Map sourceMap = new HashMap(); + for (Metric metric : metricsArray) { + sourceMap.put(metric.getType(), metric); + } + + List orderedMetricsValues = new ArrayList(); + for (Metric.MetricType type : Metric.MetricType.values()) { + orderedMetricsValues.add(sourceMap.containsKey(type) ? String.valueOf(sourceMap.get(type).getValue()) : NOT_FOUND_STRING); + } + joinCsv(stringBuilder, orderedMetricsValues); + + stringBuilder.append("\n"); + } + + writeContent(resp, stringBuilder.toString()); + } + + private void joinCsv(StringBuilder builder, List values) { + for (ListIterator iter = values.listIterator(); iter.hasNext(); ) { + builder.append(iter.next()); + if (iter.hasNext()) { + builder.append(CSV_DELIMITER); + } + } + } + private void writeContent(HttpServletResponse resp, String content) { try { resp.getWriter().append(content);