Skip to content
Permalink
Browse files
BATCHEE-98 try to find not ran jobs for embedded servlet mode
  • Loading branch information
rmannibucau committed Mar 11, 2016
1 parent 987e713 commit f08eead0c06749023aa5726fe67e8a2492b2dc2a
Showing 2 changed files with 97 additions and 3 deletions.
@@ -30,19 +30,28 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JBatchController extends HttpServlet {
private static final String DEFAULT_MAPPING_SERVLET25 = "/jbatch";
@@ -64,6 +73,8 @@ public class JBatchController extends HttpServlet {
private String mapping = DEFAULT_MAPPING_SERVLET25;
private int executionByPage = DEFAULT_PAGE_SIZE;
private boolean readOnly = false;
private boolean defaultScan = false;
private final Set<String> appBatches = new HashSet<String>();

public JBatchController mapping(final String rawMapping) {
this.mapping = rawMapping.substring(0, rawMapping.length() - 2); // mapping pattern is /xxx/*
@@ -80,6 +91,11 @@ public JBatchController readOnly(final boolean readOnly) {
return this;
}

public JBatchController defaultScan(final boolean defaultScan) {
this.defaultScan = defaultScan;
return this;
}

@Override
public void init(final ServletConfig config) throws ServletException {
this.operator = BatchRuntime.getJobOperator();
@@ -91,8 +107,33 @@ public void init(final ServletConfig config) throws ServletException {

mapping = context + mapping;
this.simpleRestController = new SimpleRestController(operator);

// this is not perfect but when it works it list jobs not executed yet which is helpful
// try to find not yet started jobs
if (defaultScan) {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final Enumeration<URL> resources;
try {
resources = loader.getResources("META-INF/batch-jobs");
} catch (final IOException e) {
return;
}
while (resources.hasMoreElements()) {
final URL url = resources.nextElement();
final File file = toFile(url);

if (file != null) {
if (file.isDirectory()) {
findInDirectory(file);
} else {
findInJar(file);
}
}
}
}
}


@Override
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
@@ -244,9 +285,10 @@ private void listExecutions(final HttpServletRequest req, final String name, fin
}

private void listJobs(final HttpServletRequest req) throws ServletException, IOException {
Set<String> names = operator.getJobNames();
if (names == null) {
names = Collections.emptySet();
final Set<String> names = new HashSet<String>(appBatches);
final Set<String> registered = operator.getJobNames();
if (registered != null) {
names.addAll(registered);
}

req.setAttribute("view", "jobs");
@@ -284,6 +326,56 @@ private static Properties readProperties(final HttpServletRequest req) {
return properties;
}

private Collection<String> findInJar(final File file) {
final Pattern pattern = Pattern.compile("META\\-INF/batch-jobs/\\(*\\).xml");
final JarFile jar;
try {
jar = new JarFile(file);
} catch (final IOException e) {
return Collections.emptySet();
}
final Enumeration<JarEntry> entries = jar.entries();
final Collection<String> values = new HashSet<String>();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
final Matcher matcher = pattern.matcher(entry.getName());
if (matcher.matches()) {
values.add(matcher.group(1));
}
}
return values;
}

private Collection<String> findInDirectory(final File file) {
final String[] batches = file.list(new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.endsWith(".xml");
}
});
if (batches != null) {
final Collection<String> values = new HashSet<String>();
for (final String batch : batches) {
values.add(batch.substring(0, batch.length() - ".xml".length()));
}
return values;
}
return Collections.emptySet();
}

private static File toFile(final URL url) {
final File file;
final String externalForm = url.toExternalForm();
if ("jar".equals(url.getProtocol())) {
file = new File(externalForm.substring("jar:".length(), externalForm.lastIndexOf('!')));
} else if ("file".equals(url.getProtocol())) {
file = new File(externalForm.substring("file:".length()));
} else {
file = null;
}
return file;
}

private static class JobInstanceIdComparator implements java.util.Comparator<JobInstance> {
private static final JobInstanceIdComparator INSTANCE = new JobInstanceIdComparator();

@@ -35,6 +35,7 @@
public class JBatchServletInitializer implements ServletContainerInitializer {
public static final String ACTIVE = "org.apache.batchee.servlet.active";
public static final String CONTROLLER_MAPPING = "org.apache.batchee.servlet.mapping";
public static final String DEFAULT_SCANNING = "org.apache.batchee.servlet.scan";
public static final String ACTIVE_PRIVATE_FILTER = "org.apache.batchee.servlet.filter.private";
public static final String BY_PAGE = "org.apache.batchee.servlet.pagination";

@@ -63,6 +64,7 @@ public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) thr

ctx.addServlet("JBatch Servlet", new JBatchController()
.readOnly(false)
.defaultScan(Boolean.parseBoolean(ctx.getInitParameter(DEFAULT_SCANNING)))
.mapping(mapping)
.executionByPage(Integer.parseInt(byPage)))
.addMapping(mapping);

0 comments on commit f08eead

Please sign in to comment.