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.Response.Status; 026import core.tut.pori.http.annotations.HTTPAuthenticationParameter; 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.AuthenticationParameter; 031import core.tut.pori.http.parameters.DataGroups; 032import core.tut.pori.http.parameters.DateIntervalParameter; 033import core.tut.pori.http.parameters.InputStreamParameter; 034import core.tut.pori.http.parameters.Limits; 035import core.tut.pori.http.parameters.LongParameter; 036import core.tut.pori.http.parameters.StringParameter; 037import core.tut.pori.utils.XMLFormatter; 038import service.tut.pori.apilta.sensors.datatypes.SensorTask; 039import service.tut.pori.tasks.datatypes.Task; 040import service.tut.pori.tasks.datatypes.TaskList; 041 042/** 043 * Reference implementation for client API methods. 044 * 045 * <h1>Implementation Service path {@value service.tut.pori.apilta.sensors.Definitions#SERVICE_SENSORS}</h1> 046 * 047 * @see service.tut.pori.apilta.sensors.SensorService 048 * 049 */ 050@HTTPService(name = Definitions.SERVICE_SENSORS_REFERENCE_CLIENT) 051public class ClientService { 052 private static final Logger LOGGER = Logger.getLogger(ClientService.class); 053 private XMLFormatter _formatter = new XMLFormatter(); 054 055 /** 056 * 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". 057 * 058 * <h2>Example Query:</h2> 059 * 060 * POST /rest/{@value service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT}/{@value service.tut.pori.apilta.sensors.Definitions#METHOD_CREATE_TASK}<br> 061 * Content-Type: text/xml; charset=UTF-8<br><br> 062 * 063 * <b>[HTTP BODY STARTS]</b><br> 064 * 065 * {@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> 066 * 067 * <b>[HTTP BODY ENDS]</b><br> 068 * 069 * <h2>Example Result:</h2> 070 * 071 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT]" method="[service.tut.pori.apilta.sensors.Definitions#METHOD_CREATE_TASK]" type="POST" query="" body_uri="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_EXAMPLE]/[service.tut.pori.tasks.Definitions#ELEMENT_TASK]"} 072 * 073 * @param authenticatedUser 074 * @param xml Only the workload data should be in the body. See {@link service.tut.pori.apilta.sensors.datatypes.SensorTask} 075 * @return {@link service.tut.pori.tasks.datatypes.TaskList} with identifier for the generated task 076 */ 077 @HTTPServiceMethod(name = service.tut.pori.apilta.sensors.Definitions.METHOD_CREATE_TASK, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST}) 078 public Response createTask ( 079 @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser, 080 @HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml 081 ) 082 { 083 try { 084 String body = IOUtils.toString(xml.getValue(), core.tut.pori.http.Definitions.CHARSET_UTF8); // read the body 085 LOGGER.debug(body); // print to debug 086 try(InputStream input = IOUtils.toInputStream(body, core.tut.pori.http.Definitions.CHARSET_UTF8)){ // convert back to stream for unmarshal 087 String taskId = SensorsReferenceCore.createTask(authenticatedUser.getUserIdentity(), _formatter.toObject(input, SensorTask.class)); 088 TaskList taskList = new TaskList(); 089 Task task = new SensorTask(); 090 task.addTaskId(taskId); 091 taskList.addTask(task); 092 return new Response(taskList); 093 } 094 } catch (IOException ex) { 095 LOGGER.error(ex, ex); 096 return new Response(Status.BAD_REQUEST); 097 } 098 } 099 100 /** 101 * 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". 102 * 103 * <h2>Example Query:</h2> 104 * 105 * POST /rest/{@value service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT}/{@value service.tut.pori.apilta.sensors.Definitions#METHOD_MODIFY_TASK}<br> 106 * Content-Type: text/xml; charset=UTF-8<br><br> 107 * 108 * <b>[HTTP BODY STARTS]</b><br> 109 * 110 * {@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> 111 * 112 * <b>[HTTP BODY ENDS]</b><br> 113 * 114 * <h2>Example Result:</h2> 115 * 116 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT]" method="[service.tut.pori.apilta.sensors.Definitions#METHOD_MODIFY_TASK]" type="POST" query="" body_uri="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_EXAMPLE]/[service.tut.pori.tasks.Definitions#ELEMENT_TASK]"} 117 * 118 * @param authenticatedUser 119 * @param xml Only the workload data should be in the body. See {@link service.tut.pori.apilta.sensors.datatypes.SensorTask} 120 * @return {@link service.tut.pori.tasks.datatypes.TaskList} with identifier for the generated task 121 */ 122 @HTTPServiceMethod(name = service.tut.pori.apilta.sensors.Definitions.METHOD_MODIFY_TASK, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST}) 123 public Response modifyTask ( 124 @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser, 125 @HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml 126 ) 127 { 128 try { 129 String body = IOUtils.toString(xml.getValue(), core.tut.pori.http.Definitions.CHARSET_UTF8); // read the body 130 LOGGER.debug(body); // print to debug 131 try(InputStream input = IOUtils.toInputStream(body, core.tut.pori.http.Definitions.CHARSET_UTF8)){ // convert back to stream for unmarshal 132 String taskId = SensorsReferenceCore.modifyTask(authenticatedUser.getUserIdentity(), _formatter.toObject(input, SensorTask.class)); 133 TaskList taskList = new TaskList(); 134 Task task = new SensorTask(); 135 task.addTaskId(taskId); 136 taskList.addTask(task); 137 return new Response(taskList); 138 } 139 } catch (IOException ex) { 140 LOGGER.error(ex, ex); 141 return new Response(Status.BAD_REQUEST); 142 } 143 } 144 145 /** 146 * This method can be used to retrieve measurements for a single task or for a list of tasks defined by the task ids. 147 * 148 * <h2>Example Query:</h2> 149 * 150 * GET /rest/{@value service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT}/{@value service.tut.pori.apilta.sensors.Definitions#METHOD_GET_MEASUREMENTS}?{@value service.tut.pori.tasks.Definitions#PARAMETER_TASK_ID}=1<br> 151 * 152 * <h2>Example Result:</h2> 153 * 154 * {@doc.restlet service="[service.tut.pori.apilta.sensors.reference.Definitions#SERVICE_SENSORS_REFERENCE_CLIENT]" method="[service.tut.pori.apilta.sensors.Definitions#METHOD_GET_MEASUREMENTS]" type="GET" query="[service.tut.pori.tasks.Definitions#PARAMETER_TASK_ID]=1" body_uri=""} 155 * 156 * 157 * @param authenticatedUser 158 * @param taskId 159 * @param backendIdFilter 160 * @param createdFilter 161 * @param dataGroups 162 * @param limits 163 * @param measurementIdFilter 164 * @return see {@link service.tut.pori.apilta.sensors.datatypes.MeasurementList} 165 */ 166 @HTTPServiceMethod(name = service.tut.pori.apilta.sensors.Definitions.METHOD_GET_MEASUREMENTS, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET}) 167 public Response getMeasurements( 168 @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser, 169 @HTTPMethodParameter(name = service.tut.pori.tasks.Definitions.PARAMETER_TASK_ID) StringParameter taskId, 170 @HTTPMethodParameter(name = service.tut.pori.tasks.Definitions.PARAMETER_BACKEND_ID, required = false) LongParameter backendIdFilter, 171 @HTTPMethodParameter(name = service.tut.pori.tasks.Definitions.PARAMETER_CREATED, required = false) DateIntervalParameter createdFilter, 172 @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups, 173 @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits, 174 @HTTPMethodParameter(name = service.tut.pori.apilta.sensors.Definitions.PARAMETER_MEASUREMENT_ID, required = false) StringParameter measurementIdFilter 175 ) 176 { 177 return new Response(SensorsReferenceCore.getMeasurements(authenticatedUser.getUserIdentity(), backendIdFilter.getValues(), createdFilter.getValues(), dataGroups, limits, measurementIdFilter.getValues(), taskId.getValues())); 178 } 179}