Skip to content

Commit

Permalink
Merge pull request mapfish#501 from NielsCharlier/jobman
Browse files Browse the repository at this point in the history
JobManager: refactor, database imp, clustered imp
  • Loading branch information
Patrick Valsecchi authored Mar 1, 2017
2 parents 3cb95be + b850d0a commit 86b4a86
Show file tree
Hide file tree
Showing 49 changed files with 2,899 additions and 1,361 deletions.
8 changes: 7 additions & 1 deletion core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ dependencies {
"org.springframework:spring-web:$project.springVersion",
"org.springframework:spring-webmvc:$project.springVersion",
"org.springframework.security:spring-security-config:$springSecurityVersion",
"org.springframework.security:spring-security-web:$springSecurityVersion"
"org.springframework.security:spring-security-web:$springSecurityVersion",
//hibernate & postgres
"org.hibernate:hibernate-core:4.1.7.Final",
"org.postgresql:postgresql:9.4-1206-jdbc42",
"org.springframework:spring-orm:$project.springVersion",
"org.springframework:spring-jdbc:$project.springVersion",
"org.springframework:spring-tx:$project.springVersion"
)
def metricsVersion = "3.0.2"
metrics (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.mapfish.print;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
*
* Provides application context in static context.
*
*/
public class ApplicationContextProvider implements ApplicationContextAware {

private static ApplicationContext context;

public static ApplicationContext getApplicationContext() {
return context;
}

@Override
public final void setApplicationContext(final ApplicationContext ctx) {
context = ctx;
}
}
17 changes: 17 additions & 0 deletions core/src/main/java/org/mapfish/print/ExceptionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,21 @@ public static RuntimeException getRuntimeException(final Throwable exc) {
return new RuntimeException(exc);
}
}

/**
* Because exceptions might get re-thrown several times, an error message like
* "java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: ..."
* might get created. To avoid this, this method finds the root cause, so that only a message like
* "java.lang.IllegalArgumentException: ..." is shown.
*
* @param e A throwable.
* @return root Throwable
*/
public static Throwable getRootCause(final Throwable e) {
Throwable rootCause = e;
while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
rootCause = rootCause.getCause();
}
return rootCause;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,12 @@ public interface AccessAssertion extends ConfigurationObject {
* @param encodedAssertion the assertion encoded as JSON.
*/
void unmarshal(JSONObject encodedAssertion);

/**
* Deep copy of this access assertion.
*
* @return the copy
*/
AccessAssertion copy();

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* This assertion always allows access.
*/
public final class AlwaysAllowAssertion implements AccessAssertion {

private static final int HASH_CODE = 42;
/**
* A public instance that can be used by all resource in the default case.
*/
Expand All @@ -33,4 +35,20 @@ public void unmarshal(final JSONObject encodedAssertion) {
public void validate(final List<Throwable> validationErrors, final Configuration configuration) {
// do nothing
}

@Override
public boolean equals(final Object o) {
return o instanceof AlwaysAllowAssertion;
}

@Override
public int hashCode() {
return HASH_CODE;
}

@Override
public AccessAssertion copy() {
return new AlwaysAllowAssertion();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.mapfish.print.config.Configuration;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -86,4 +87,25 @@ public void validate(final List<Throwable> validationErrors, final Configuration
predicate.validate(validationErrors, configuration);
}
}

@Override
public boolean equals(final Object o) {
if (o instanceof AndAccessAssertion) {
return ((AndAccessAssertion) o).predicates.equals(this.predicates);
}
return false;
}

@Override
public int hashCode() {
return this.predicates.hashCode();
}

@Override
public AccessAssertion copy() {
AndAccessAssertion assertion = new AndAccessAssertion();
assertion.predicates = new ArrayList<AccessAssertion>(this.predicates);
assertion.persister = this.persister;
return assertion;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -121,4 +122,24 @@ public void validate(final List<Throwable> validationErrors, final Configuration
validationErrors.add(new ConfigurationException("requiredRoles must be defined"));
}
}

@Override
public boolean equals(final Object o) {
if (o instanceof RoleAccessAssertion) {
return ((RoleAccessAssertion) o).requiredRoles.equals(this.requiredRoles);
}
return false;
}

@Override
public int hashCode() {
return this.requiredRoles.hashCode();
}

@Override
public AccessAssertion copy() {
RoleAccessAssertion assertion = new RoleAccessAssertion();
assertion.requiredRoles = Collections.unmodifiableSet(new HashSet<String>(this.requiredRoles));
return assertion;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.mapfish.print.servlet;

import org.mapfish.print.servlet.job.FailedPrintJob;
import org.mapfish.print.servlet.job.SuccessfulPrintJob;
import org.mapfish.print.servlet.job.PrintJobStatus;
import org.mapfish.print.servlet.job.loader.ReportLoader;

import java.io.IOException;
Expand Down Expand Up @@ -40,7 +39,7 @@ public interface HandleReportLoadResult<R> {
* @param reportURI the uri to the report
* @param loader the loader for loading the report.
*/
R successfulPrint(SuccessfulPrintJob successfulPrintResult, HttpServletResponse httpServletResponse, URI reportURI,
R successfulPrint(PrintJobStatus successfulPrintResult, HttpServletResponse httpServletResponse, URI reportURI,
ReportLoader loader) throws IOException, ServletException;

/**
Expand All @@ -49,7 +48,7 @@ R successfulPrint(SuccessfulPrintJob successfulPrintResult, HttpServletResponse
* @param failedPrintJob the failed print job
* @param httpServletResponse the object for writing response
*/
R failedPrint(FailedPrintJob failedPrintJob, HttpServletResponse httpServletResponse);
R failedPrint(PrintJobStatus failedPrintJob, HttpServletResponse httpServletResponse);

/**
* Called when the print job has not yet completed.
Expand Down
63 changes: 24 additions & 39 deletions core/src/main/java/org/mapfish/print/servlet/MapPrinterServlet.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.mapfish.print.servlet;

import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.io.Files;

Expand All @@ -14,21 +13,17 @@
import org.mapfish.print.MapPrinter;
import org.mapfish.print.MapPrinterFactory;
import org.mapfish.print.config.Template;
import org.mapfish.print.servlet.job.FailedPrintJob;
import org.mapfish.print.servlet.job.JobManager;
import org.mapfish.print.servlet.job.JobStatus;
import org.mapfish.print.servlet.job.NoSuchReferenceException;
import org.mapfish.print.servlet.job.PrintJob;
import org.mapfish.print.servlet.job.PrintJobStatus;
import org.mapfish.print.servlet.job.SuccessfulPrintJob;
import org.mapfish.print.servlet.job.impl.PrintJobEntryImpl;
import org.mapfish.print.servlet.job.loader.ReportLoader;
import org.mapfish.print.wrapper.json.PJsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
Expand Down Expand Up @@ -195,7 +190,6 @@ public class MapPrinterServlet extends BaseMapServlet {
@Autowired
private ServletInfo servletInfo;


private long maxCreateAndGetWaitTimeInSeconds;
@Autowired
private MapPrinterFactory mapPrinterFactory;
Expand Down Expand Up @@ -241,7 +235,7 @@ public final void getStatus(
final HttpServletResponse statusResponse) {
PrintWriter writer = null;
try {
JobStatus status = this.jobManager.getStatus(referenceId);
PrintJobStatus status = this.jobManager.getStatus(referenceId);

setContentType(statusResponse, jsonpCallback);
writer = statusResponse.getWriter();
Expand Down Expand Up @@ -399,14 +393,14 @@ public Void unsupportedLoader(final HttpServletResponse httpServletResponse, fin
}

@Override
public Void successfulPrint(final SuccessfulPrintJob successfulPrintResult, final HttpServletResponse httpServletResponse,
public Void successfulPrint(final PrintJobStatus successfulPrintResult, final HttpServletResponse httpServletResponse,
final URI reportURI, final ReportLoader loader) throws IOException, ServletException {
sendReportFile(successfulPrintResult, httpServletResponse, loader, reportURI, inline);
return null;
}

@Override
public Void failedPrint(final FailedPrintJob failedPrintJob, final HttpServletResponse httpServletResponse) {
public Void failedPrint(final PrintJobStatus failedPrintJob, final HttpServletResponse httpServletResponse) {
error(httpServletResponse, failedPrintJob.getError(), HttpStatus.INTERNAL_SERVER_ERROR);
return null;
}
Expand Down Expand Up @@ -477,15 +471,15 @@ public Boolean unsupportedLoader(final HttpServletResponse httpServletResponse,
}

@Override
public Boolean successfulPrint(final SuccessfulPrintJob successfulPrintResult,
public Boolean successfulPrint(final PrintJobStatus successfulPrintResult,
final HttpServletResponse httpServletResponse,
final URI reportURI, final ReportLoader loader) throws IOException, ServletException {
sendReportFile(successfulPrintResult, httpServletResponse, loader, reportURI, inline);
return true;
}

@Override
public Boolean failedPrint(final FailedPrintJob failedPrintJob, final HttpServletResponse httpServletResponse) {
public Boolean failedPrint(final PrintJobStatus failedPrintJob, final HttpServletResponse httpServletResponse) {
error(httpServletResponse, failedPrintJob.getError(), HttpStatus.INTERNAL_SERVER_ERROR);
return true;
}
Expand Down Expand Up @@ -790,15 +784,15 @@ public final void setMaxCreateAndGetWaitTimeInSeconds(final long maxCreateAndGet
* @param reportURI the uri of the report
* @param inline whether or not to inline the content
*/
protected final void sendReportFile(final SuccessfulPrintJob metadata, final HttpServletResponse httpServletResponse,
protected final void sendReportFile(final PrintJobStatus metadata, final HttpServletResponse httpServletResponse,
final ReportLoader reportLoader, final URI reportURI, final boolean inline)
throws IOException, ServletException {

final OutputStream response = httpServletResponse.getOutputStream();
try {
httpServletResponse.setContentType(metadata.getMimeType());
httpServletResponse.setContentType(metadata.getResult().getMimeType());
if (!inline) {
String fileName = metadata.getFileName();
String fileName = metadata.getResult().getFileName();
Matcher matcher = VARIABLE_PATTERN.matcher(fileName);
while (matcher.find()) {
final String variable = matcher.group(1);
Expand All @@ -807,7 +801,7 @@ protected final void sendReportFile(final SuccessfulPrintJob metadata, final Htt
matcher = VARIABLE_PATTERN.matcher(fileName);
}

fileName += "." + metadata.getFileExtension();
fileName += "." + metadata.getResult().getFileExtension();
httpServletResponse.setHeader("Content-disposition", "attachment; filename=" + cleanUpName(fileName));
}
reportLoader.loadReport(reportURI, response);
Expand Down Expand Up @@ -920,43 +914,37 @@ public final String createAndSubmitPrintJob(final String appId, final String for
}
String ref = UUID.randomUUID().toString() + "@" + this.servletInfo.getServletId();

PrintJob job = this.context.getBean(PrintJob.class);

job.setReferenceId(ref);
job.setRequestData(specJson);
job.setSecurityContext(SecurityContextHolder.getContext());
job.setCreateTime(System.currentTimeMillis());

// check that we have authorization and configure the job so it can only be access by users with sufficient authorization
final String templateName = specJson.getString(Constants.JSON_LAYOUT_KEY);
final MapPrinter mapPrinter = this.mapPrinterFactory.create(appId);
final Template template = mapPrinter.getConfiguration().getTemplate(templateName);
job.configureAccess(template);


PrintJobEntryImpl jobEntry = new PrintJobEntryImpl(ref, specJson, System.currentTimeMillis());
jobEntry.configureAccess(template, this.context);

try {
this.jobManager.submit(job);
this.jobManager.submit(jobEntry);
} catch (RuntimeException exc) {
LOGGER.error("Error when creating job", exc);
ref = null;
}
return ref;
}

private <R> R loadReport(final String referenceId, final HttpServletResponse httpServletResponse,
final HandleReportLoadResult<R> handler) throws IOException, ServletException {
Optional<? extends PrintJobStatus> metadata;
PrintJobStatus metadata;

try {
metadata = this.jobManager.getCompletedPrintJob(referenceId);
metadata = this.jobManager.getStatus(referenceId);
} catch (NoSuchReferenceException e) {
return handler.unknownReference(httpServletResponse, referenceId);
}

if (!metadata.isPresent()) {
if (!metadata.isDone()) {
return handler.printJobPending(httpServletResponse, referenceId);
} else if (metadata.get() instanceof SuccessfulPrintJob) {
SuccessfulPrintJob successfulPrintJob = (SuccessfulPrintJob) metadata.get();
URI pdfURI = successfulPrintJob.getURI();
} else if (metadata.getResult() != null) {
URI pdfURI = metadata.getResult().getReportURI();

ReportLoader loader = null;
for (ReportLoader reportLoader : this.reportLoaders) {
Expand All @@ -968,14 +956,11 @@ private <R> R loadReport(final String referenceId, final HttpServletResponse htt
if (loader == null) {
return handler.unsupportedLoader(httpServletResponse, referenceId);
} else {
return handler.successfulPrint(successfulPrintJob, httpServletResponse, pdfURI, loader);
return handler.successfulPrint(metadata, httpServletResponse, pdfURI, loader);
}
} else if (metadata.get() instanceof FailedPrintJob) {
FailedPrintJob failedPrintJob = (FailedPrintJob) metadata.get();
return handler.failedPrint(failedPrintJob, httpServletResponse);
} else {
throw new ServletException("Unexpected state");
}
return handler.failedPrint(metadata, httpServletResponse);
}

}

Expand Down
Loading

0 comments on commit 86b4a86

Please sign in to comment.