Commit b73d9b55 authored by Adam Kucera's avatar Adam Kucera
Browse files

refactoring + preparation to final implementation of the DA API

parent 7596c4a3
...@@ -20,12 +20,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -20,12 +20,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import cz.muni.fi.lasaris.sbms.data.api.request.GroupedAddressRequest; import cz.muni.fi.lasaris.sbms.data.api.request.GroupedAddressRequest;
import cz.muni.fi.lasaris.sbms.data.api.request.AddressRequest; import cz.muni.fi.lasaris.sbms.data.api.request.AddressRequest;
import cz.muni.fi.lasaris.sbms.data.api.response.AggregateResponse; import cz.muni.fi.lasaris.sbms.data.api.response.AggregateResponse;
import cz.muni.fi.lasaris.sbms.data.api.response.SliceResponse; import cz.muni.fi.lasaris.sbms.data.api.response.SnapshotResponse;
import cz.muni.fi.lasaris.sbms.data.entities.Address; import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction; import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction;
import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue; import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue;
import cz.muni.fi.lasaris.sbms.data.logic.ProviderManager; import cz.muni.fi.lasaris.sbms.data.logic.ProviderManager;
import cz.muni.fi.lasaris.sbms.data.logic.DataCollector; import cz.muni.fi.lasaris.sbms.data.logic.DPDataCollector;
//TODO http://stackoverflow.com/questions/14202257/design-restful-query-api-with-a-long-list-of-query-parameters //TODO http://stackoverflow.com/questions/14202257/design-restful-query-api-with-a-long-list-of-query-parameters
...@@ -34,12 +34,12 @@ import cz.muni.fi.lasaris.sbms.data.logic.DataCollector; ...@@ -34,12 +34,12 @@ import cz.muni.fi.lasaris.sbms.data.logic.DataCollector;
public class DataPointsEndpoint { public class DataPointsEndpoint {
final static Logger logger = Logger.getLogger(DataPointsEndpoint.class); final static Logger logger = Logger.getLogger(DataPointsEndpoint.class);
private DataCollector dc = new DataCollector(); private DPDataCollector dc = new DPDataCollector();
@RolesAllowed({"user","admin"}) @RolesAllowed({"user","admin"})
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public SliceResponse getDataPoints( public SnapshotResponse getDataPoints(
@QueryParam("ids") String json, @QueryParam("ids") String json,
@QueryParam("cache") String cache @QueryParam("cache") String cache
) { ) {
...@@ -51,11 +51,11 @@ public class DataPointsEndpoint { ...@@ -51,11 +51,11 @@ public class DataPointsEndpoint {
logger.debug(json); logger.debug(json);
AddressRequest readSpecs = m.readValue(json, AddressRequest.class); AddressRequest readSpecs = m.readValue(json, AddressRequest.class);
logger.debug(readSpecs); logger.debug(readSpecs);
SliceResponse result = dc.getDataPointValues(readSpecs, allowCache(cache)); SnapshotResponse result = dc.getDataPointValues(readSpecs, allowCache(cache));
logger.debug(result); logger.debug(result);
return result; return result;
} catch (IOException e) { } catch (IOException e) {
return SliceResponse.getErrorResponse("Unable to parse query:" + e); return SnapshotResponse.getErrorResponse("Unable to parse query:" + e);
} }
...@@ -88,7 +88,7 @@ public class DataPointsEndpoint { ...@@ -88,7 +88,7 @@ public class DataPointsEndpoint {
@GET @GET
@Path("/grouped") @Path("/grouped")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public SliceResponse getGroupedDataPoints( public SnapshotResponse getGroupedDataPoints(
@QueryParam("ids") String json, @QueryParam("ids") String json,
@QueryParam("cache") String cache @QueryParam("cache") String cache
) { ) {
...@@ -100,7 +100,7 @@ public class DataPointsEndpoint { ...@@ -100,7 +100,7 @@ public class DataPointsEndpoint {
logger.debug(readSpecs); logger.debug(readSpecs);
return dc.getDataPointGroupedValues(readSpecs, allowCache(cache)); return dc.getDataPointGroupedValues(readSpecs, allowCache(cache));
} catch (IOException e) { } catch (IOException e) {
return SliceResponse.getErrorResponse("Unable to parse query:" + e); return SnapshotResponse.getErrorResponse("Unable to parse query:" + e);
} }
} }
...@@ -131,12 +131,12 @@ public class DataPointsEndpoint { ...@@ -131,12 +131,12 @@ public class DataPointsEndpoint {
@GET @GET
@Path("/{id}") @Path("/{id}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public SliceResponse getDataPoint( public SnapshotResponse getDataPoint(
@PathParam("id") String idP, @PathParam("id") String idP,
@QueryParam("cache") String cache) { @QueryParam("cache") String cache) {
Address a = new Address(idP); Address a = new Address(idP);
RawValue v = ProviderManager.getDataPointsProvider(a.getProtocol()).getDataPointValue(a, allowCache(cache)); RawValue v = ProviderManager.getDataPointsProvider(a.getProtocol()).getDataPointValue(a, allowCache(cache));
return new SliceResponse(a, v); return new SnapshotResponse(a, v);
} }
private boolean allowCache(String cache) { private boolean allowCache(String cache) {
......
...@@ -5,10 +5,12 @@ import java.time.Duration; ...@@ -5,10 +5,12 @@ import java.time.Duration;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit; import java.time.temporal.TemporalUnit;
import java.util.Arrays;
import javax.annotation.security.RolesAllowed; import javax.annotation.security.RolesAllowed;
import javax.ws.rs.DefaultValue; import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
...@@ -17,155 +19,109 @@ import javax.ws.rs.core.MediaType; ...@@ -17,155 +19,109 @@ import javax.ws.rs.core.MediaType;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import cz.muni.fi.lasaris.sbms.data.api.request.GroupedAddressRequest; import cz.muni.fi.lasaris.sbms.data.api.request.GroupedAddressRequest;
import cz.muni.fi.lasaris.sbms.data.api.request.TrendsRequest;
import cz.muni.fi.lasaris.sbms.data.api.request.AddressRequest; import cz.muni.fi.lasaris.sbms.data.api.request.AddressRequest;
import cz.muni.fi.lasaris.sbms.data.api.response.AggregateResponse; import cz.muni.fi.lasaris.sbms.data.api.response.AggregateResponse;
import cz.muni.fi.lasaris.sbms.data.api.response.SliceResponse; import cz.muni.fi.lasaris.sbms.data.api.response.SeriesOfValuesResponse;
import cz.muni.fi.lasaris.sbms.data.api.response.SliceResponse; import cz.muni.fi.lasaris.sbms.data.api.response.SliceResponse;
import cz.muni.fi.lasaris.sbms.data.entities.Address; import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction; import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationWindow;
import cz.muni.fi.lasaris.sbms.data.entities.Interpolation; import cz.muni.fi.lasaris.sbms.data.entities.Interpolation;
import cz.muni.fi.lasaris.sbms.data.entities.Sampling; import cz.muni.fi.lasaris.sbms.data.entities.Sampling;
import cz.muni.fi.lasaris.sbms.data.entities.SeriesSpecs; import cz.muni.fi.lasaris.sbms.data.entities.SeriesSpecs;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Trend; import cz.muni.fi.lasaris.sbms.data.entities.containers.Trend;
import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue; import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue;
import cz.muni.fi.lasaris.sbms.data.logic.DataCollector; import cz.muni.fi.lasaris.sbms.data.logic.DPDataCollector;
import cz.muni.fi.lasaris.sbms.data.logic.ProviderManager; import cz.muni.fi.lasaris.sbms.data.logic.ProviderManager;
import cz.muni.fi.lasaris.sbms.data.logic.TrendsDataCollector;
import cz.muni.fi.lasaris.sbms.data.util.Aggregator; import cz.muni.fi.lasaris.sbms.data.util.Aggregator;
public class TrendsEndpoint { public class TrendsEndpoint {
final static Logger logger = Logger.getLogger(TrendsEndpoint.class); final static Logger logger = Logger.getLogger(TrendsEndpoint.class);
private DataCollector dc; private TrendsDataCollector dc;
private ObjectMapper m; private ObjectMapper m;
public TrendsEndpoint() { public TrendsEndpoint() {
dc = new DataCollector(); dc = new TrendsDataCollector();
m = new ObjectMapper(); m = new ObjectMapper();
m.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); m.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
} }
// TODO http://stackoverflow.com/questions/14202257/design-restful-query-api-with-a-long-list-of-query-parameters // http://stackoverflow.com/questions/14202257/design-restful-query-api-with-a-long-list-of-query-parameters
/*
// Methods 4, 6
@RolesAllowed({"user","admin"}) @RolesAllowed({"user","admin"})
@GET @GET
@Path("/serie/{id}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public SliceResponse getTrends( public SeriesOfValuesResponse getFunc(
@QueryParam("ids") String json, @QueryParam("id") String id,
@QueryParam("start") String start, @QueryParam("start") String start,
@QueryParam("end") String end, @QueryParam("end") String end,
@QueryParam("sampling.cron") String samplingCron, @QueryParam("sampling.cron") String samplingCron,
@QueryParam("sampling.duration") Long samplingDur, @QueryParam("sampling.duration") Long samplingDur,
@DefaultValue("NONE") @QueryParam("interpolation") Interpolation interpolation @QueryParam("sampling.interpolation") Interpolation interpolation,
@QueryParam("aggregation.function") String aggregation,
@QueryParam("aggregation.window") String window,
) { ) {
try { Address a = new Address(id);
logger.debug("Processing request..."); Trend v = ProviderManager.getTrendsProvider(a.getProtocol()).getTrend(a, getSeriesSpecs(start, end, samplingCron, samplingDur, interpolation));
logger.debug(json); return new SeriesOfValuesResponse(a, v);
TrendsRequest readSpecs = getReadSpecs(json, start, end, samplingCron, samplingDur, interpolation, null);
logger.debug(readSpecs);
SliceResponse result = dc.getTrends(readSpecs);
logger.debug(result);
return result;
} catch (IOException e) {
return SliceResponse.getErrorResponse("Unable to parse query:" + e);
}
} }
*/
// Method 4
@RolesAllowed({"user","admin"}) @RolesAllowed({"user","admin"})
@GET @POST
@Path("/aggregated") @Path("/si")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public AggregateResponse getAggregatedTrends( public SeriesOfValuesResponse getSI(
@QueryParam("ids") String json, @QueryParam("id") String id,
@DefaultValue("NONE") @QueryParam("aggregation") AggregationFunction agg @QueryParam("start") String start,
@QueryParam("end") String end
) { ) {
ObjectMapper m = new ObjectMapper();
try {
logger.debug("Processing request...");
logger.debug(json);
AddressRequest readSpecs = m.readValue(json, AddressRequest.class);
logger.debug(readSpecs);
return dc.getDataPointsAggregation(readSpecs, agg);
} catch (IOException e) {
return AggregateResponse.getErrorResponse("Unable to parse query:" + e);
}
}
@RolesAllowed({"user","admin"}) TrendsRequest r = getReadSpecsSingle(id, start, end, null, null, null, null, null);
@GET Trend v = dc.getTrend(r);
@Path("/grouped") return new SeriesOfValuesResponse(r.getAddress(), v);
@Produces(MediaType.APPLICATION_JSON)
public SliceResponse getGroupedDataPoints(
@QueryParam("json") String json
) {
ObjectMapper m = new ObjectMapper();
try {
logger.debug("Processing request...");
logger.debug(json);
GroupedAddressRequest readSpecs = m.readValue(json,GroupedAddressRequest.class);
logger.debug(readSpecs);
return dc.getDataPointGroupedValues(readSpecs);
} catch (IOException e) {
return SliceResponse.getErrorResponse("Unable to parse query:" + e);
}
} }
@RolesAllowed({"user","admin"}) private TrendsRequest getReadSpecsSingle(String id, String start, String end, String samplingCron,
@GET Long samplingDur, Interpolation interpolation, AggregationFunction aggregation, AggregationWindow window) {
@Path("/group-aggregated")
@Produces(MediaType.APPLICATION_JSON) TrendsRequest readSpecs = getReadSpecsBase(start, end, samplingCron, samplingDur, interpolation, aggregation, window);
public AggregateResponse getGroupedAggregatedDataPoints( AddressRequest ar = new AddressRequest();
@QueryParam("json") String json, ar.setAddresses(Arrays.asList(new Address[] { new Address(id)}));
@DefaultValue("NONE") @QueryParam("aggregation") AggregationFunction agg readSpecs.setAddressSpecs(ar);
) { return readSpecs;
ObjectMapper m = new ObjectMapper();
try {
logger.debug("Processing request...");
logger.debug(json);
GroupedAddressRequest readSpecs = m.readValue(json, GroupedAddressRequest.class);
logger.debug(readSpecs);
AggregateResponse result = dc.getDataPointGroupAggregations(readSpecs, agg);
logger.debug(result);
return result;
} catch (IOException e) {
return AggregateResponse.getErrorResponse("Unable to parse query:" + e);
}
} }
@RolesAllowed({"user","admin"}) private TrendsRequest getReadSpecsMulti(String json, boolean grouping, String start, String end, String samplingCron,
@GET Long samplingDur, Interpolation interpolation, AggregationFunction aggregation, AggregationWindow window) throws JsonParseException, JsonMappingException, IOException {
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON) TrendsRequest readSpecs = getReadSpecsBase(start, end, samplingCron, samplingDur, interpolation, aggregation, window);
public SliceResponse getTrend( readSpecs.setAddressSpecs(m.readValue(json, AddressRequest.class));
@QueryParam("id") String id, return readSpecs;
@QueryParam("start") String start,
@QueryParam("end") String end,
@QueryParam("sampling.cron") String samplingCron,
@QueryParam("sampling.duration") Long samplingDur,
@DefaultValue("NONE") @QueryParam("interpolation") Interpolation interpolation
) {
Address a = new Address(id);
Trend v = ProviderManager.getTrendsProvider(a.getProtocol()).getTrend(a, getSeriesSpecs(start, end, samplingCron, samplingDur, interpolation));
return new SliceResponse(a, v);
} }
private TrendsRequest getReadSpecs(String json, String start, String end, String samplingCron,
Long samplingDur, Interpolation interpolation, AggregationFunction aggregation) { private TrendsRequest getReadSpecsBase(String start, String end, String samplingCron,
Long samplingDur, Interpolation interpolation, AggregationFunction aggregation, AggregationWindow window) {
TrendsRequest readSpecs = new TrendsRequest(); TrendsRequest readSpecs = new TrendsRequest();
readSpecs.setAddressesSpecs(m.readValue(json, AddressRequest.class));
SeriesSpecs s = getSeriesSpecs(start, end, samplingCron, samplingDur, interpolation); SeriesSpecs s = getSeriesSpecs(start, end, samplingCron, samplingDur, interpolation);
readSpecs.setSeriesSpecs(s); readSpecs.setSeriesSpecs(s);
readSpecs.setAggregation(aggregation); readSpecs.setAggregation(aggregation, window);
return readSpecs; return readSpecs;
} }
......
package cz.muni.fi.lasaris.sbms.data.api.request;
import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationWindow;
import cz.muni.fi.lasaris.sbms.data.entities.SeriesSpecs;
public class TrendsRequest {
public void setAddressSpecs(AddressRequest ar) {
// TODO Auto-generated method stub
}
public Address getAddress() {
// TODO Auto-generated method stub
return null;
}
public void setSeriesSpecs(SeriesSpecs s) {
// TODO Auto-generated method stub
}
public void setAggregation(AggregationFunction aggregation, AggregationWindow window) {
// TODO Auto-generated method stub
}
}
...@@ -8,6 +8,8 @@ import cz.muni.fi.lasaris.sbms.data.entities.containers.Aggregation; ...@@ -8,6 +8,8 @@ import cz.muni.fi.lasaris.sbms.data.entities.containers.Aggregation;
import cz.muni.fi.lasaris.sbms.data.entities.values.AggregatedValue; import cz.muni.fi.lasaris.sbms.data.entities.values.AggregatedValue;
public class AggregateResponse { public class AggregateResponse {
private static final String DEFAULT_GROUPING = "noGrouping";
private String error; private String error;
private Map<String, AggregatedValue> results; private Map<String, AggregatedValue> results;
...@@ -31,7 +33,7 @@ public class AggregateResponse { ...@@ -31,7 +33,7 @@ public class AggregateResponse {
public AggregateResponse(AggregatedValue v) { public AggregateResponse(AggregatedValue v) {
this.results = new LinkedHashMap<String, AggregatedValue>(); this.results = new LinkedHashMap<String, AggregatedValue>();
this.results.put("value", v); this.results.put(DEFAULT_GROUPING, v);
} }
public AggregateResponse(Aggregation<AddressGroup> a) { public AggregateResponse(Aggregation<AddressGroup> a) {
......
...@@ -8,7 +8,7 @@ import cz.muni.fi.lasaris.sbms.data.entities.containers.Series; ...@@ -8,7 +8,7 @@ import cz.muni.fi.lasaris.sbms.data.entities.containers.Series;
import cz.muni.fi.lasaris.sbms.data.entities.values.Value; import cz.muni.fi.lasaris.sbms.data.entities.values.Value;
public class SeriesOfValuesResponse { public class SeriesOfValuesResponse {
private static final String DEFAULT_GROUPING = "noGrouping"; private static final String DEFAULT_GROUPING = "noGrouping";
private String error; private String error;
private Map<String, Map<Address, Series<? extends Value>>> results; private Map<String, Map<Address, Series<? extends Value>>> results;
......
...@@ -4,17 +4,17 @@ import java.util.LinkedHashMap; ...@@ -4,17 +4,17 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import cz.muni.fi.lasaris.sbms.data.entities.Address; import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Snapshot; import cz.muni.fi.lasaris.sbms.data.entities.containers.Slice;
import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue; import cz.muni.fi.lasaris.sbms.data.entities.values.InterpolatedValue;
public class SliceResponse { public class SliceResponse {
private static final String DEFAULT_GROUPING = "noGrouping"; private static final String DEFAULT_GROUPING = "noGrouping";
private String error; private String error;
private Map<String, Snapshot> results; private Map<String, Slice> results;
public Map<String, Snapshot> getResults() { public Map<String, Slice> getResults() {
return this.results; return this.results;
} }
...@@ -28,17 +28,17 @@ public class SliceResponse { ...@@ -28,17 +28,17 @@ public class SliceResponse {
this.results = null; this.results = null;
} }
public SliceResponse(Map<String, Snapshot> data) { public SliceResponse(Map<String, Slice> data) {
this.results = data; this.results = data;
} }
public SliceResponse(Snapshot data) { public SliceResponse(Slice data) {
this.results = new LinkedHashMap<String, Snapshot>(); this.results = new LinkedHashMap<String, Slice>();
this.results.put(DEFAULT_GROUPING, data); this.results.put(DEFAULT_GROUPING, data);
} }
public SliceResponse(Address a, RawValue v) { public SliceResponse(Address a, InterpolatedValue v) {
this(new Snapshot()); this(new Slice());
this.results.get(DEFAULT_GROUPING).add(a, v); this.results.get(DEFAULT_GROUPING).add(a, v);
} }
......
package cz.muni.fi.lasaris.sbms.data.api.response;
import java.util.LinkedHashMap;
import java.util.Map;
import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Snapshot;
import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue;
public class SnapshotResponse {
private static final String DEFAULT_GROUPING = "noGrouping";
private String error;
private Map<String, Snapshot> results;
public Map<String, Snapshot> getResults() {
return this.results;
}
public static SnapshotResponse getErrorResponse(String error) {
SnapshotResponse r = new SnapshotResponse();
r.setError(error);
return r;
}
private SnapshotResponse() {
this.results = null;
}
public SnapshotResponse(Map<String, Snapshot> data) {
this.results = data;
}
public SnapshotResponse(Snapshot data) {
this.results = new LinkedHashMap<String, Snapshot>();
this.results.put(DEFAULT_GROUPING, data);
}
public SnapshotResponse(Address a, RawValue v) {
this(new Snapshot());
this.results.get(DEFAULT_GROUPING).add(a, v);
}
public String getError() {
return error;