001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.contentanalysis.reference;
017
018import java.io.IOException;
019import java.io.InputStream;
020
021import org.apache.commons.io.IOUtils;
022import org.apache.log4j.Logger;
023
024import service.tut.pori.contentanalysis.Definitions;
025import service.tut.pori.contentanalysis.PhotoTaskResponse;
026import core.tut.pori.http.Response;
027import core.tut.pori.http.annotations.HTTPMethodParameter;
028import core.tut.pori.http.annotations.HTTPService;
029import core.tut.pori.http.annotations.HTTPServiceMethod;
030import core.tut.pori.http.parameters.DataGroups;
031import core.tut.pori.http.parameters.InputStreamParameter;
032import core.tut.pori.http.parameters.IntegerParameter;
033import core.tut.pori.http.parameters.Limits;
034import core.tut.pori.http.parameters.LongParameter;
035import core.tut.pori.utils.XMLFormatter;
036
037/**
038 * 
039 * Reference implementation for Server APIs.
040 * 
041 * <h1>Implementation Service path {@value service.tut.pori.contentanalysis.Definitions#SERVICE_CA}</h1>
042 * 
043 * @see service.tut.pori.contentanalysis.ContentAnalysisService
044 *
045 */
046@HTTPService(name = service.tut.pori.contentanalysis.reference.Definitions.SERVICE_CA_REFERENCE_SERVER)
047public class ServerService {
048  private static final Logger LOGGER = Logger.getLogger(ServerService.class);
049  private XMLFormatter _formatter = new XMLFormatter();
050  
051  /**
052   * The request is to be sent in the body of POST method. The Content-Type header MUST be set to "text/xml". The character set MUST be UTF-8. For example, "Content-Type: text/xml; charset=UTF-8".
053   * 
054   * The method can be called multiple times by the back-ends. Each call is assumed to be an incremental update on the previous one and can contain any amount of new information. 
055   * It is also possible to update previously submitted data by using the same identifiers: photo GUID (for photos), and media object id or a combination of back-end id and object id (for media objects).
056   * 
057   * Task results may contain photo specific back-end status information, though it is not required.
058   * 
059   * Using an invalid back-end id (both for the task and the generated media objects) can result in an error, causing the entire task result to be rejected. It is not allowed for a one back-end to update/modify media objects previously submitted by another back-end, or by the user.
060   * 
061   * <h2>Example Query:</h2>
062   *
063   * POST /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_SERVER}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_TASK_FINISHED}<br>
064   * Content-Type: text/xml; charset=UTF-8<br><br>
065   *
066   * <b>[HTTP BODY STARTS]</b><br>
067   * 
068   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_RESULTS]" type="GET" query="" body_uri=""} <br>
069   * 
070   * <b>[HTTP BODY ENDS]</b><br>
071   *
072   * <h2>Example Result:</h2>
073   * 
074   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_SERVER]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_TASK_FINISHED]" type="POST" query="" body_uri="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]/[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_RESULTS]"}
075   * 
076   * @param xml Only the result data should be in the body. See {@link service.tut.pori.contentanalysis.PhotoTaskResponse}
077   */
078  @HTTPServiceMethod(name = Definitions.METHOD_TASK_FINISHED, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST})
079  public void taskFinished(@HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml) {
080    try {
081      String body = IOUtils.toString(xml.getValue()); // read the body
082      LOGGER.debug(body); // print to debug
083      try(InputStream input = IOUtils.toInputStream(body)){ // convert back to stream for unmarshal
084        CAReferenceCore.taskFinished(_formatter.toObject(input, PhotoTaskResponse.class));
085      }
086    } catch (IOException ex) {
087      LOGGER.error(ex, ex);
088    }
089  }
090  
091  /**
092   * This method can be used to retrieve the up-to-date details and progress of a previously scheduled task.
093   * 
094   * <h2>Example Query:</h2>
095   *
096   * GET /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_SERVER}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_QUERY_TASK_DETAILS}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_TASK_ID}=1&amp;{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_BACKEND_ID}=1<br>
097   *
098   * <h2>Example Result:</h2>
099   * 
100   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_SERVER]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_QUERY_TASK_DETAILS]" type="GET" query="[service.tut.pori.contentanalysis.Definitions#PARAMETER_TASK_ID]=1&[service.tut.pori.contentanalysis.Definitions#PARAMETER_BACKEND_ID]=1" body_uri=""}
101   * 
102   * @param taskId
103   * @param backendId used to provide custom task details for specific back-ends
104   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(core.tut.pori.http.parameters.AuthenticationParameter, DataGroups, Limits, core.tut.pori.http.parameters.IntegerParameter, core.tut.pori.http.parameters.StringParameter)}.
105   * @param limits paging limits
106   * @return response
107   */
108  @HTTPServiceMethod(name = Definitions.METHOD_QUERY_TASK_DETAILS, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
109  public Response queryTaskDetails(
110      @HTTPMethodParameter(name = Definitions.PARAMETER_BACKEND_ID) IntegerParameter backendId,
111      @HTTPMethodParameter(name = Definitions.PARAMETER_TASK_ID) LongParameter taskId,
112      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
113      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits
114      ) 
115  {
116    return CAReferenceCore.queryTaskDetails(backendId.getValue(), taskId.getValue(), dataGroups, limits);
117  }
118}