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&{@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}