Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openprovenance.prov.service.core.PostService Maven / Gradle / Ivy
package org.openprovenance.prov.service.core;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.openprovenance.prov.model.interop.ApiUriFragments;
import org.openprovenance.prov.model.interop.InteropMediaType;
import org.openprovenance.prov.log.ProvLevel;
import org.openprovenance.prov.model.exception.ParserException;
import org.openprovenance.prov.model.exception.UncheckedException;
import org.openprovenance.prov.service.core.jobs.JobManagement;
import org.openprovenance.prov.storage.api.DocumentResource;
import org.quartz.SchedulerException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import java.io.InputStream;
import java.security.Principal;
import java.util.*;
@Path("")
public class PostService implements Constants, InteropMediaType, SwaggerTags, ApiUriFragments {
static Logger logger = LogManager.getLogger(PostService.class);
private final JobManagement jobManager = new JobManagement();
private final boolean autoDelete;
public PostService(ServiceUtilsConfig config) {
this(config, new LinkedList<>(), Optional.empty());
}
public JobManagement getJobManager() {
return jobManager;
}
final protected ServiceUtils utils;
private final List performers;
private Optional otherPerformer;
public static List addToList(E element, List list) {
List result = new LinkedList<>();
result.add(element);
result.addAll(list);
return result;
}
public PostService(ServiceUtilsConfig config, List performers, Optional otherPerformer) {
utils = new ServiceUtils(this, config);
this.autoDelete = config.autoDelete;
jobManager.setupScheduler();
try {
JobManagement.getScheduler().getContext().put(JobManagement.UTILS_KEY, utils);
JobManagement.getScheduler().getContext().put(JobManagement.DURATION_KEY, config.deletePeriod);
} catch (SchedulerException e) {
logger.throwing(e);
}
this.performers = performers;
this.otherPerformer = otherPerformer;
}
public ServiceUtils getServiceUtils() {
return utils;
}
public void addToPerformers(List newPerformers) {
performers.addAll(newPerformers);
}
public void addOtherPerformer(Optional newOtherPerformer) {
otherPerformer = newOtherPerformer;
}
public Map addToConfiguration(String property, Object value) {
this.configuration.put(property, value);
return this.configuration;
}
public Map getConfiguration() {
return configuration;
}
private final Map configuration=new HashMap<>();
@POST
@Path(FRAGMENT_DOCUMENTS_FORM)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Tag(name = DOCUMENTS)
@Operation(summary = "Post a document. Payload is a form that may contain a file, prov statements or a url",
description = "Post a document in a form; indicate if validation or translation required; and redirects to the appropriate page. This method is also designed for browser interaction, allowing the user to select a file, a url or statements for provenance. The user may specify validate or translate directly.",
responses = {@ApiResponse(responseCode = "303",
headers = @Header(name = "location", description = "Location of posted document"),
description = "See other url for serialization of posted resource as requested by accept header."),
@ApiResponse(responseCode = "404", description = "Provenance not found")})
public Response submit(@Parameter(name = "form",
description = "form to be posted",
required = true,
schema = @Schema(implementation = UploadForm.class))
MultipartFormDataInput input,
@Context HttpHeaders headers,
@Context HttpServletRequest ignoredRequestContext) {
MediaType mediaType = headers.getMediaType();
Principal principal = ignoredRequestContext.getUserPrincipal();
logger.info("principal is " + principal);
if (mediaType.toString().startsWith("multipart/form-data")) {
try {
Map> formData = input.getFormDataMap();
logger.debug("submitted " + formData);
DocumentResource vr;
vr = processFileInForm(formData);
if (vr == null) vr = processUrlInForm(formData);
if (vr == null) vr = processStatementsInForm(formData);
boolean success = utils.doProcessFile(vr, true);
if (vr == null) {
String result = "No provenance was found, and therefore failed to create resource for validation service";
return utils.composeResponseNotFOUND(result);
}
if (!success) {
String result = "Failed to parse provenance";
return utils.composeResponseBadRequest(result, vr.getThrown());
}
if (/*vr.bundle == null && */ !utils.documentCache.containsKey(vr.getStorageId())) { //TODO: what about bundle?
String result = "No provenance was found (empty document), and therefore failed to create resource for validation service";
return utils.composeResponseNotFOUND(result);
}
Date date = autoDelete ? jobManager.scheduleJob(vr.getVisibleId()) : null;
vr.setExpires(date);
final ServiceUtils.Action action = utils.getAction(formData);
doLog(action, vr);
logger.debug("trying performers " + performers);
for (ActionPerformer performer : performers) {
logger.debug("trying performer " + performer.getAction());
if (performer.getAction().equals(action)) {
logger.debug("invoking performer " + performer.getAction());
return performer.doAction(formData, vr, date);
}
}
logger.debug("checking other performer ");
if (otherPerformer.isPresent() && otherPerformer.get().otherAction(action, formData)) {
logger.debug("invoking other performer ");
return otherPerformer.get().doAction(action, formData, vr, date);
}
//default
String location = "view/documents/" + vr.getVisibleId() + "/translation.html";
// alternatively, go to document the landing page
return utils.composeResponseSeeOther(location).header("Expires", date).build();
} catch (UncheckedException e) {
return utils.composeResponseBadRequest("URI problem (" + e.getCause() + ")", e);
} catch (ParserException e) {
return utils.composeResponseBadRequest("Parser problem", e);
} catch (Throwable t) {
logger.throwing(t);
String result = "exception occurred";
return utils.composeResponseInternalServerError(result, t);
}
} else {
String result = "Media type " + mediaType + " Not Supported yet";
return utils.composeResponseNotFOUND(result);
}
}
@POST
@Path(FRAGMENT_DOCUMENTS)
@Tag(name = DOCUMENTS)
@Consumes({
MEDIA_TEXT_TURTLE, MEDIA_TEXT_PROVENANCE_NOTATION,
MEDIA_APPLICATION_PROVENANCE_XML, MEDIA_APPLICATION_JSON})
@Operation(
summary = "Post a document, directly, creates a resource, supports content negotiation, redirects to URL providing serialization for the resource",
description = "It supports the direct posting of documents using a prov serialization.",
responses = {
@ApiResponse(
responseCode = "200",
//headers=@Header(name="location",description="Location of posted document"),
content = {
@Content(mediaType = MEDIA_TEXT_TURTLE),
@Content(mediaType = MEDIA_TEXT_PROVENANCE_NOTATION),
@Content(mediaType = MEDIA_APPLICATION_PROVENANCE_XML),
@Content(mediaType = MEDIA_APPLICATION_JSON)}),
@ApiResponse(
responseCode = "303",
headers = @Header(name = "location", description = "Location of posted document"),
description = "See other url for serialization of posted resource as requested by accept header."),
@ApiResponse(
responseCode = "404", description = "Provenance not found")})
public Response submit2(@Parameter(name = "input",
description = "input file in a prov serialization",
example = "document\n prefix ex \n entity(ex:e)\nendDocument") InputStream input,
@Context HttpHeaders headers,
//@Context HttpServletRequest requestContext,
@Context Request request) {
MediaType mediaType = headers.getMediaType();
String type = mediaType.getType() + "/" + mediaType.getSubtype();
logger.debug(">>> post media type is " + type);
logger.debug("accept header is" + headers.getAcceptableMediaTypes());
DocumentResource vr = utils.doProcessFile(input, type);
Date date = jobManager.scheduleJob(vr.getVisibleId());
vr.setExpires(date);
// TODO: maybe not return content directly
if (true) {
return utils.contentNegotiationForDocument(request, vr.getVisibleId(), ".");
}
return utils.composeResponseSeeOther("documents/" + vr.getVisibleId()).header("Expires", date).build();
}
@GET
@Path(FRAGMENT_CONFIGURATION)
@Tag(name = "configuration")
@Operation(
summary = "Get configuration",
description = "Get configuration",
responses = {
@ApiResponse(
responseCode = "200",
content = {
@Content(mediaType = MEDIA_APPLICATION_JSON)})})
public Response getConfiguration(@Context HttpHeaders headers) {
StreamingOutput promise= out -> new ObjectMapper().writeValue(out, configuration);
return ServiceUtils.composeResponseOK(promise).type(InteropMediaType.MEDIA_APPLICATION_JSON).build();
}
private DocumentResource processFileInForm(Map> formData) {
DocumentResource vr = null;
List inputParts = formData.get("file");
if ((inputParts != null)) {
vr = utils.doProcessFileForm(inputParts);
}
return vr;
}
private DocumentResource processUrlInForm(Map> formData) {
DocumentResource vr = null;
List inputParts = formData.get("url");
if (inputParts != null) {
vr = utils.doProcessURLForm(inputParts);
}
return vr;
}
private DocumentResource processStatementsInForm(Map> formData) {
DocumentResource vr = null;
List inputParts = formData.get("statements");
List type = formData.get("type");
if (inputParts != null) {
vr = utils.doProcessStatementsForm(inputParts, type);
}
return vr;
}
private void doLog(ServiceUtils.Action action, DocumentResource vr) {
doLog(action.toString(), vr);
}
private void doLog(String action, DocumentResource vr) {
logger.log(ProvLevel.PROV,
action + ","
+ vr.getVisibleId() + ","
+ vr.getStorageId());
}
}