/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.stanbol.reasoners.web.resources; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import javax.ws.rs.GET; import javax.ws.rs.OPTIONS; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.apache.stanbol.commons.jobs.api.JobManager; import org.apache.stanbol.commons.web.viewable.Viewable; import org.apache.stanbol.commons.web.base.resource.BaseStanbolResource; import org.apache.stanbol.reasoners.web.utils.ReasoningServiceResult; import org.apache.stanbol.reasoners.web.utils.ResponseTaskBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Return the result of a reasoners background job * * @author enridaga * */ @Component @Service(Object.class) @Property(name="javax.ws.rs", boolValue=true) @Path("/reasoners/jobs") public class JobsResource extends BaseStanbolResource { private Logger log = LoggerFactory.getLogger(getClass()); private String jobLocation = ""; @Reference private JobManager jobManager; public JobsResource() { } /** * To read a /reasoners job output. * * @param id * @return */ @GET @Path("/{jid}") public Response get(@PathParam("jid") String id, @Context HttpHeaders headers) { log.info("Pinging job {}", id); // No id if(id == null || id.equals("")){ ResponseBuilder rb = Response.status(Status.BAD_REQUEST); return rb.build(); } JobManager m = getJobManager(); // If the job exists if (m.hasJob(id)) { log.info("Found job with id {}", id); Future<?> f = m.ping(id); if(f.isDone() && (!f.isCancelled())){ /** * We return OK with the result */ Object o; try { o = f.get(); if(o instanceof ReasoningServiceResult){ log.debug("Is a ReasoningServiceResult"); ReasoningServiceResult<?> result = (ReasoningServiceResult<?>) o; return new ResponseTaskBuilder(new JobResultResource(uriInfo, headers)).build(result); }else{ log.error("Job {} does not belong to reasoners", id); throw new WebApplicationException(Response.Status.NOT_FOUND); } } catch (InterruptedException e) { log.error("Error: ",e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (ExecutionException e) { log.error("Error: ",e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } }else{ /** * We return 404 with additional info */ String jobService = new StringBuilder().append(getPublicBaseUri()).append("jobs/").append(id).toString(); this.jobLocation = jobService; Viewable viewable = new Viewable("404.ftl",this); ResponseBuilder rb = Response.status(Status.NOT_FOUND); rb.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML+ "; charset=utf-8"); rb.entity(viewable); return rb.build(); } } else { log.info("No job found with id {}", id); ResponseBuilder rb = Response.status(Status.NOT_FOUND); rb.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML+ "; charset=utf-8"); return rb.build(); } } /** * If the output is not ready, this field contains the location of the job to be rendered in the viewable. * * @return */ public String getJobLocation(){ return this.jobLocation; } /** * Gets the job manager * * @return */ private JobManager getJobManager() { log.debug("(getJobManager()) "); return jobManager; } @OPTIONS public Response handleCorsPreflight() { ResponseBuilder rb = Response.ok(); return rb.build(); } public class JobResultResource extends ResultData implements ReasoningResult { private Object result; private UriInfo uriInfo; private HttpHeaders headers; public JobResultResource(UriInfo uriInfo, HttpHeaders headers) { this.headers = headers; this.uriInfo = uriInfo; } public void setResult(Object result){ this.result = result; } public Object getResult() { return this.result; } public HttpHeaders getHeaders() { return headers; } public UriInfo getUriInfo(){ return uriInfo; } } }