mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-16 01:01:02 +00:00
add gpsfixes endpoint in REST API and update tracking app
This commit is contained in:
1 parent
ebf4cc5fed
commit
4acf842890
7 files changed
+222
-24
No files matched your search
@@ -8,10 +8,10 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Fragment-Host: com.sap.sailing.server.gateway.serialization
|
||||
Require-Bundle: com.sap.sailing.domain;bundle-version="1.0.0",
|
||||
com.sap.sailing.domain.common;bundle-version="1.0.0",
|
||||
org.hamcrest;bundle-version="1.1.0",
|
||||
org.junit4;bundle-version="4.8.2",
|
||||
com.sap.sailing.domain.shared.android,
|
||||
org.json.simple,
|
||||
org.mockito.mockito-core;bundle-version="1.9.5",
|
||||
org.hamcrest;bundle-version="1.1.0",
|
||||
org.objenesis;bundle-version="1.3.0",
|
||||
com.sap.sse.common
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.sap.sailing.server.gateway.serialization.test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializerTest {
|
||||
@Test
|
||||
public void deserialize() throws JsonDeserializationException, ParseException {
|
||||
String json = "{\n" +
|
||||
" \"deviceUuid\" : \"af855a56-9726-4a9c-a77e-da955bd289bf\",\n" +
|
||||
" \"fixes\" : [\n" +
|
||||
" {\n" +
|
||||
" \"timestamp\" : 14144160080000,\n" +
|
||||
" \"latitude\" : 54.325246,\n" +
|
||||
" \"longitude\" : 10.148556,\n" +
|
||||
" \"speed\" : 3.61,\n" +
|
||||
" \"course\" : 258.11,\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"timestamp\" : 14144168490000,\n" +
|
||||
" \"latitude\" : 55.12456,\n" +
|
||||
" \"longitude\" : 8.03456,\n" +
|
||||
" \"speed\" : 5.1,\n" +
|
||||
" \"course\" : 14.2,\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> deserializer =
|
||||
new FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer();
|
||||
|
||||
Pair<UUID, List<GPSFixMoving>> result =
|
||||
deserializer.deserialize(Helpers.toJSONObjectSafe(JSONValue.parseWithException(json)));
|
||||
assertThat("uuid", result.getA(), equalTo(UUID.fromString("af855a56-9726-4a9c-a77e-da955bd289bf")));
|
||||
assertThat("number of fixes", result.getB().size(), equalTo(2));
|
||||
}
|
||||
}
|
||||
+29
-17
@@ -1,7 +1,10 @@
|
||||
package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedImpl;
|
||||
@@ -12,29 +15,38 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
/**
|
||||
* Make serialization on the smartphone easier by providing a flat structure rather
|
||||
* than nested JSON documents.
|
||||
* Make serialization on the smartphone easier by providing a flat structure rather than nested JSON documents.
|
||||
*
|
||||
* @author Fredrik Teschke
|
||||
*
|
||||
*/
|
||||
public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer implements JsonDeserializer<Pair<UUID, GPSFixMoving>> {
|
||||
public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer implements
|
||||
JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> {
|
||||
public static final String DEVICE_UUID = "deviceUuid";
|
||||
public static final String LON_DEG = "lonDeg";
|
||||
public static final String LAT_DEG = "latDeg";
|
||||
public static final String TIME_MILLIS = "timeMillis";
|
||||
public static final String SPEED_M_PER_S = "speedMperS";
|
||||
public static final String BEARING_DEG = "bearingDeg";
|
||||
public static final String FIXES = "fixes";
|
||||
public static final String LON_DEG = "longitude";
|
||||
public static final String LAT_DEG = "latitude";
|
||||
public static final String TIME_MILLIS = "timestamp";
|
||||
public static final String SPEED_M_PER_S = "speed";
|
||||
public static final String BEARING_DEG = "course";
|
||||
|
||||
@Override
|
||||
public Pair<UUID, GPSFixMoving> deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
public Pair<UUID, List<GPSFixMoving>> deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
UUID device = UUID.fromString(object.get(DEVICE_UUID).toString());
|
||||
double lonDeg = Double.parseDouble(object.get(LON_DEG).toString());
|
||||
double latDeg = Double.parseDouble(object.get(LAT_DEG).toString());
|
||||
long timeMillis = Long.parseLong(object.get(TIME_MILLIS).toString());
|
||||
double speedMperS = Double.parseDouble(object.get(SPEED_M_PER_S).toString());
|
||||
double speedKnots = new MeterPerSecondSpeedImpl(speedMperS).getKnots();
|
||||
double bearingDeg = Double.parseDouble(object.get(BEARING_DEG).toString());
|
||||
GPSFixMoving fix = GPSFixMovingImpl.create(lonDeg, latDeg, timeMillis, speedKnots, bearingDeg);
|
||||
return new Pair<UUID, GPSFixMoving>(device, fix);
|
||||
JSONArray jsonFixes = Helpers.getNestedArraySafe(object, FIXES);
|
||||
List<GPSFixMoving> fixes = new ArrayList<GPSFixMoving>();
|
||||
for (int i = 0; i < jsonFixes.size(); i++) {
|
||||
JSONObject fixObject = Helpers.toJSONObjectSafe(jsonFixes.get(i));
|
||||
double lonDeg = Double.parseDouble(fixObject.get(LON_DEG).toString());
|
||||
double latDeg = Double.parseDouble(fixObject.get(LAT_DEG).toString());
|
||||
long timeMillis = Long.parseLong(fixObject.get(TIME_MILLIS).toString());
|
||||
double speedMperS = Double.parseDouble(fixObject.get(SPEED_M_PER_S).toString());
|
||||
double speedKnots = new MeterPerSecondSpeedImpl(speedMperS).getKnots();
|
||||
double bearingDeg = Double.parseDouble(fixObject.get(BEARING_DEG).toString());
|
||||
GPSFixMoving fix = GPSFixMovingImpl.create(lonDeg, latDeg, timeMillis, speedKnots, bearingDeg);
|
||||
fixes.add(fix);
|
||||
}
|
||||
|
||||
return new Pair<UUID, List<GPSFixMoving>>(device, fixes);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.sap.sailing.server.gateway.test.jaxrs;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.racelog.tracking.impl.SmartphoneUUIDIdentifierImpl;
|
||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneUuidServiceFinderFactory;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.GPSFixesResource;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
|
||||
public class GPSFixesResourceTest {
|
||||
private RacingEventService service;
|
||||
@Before
|
||||
public void setup() {
|
||||
service = new RacingEventServiceImpl(true, new MockSmartphoneUuidServiceFinderFactory());
|
||||
service.getMongoObjectFactory().getDatabase().dropDatabase();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserialize() throws ParseException, TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
String json = "{\n" +
|
||||
" \"deviceUuid\" : \"af855a56-9726-4a9c-a77e-da955bd289bf\",\n" +
|
||||
" \"fixes\" : [\n" +
|
||||
" {\n" +
|
||||
" \"timestamp\" : 14144160080000,\n" +
|
||||
" \"latitude\" : 54.325246,\n" +
|
||||
" \"longitude\" : 10.148556,\n" +
|
||||
" \"speed\" : 3.61,\n" +
|
||||
" \"course\" : 258.11,\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"timestamp\" : 14144168490000,\n" +
|
||||
" \"latitude\" : 55.12456,\n" +
|
||||
" \"longitude\" : 8.03456,\n" +
|
||||
" \"speed\" : 5.1,\n" +
|
||||
" \"course\" : 14.2,\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
GPSFixesResource resource = new GPSFixesResource() {
|
||||
public RacingEventService getService() {
|
||||
return service;
|
||||
};
|
||||
};
|
||||
Response response = resource.postFixes(json);
|
||||
assertThat("response is ok", response.getStatus(), equalTo(Response.Status.OK.getStatusCode()));
|
||||
|
||||
DeviceIdentifier device = new SmartphoneUUIDIdentifierImpl(UUID.fromString("af855a56-9726-4a9c-a77e-da955bd289bf"));
|
||||
assertThat("all fixes stored", service.getGPSFixStore().getNumberOfFixes(device), equalTo(2L));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.sap.sailing.server.gateway.jaxrs.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.racelog.tracking.impl.SmartphoneUUIDIdentifierImpl;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
||||
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
@Path("/v1/gps_fixes")
|
||||
public class GPSFixesResource extends AbstractSailingServerResource {
|
||||
private static final Logger logger = Logger.getLogger(GPSFixesResource.class.getName());
|
||||
private final JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> deserializer =
|
||||
new FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer();
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response postFixes(String json) {
|
||||
Pair<UUID, List<GPSFixMoving>> data = null;
|
||||
try {
|
||||
logger.fine("Post issued to " + this.getClass().getName());
|
||||
Object requestBody = JSONValue.parseWithException(json);
|
||||
JSONObject requestObject = Helpers.toJSONObjectSafe(requestBody);
|
||||
logger.fine("JSON requestObject is: " + requestObject.toString());
|
||||
data = deserializer.deserialize(requestObject);
|
||||
} catch (ParseException | JsonDeserializationException e) {
|
||||
logger.warning(String.format("Exception while parsing post request:\n%s", e.toString()));
|
||||
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request").type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
|
||||
DeviceIdentifier device = new SmartphoneUUIDIdentifierImpl(data.getA());
|
||||
List<GPSFixMoving> fixes = data.getB();
|
||||
|
||||
try {
|
||||
for (GPSFixMoving fix : fixes) {
|
||||
getService().getGPSFixStore().storeFix(device, fix);
|
||||
}
|
||||
logger.log(Level.INFO, "Added " + fixes.size() + " fixes for device " + device.toString() + " to store");
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not store fix for device " + device);
|
||||
}
|
||||
|
||||
return Response.ok().build();
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -14,6 +14,7 @@ public class RestApiApplication extends Application {
|
||||
classes.add(RegattasResource.class);
|
||||
classes.add(LeaderboardsResource.class);
|
||||
classes.add(SearchResource.class);
|
||||
classes.add(GPSFixesResource.class);
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user