001/** 002 * Copyright 2016 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.apilta.sensors.reference; 017 018import java.io.IOException; 019import java.io.InputStream; 020 021import org.apache.commons.io.IOUtils; 022import org.apache.log4j.Logger; 023 024import core.tut.pori.http.Response; 025import core.tut.pori.http.annotations.HTTPAuthenticationParameter; 026import core.tut.pori.http.annotations.HTTPMethodParameter; 027import core.tut.pori.http.annotations.HTTPService; 028import core.tut.pori.http.annotations.HTTPServiceMethod; 029import core.tut.pori.http.parameters.AuthenticationParameter; 030import core.tut.pori.http.parameters.DataGroups; 031import core.tut.pori.http.parameters.InputStreamParameter; 032import core.tut.pori.http.parameters.Limits; 033import core.tut.pori.http.parameters.StringParameter; 034import core.tut.pori.utils.XMLFormatter; 035import service.tut.pori.apilta.sensors.datatypes.SensorTask; 036 037/** 038 * 039 * Reference implementation for Back-end APIs 040 * 041 */ 042@HTTPService(name = Definitions.SERVICE_SENSORS_REFERENCE_BACKEND) 043public class BackendService { 044 private static final Logger LOGGER = Logger.getLogger(BackendService.class); 045 private XMLFormatter _formatter = new XMLFormatter(); 046 047 /** 048 * 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". 049 * 050 * <h2>Example Query:</h2> 051 * 052 * POST /rest/{@value service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_BACKEND}/{@value service.tut.pori.tasks.Definitions#METHOD_ADD_TASK}<br> 053 * Content-Type: text/xml; charset=UTF-8<br><br> 054 * 055 * <b>[HTTP BODY STARTS]</b><br> 056 * 057 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_EXAMPLE]" method="[service.tut.pori.tasks.Definitions#ELEMENT_TASK]" type="GET" query="" body_uri=""} <br> 058 * 059 * <b>[HTTP BODY ENDS]</b><br> 060 * 061 * <h2>Example Result:</h2> 062 * 063 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_BACKEND]" method="[service.tut.pori.tasks.Definitions#METHOD_ADD_TASK]" type="POST" query="" body_uri="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_EXAMPLE]/[service.tut.pori.tasks.Definitions#ELEMENT_TASK]"} 064 * 065 * @param authenticatedUser 066 * @param xml Only the workload data should be in the body. See {@link service.tut.pori.apilta.sensors.datatypes.SensorTask} 067 */ 068 @HTTPServiceMethod(name = service.tut.pori.tasks.Definitions.METHOD_ADD_TASK, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST}) 069 public void addTask ( 070 @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser, 071 @HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml 072 ) 073 { 074 try { 075 String body = IOUtils.toString(xml.getValue(), core.tut.pori.http.Definitions.CHARSET_UTF8); // read the body 076 LOGGER.debug(body); // print to debug 077 try(InputStream input = IOUtils.toInputStream(body, core.tut.pori.http.Definitions.CHARSET_UTF8)){ // convert back to stream for unmarshal 078 SensorsReferenceCore.addTask(authenticatedUser.getUserIdentity(), _formatter.toObject(input, SensorTask.class)); 079 } 080 } catch (IOException ex) { 081 LOGGER.error(ex, ex); 082 } 083 } 084 085 /** 086 * This method can be used to query the current status of a sensor task from the back-end. 087 * 088 * 089 * <h2>Example Query:</h2> 090 * 091 * GET /rest/{@value service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_BACKEND}/{@value service.tut.pori.tasks.Definitions#METHOD_QUERY_TASK_STATUS}?{@value service.tut.pori.tasks.Definitions#PARAMETER_TASK_ID}=1<br> 092 * 093 * <h2>Example Result:</h2> 094 * 095 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_BACKEND]" method="[service.tut.pori.tasks.Definitions#METHOD_QUERY_TASK_STATUS]" type="GET" query="[service.tut.pori.tasks.Definitions#PARAMETER_TASK_ID]=1" body_uri=""} 096 * 097 * @param authenticatedUser 098 * @param taskId 099 * @param dataGroups 100 * @param limits paging limits 101 * @return See {@link service.tut.pori.apilta.sensors.datatypes.SensorTask} 102 */ 103 @HTTPServiceMethod(name = service.tut.pori.tasks.Definitions.METHOD_QUERY_TASK_STATUS, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET}) 104 public Response queryTaskStatus( 105 @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser, 106 @HTTPMethodParameter(name = service.tut.pori.tasks.Definitions.PARAMETER_TASK_ID) StringParameter taskId, 107 @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups, 108 @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits 109 ) 110 { 111 return new Response(SensorsReferenceCore.generateTaskResults(authenticatedUser.getUserIdentity(), dataGroups, limits, taskId.getValue(), service.tut.pori.apilta.sensors.Definitions.TASK_TYPE_DATA_COLLECT)); // we can simply return pseudo randomly generated task results with hard-coded task type 112 } 113}