[New] Added REST API for Reports
This commit is contained in:
parent
966fbf6f69
commit
9b8e91d0a5
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -56,6 +56,10 @@ public class StrolchModelConstants {
|
|||
* This uom value indicates that the {@link Parameter} has no defined uom
|
||||
*/
|
||||
public static final String UOM_NONE = "None"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public static final String INTERNAL = "internal";
|
||||
|
||||
public static final String SUFFIX_REF = "-Ref";
|
||||
public static final String BAG_RELATIONS = "relations";
|
||||
public static final String BAG_PARAMETERS = "parameters";
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
*/
|
||||
package li.strolch.model;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
/**
|
||||
* This class contains all constants used to marshall strolch objects to XML and JSON.
|
||||
*/
|
||||
public class Tags {
|
||||
|
||||
public static final String AGENT = "Agent";
|
||||
|
|
|
@ -50,6 +50,12 @@
|
|||
<artifactId>javax.mail-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
|
|
@ -38,6 +38,7 @@ public class StrolchRestfulClasses {
|
|||
|
||||
restfulClasses.add(AuthenticationService.class);
|
||||
restfulClasses.add(StrolchJobsResource.class);
|
||||
restfulClasses.add(ReportResource.class);
|
||||
restfulClasses.add(Inspector.class);
|
||||
restfulClasses.add(VersionQuery.class);
|
||||
restfulClasses.add(ModelQuery.class);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package li.strolch.rest;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
|
@ -34,4 +36,14 @@ public class StrolchRestfulConstants {
|
|||
public static final String OFFSET = "offset";
|
||||
public static final String LIMIT = "limit";
|
||||
|
||||
public static final String PARAM_DATE_RANGE = "dateRange";
|
||||
public static final String PARAM_DATE_RANGE_SEL = "dateRangeSel";
|
||||
public static final String PARAM_FACETS = "facets";
|
||||
public static final String PARAM_FROM = "from";
|
||||
public static final String PARAM_TO = "to";
|
||||
public static final String PARAM_FILTER = "filter";
|
||||
public static final String PARAM_QUERY = "query";
|
||||
|
||||
public static final MediaType TEXT_CSV_TYPE = new MediaType("text", "csv");
|
||||
public static final String TEXT_CSV = "text/csv";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
package li.strolch.rest.endpoint;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
import static li.strolch.report.ReportConstants.*;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.*;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.PARAM_DATE_RANGE_SEL;
|
||||
import static li.strolch.utils.helper.StringHelper.formatNanoDuration;
|
||||
import static li.strolch.utils.helper.StringHelper.isNotEmpty;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.StrolchRootElement;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.model.parameter.StringParameter;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.report.Report;
|
||||
import li.strolch.report.ReportSearch;
|
||||
import li.strolch.rest.RestfulStrolchComponent;
|
||||
import li.strolch.rest.StrolchRestfulConstants;
|
||||
import li.strolch.rest.helper.ResponseUtil;
|
||||
import li.strolch.utils.collections.DateRange;
|
||||
import li.strolch.utils.collections.MapOfSets;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.iso8601.ISO8601FormatFactory;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Path("strolch/reports")
|
||||
public class ReportResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ReportResource.class);
|
||||
|
||||
private static String getContext() {
|
||||
StackTraceElement element = new Throwable().getStackTrace()[1];
|
||||
return element.getClassName() + "." + element.getMethodName();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getAllReportIds(@Context HttpServletRequest request) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) {
|
||||
|
||||
List<Resource> ids = new ReportSearch().search(tx).orderByName(false).toList();
|
||||
|
||||
// create final array
|
||||
JsonArray array = new JsonArray();
|
||||
ids.forEach(res -> {
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, res.getId());
|
||||
o.addProperty(Tags.Json.NAME, res.getName());
|
||||
o.addProperty(PARAM_DATE_RANGE, res.hasParameter(BAG_PARAMETERS, PARAM_DATE_RANGE_SEL));
|
||||
array.add(o);
|
||||
});
|
||||
|
||||
return ResponseUtil.toResponse(DATA, array);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}/facets")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getReportFacets(@Context HttpServletRequest request, @PathParam("id") String id,
|
||||
@QueryParam(LIMIT) String limitS) throws IOException {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
|
||||
int limit = isNotEmpty(limitS) ? Integer.parseInt(limitS) : 10;
|
||||
|
||||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = new JsonParser().parse(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toString()))
|
||||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
JsonArray result = new JsonArray();
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) {
|
||||
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
MapOfSets<String, StrolchRootElement> criteria = report.generateFilterCriteria();
|
||||
criteria.keySet().forEach(type -> {
|
||||
JsonArray values = new JsonArray();
|
||||
criteria.getSet(type).stream().limit(limit) //
|
||||
.forEach(f -> {
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, f.getId());
|
||||
o.addProperty(Tags.Json.NAME, f.getName());
|
||||
values.add(o);
|
||||
});
|
||||
|
||||
JsonObject filter = new JsonObject();
|
||||
filter.addProperty(Tags.Json.TYPE, type);
|
||||
filter.add(Tags.Json.VALUES, values);
|
||||
result.add(filter);
|
||||
});
|
||||
|
||||
return ResponseUtil.toResponse(DATA, result);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}/facets/{type}/fields")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getReportFacetValues(@Context HttpServletRequest request, @PathParam("id") String id,
|
||||
@PathParam("type") String type, @QueryParam(PARAM_QUERY) String queryS, @QueryParam(LIMIT) String limitS)
|
||||
throws IOException {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
|
||||
String query = isNotEmpty(queryS) ? queryS.toLowerCase() : queryS;
|
||||
int limit = isNotEmpty(limitS) ? Integer.parseInt(limitS) : 10;
|
||||
|
||||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = new JsonParser().parse(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toString()))
|
||||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) {
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// get filter criteria
|
||||
MapOfSets<String, StrolchRootElement> criteria = report.generateFilterCriteria();
|
||||
|
||||
// create final array
|
||||
JsonArray array = new JsonArray();
|
||||
Set<StrolchRootElement> valueSet = criteria.getSet(type);
|
||||
|
||||
// filter if required
|
||||
if (valueSet != null) {
|
||||
|
||||
Stream<StrolchRootElement> stream = valueSet.stream();
|
||||
if (query != null)
|
||||
stream = stream.filter(f -> f.getName().toLowerCase().startsWith(query));
|
||||
|
||||
// limit
|
||||
stream.limit(limit) //
|
||||
|
||||
// add the data finally
|
||||
.forEach(f -> {
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, f.getId());
|
||||
o.addProperty(Tags.Json.NAME, f.getName());
|
||||
array.add(o);
|
||||
});
|
||||
}
|
||||
|
||||
return ResponseUtil.toResponse(DATA, array);
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{id}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getReportById(@Context HttpServletRequest request, @PathParam("id") String id, String data)
|
||||
throws IOException {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
|
||||
DBC.PRE.assertNotEmpty("report ID is required", id);
|
||||
|
||||
// get information from body
|
||||
JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
|
||||
|
||||
int offset = jsonObject.get(OFFSET) != null ? jsonObject.get(OFFSET).getAsInt() : 50;
|
||||
int limit = jsonObject.get(LIMIT) != null ? jsonObject.get(LIMIT).getAsInt() : 50;
|
||||
|
||||
MapOfSets<String, String> filters = jsonObject.get(PARAM_FILTER) != null ?
|
||||
getFiltersFromJson(jsonObject.get(PARAM_FILTER).getAsJsonArray()) :
|
||||
new MapOfSets<>();
|
||||
|
||||
// get date range if defined
|
||||
JsonObject rangeJ =
|
||||
jsonObject.get(PARAM_DATE_RANGE) != null ? jsonObject.getAsJsonObject(PARAM_DATE_RANGE) : null;
|
||||
|
||||
String fromS = rangeJ != null && rangeJ.get(PARAM_FROM) != null && !rangeJ.get(PARAM_FROM).isJsonNull() ?
|
||||
rangeJ.get(PARAM_FROM).getAsString() :
|
||||
null;
|
||||
Date from;
|
||||
try {
|
||||
from = fromS != null ? ISO8601FormatFactory.getInstance().parseDate(fromS) : null;
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not parse 'from' date, setting it to null.", e);
|
||||
from = null;
|
||||
}
|
||||
|
||||
String toS = rangeJ != null && rangeJ.get(PARAM_TO) != null && !rangeJ.get(PARAM_TO).isJsonNull() ?
|
||||
rangeJ.get(PARAM_TO).getAsString() :
|
||||
null;
|
||||
Date to;
|
||||
try {
|
||||
to = (toS != null) ? ISO8601FormatFactory.getInstance().parseDate(toS) : null;
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not parse 'to' date, setting it to null.", e);
|
||||
to = null;
|
||||
}
|
||||
|
||||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = new JsonParser().parse(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toString()))
|
||||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// add filters from request
|
||||
if (report.hasDateRangeSelector()) {
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, true);
|
||||
report.dateRange(dateRange);
|
||||
}
|
||||
filters.keySet().forEach(f -> report.filter(f, filters.getSet(f)));
|
||||
|
||||
// get rows
|
||||
Stream<JsonObject> json = report.doReportAsJson().skip(offset).limit(limit);
|
||||
|
||||
// add rows to response
|
||||
JsonObject finalResult = new JsonObject();
|
||||
JsonArray rows = new JsonArray();
|
||||
json.forEach(rows::add);
|
||||
|
||||
finalResult.add(PARAM_ROWS, rows);
|
||||
|
||||
// add column information to JSON
|
||||
JsonArray col = new JsonArray();
|
||||
|
||||
Resource reportR = tx.getResourceBy(TYPE_REPORT, id, true);
|
||||
reportR.getParameterBag(BAG_COLUMNS).getParameterKeySet().forEach(s -> {
|
||||
StringParameter param = reportR.getParameter(BAG_COLUMNS, s, true);
|
||||
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, s);
|
||||
o.addProperty(Tags.Json.NAME, param.getName());
|
||||
o.addProperty(Tags.Json.INDEX, param.getIndex());
|
||||
col.add(o);
|
||||
});
|
||||
|
||||
finalResult.add(PARAM_COLUMNS, col);
|
||||
|
||||
long size = report.getCounter();
|
||||
long lastOffset = size % limit == 0 ? size - limit : (size / limit) * limit;
|
||||
long nextOffset = Math.min(lastOffset, limit + offset);
|
||||
long previousOffset = Math.max(0, offset - limit);
|
||||
|
||||
finalResult.addProperty(LIMIT, limit);
|
||||
finalResult.addProperty(OFFSET, offset);
|
||||
finalResult.addProperty(SIZE, size);
|
||||
finalResult.addProperty(LAST_OFFSET, lastOffset);
|
||||
finalResult.addProperty(NEXT_OFFSET, nextOffset);
|
||||
finalResult.addProperty(PREVIOUS_OFFSET, previousOffset);
|
||||
|
||||
String duration = formatNanoDuration(System.nanoTime() - start);
|
||||
finalResult.addProperty(PARAM_DURATION, duration);
|
||||
|
||||
logger.info(id + " Report took: " + duration);
|
||||
return ResponseUtil.toResponse(DATA, finalResult);
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{id}/csv")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(TEXT_CSV)
|
||||
public Response getReportByIdAsCsv(@Context HttpServletRequest request, @PathParam("id") String id, String data)
|
||||
throws IOException {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
|
||||
DBC.PRE.assertNotEmpty("report ID is required", id);
|
||||
|
||||
// get information from body
|
||||
JsonObject jsonObject = StringHelper.isEmpty(data) ? null : new JsonParser().parse(data).getAsJsonObject();
|
||||
|
||||
MapOfSets<String, String> filters = jsonObject != null && jsonObject.get(PARAM_FILTER) != null ?
|
||||
getFiltersFromJson(jsonObject.get(PARAM_FILTER).getAsJsonArray()) :
|
||||
new MapOfSets<>();
|
||||
|
||||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = new JsonParser().parse(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toString()))
|
||||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) {
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// add filters from request
|
||||
filters.keySet().forEach(f -> report.filter(f, filters.getSet(f)));
|
||||
|
||||
// get headers
|
||||
List<String> orderedColumnKeys = report.getColumnKeys();
|
||||
String[] headers = new String[orderedColumnKeys.size()];
|
||||
orderedColumnKeys.toArray(headers);
|
||||
|
||||
if (localeJ != null) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
if (localeJ.has(headers[i]))
|
||||
headers[i] = localeJ.get(headers[i]).getAsString();
|
||||
}
|
||||
}
|
||||
|
||||
// create CSV printer with header
|
||||
StreamingOutput out = getOut(report, headers);
|
||||
|
||||
// send
|
||||
String fileName = id + "_" + System.currentTimeMillis() + ".csv";
|
||||
return Response.ok(out, TEXT_CSV_TYPE)
|
||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build();
|
||||
}
|
||||
}
|
||||
|
||||
private StreamingOutput getOut(Report report, String[] headers) {
|
||||
return out -> {
|
||||
|
||||
// get report content and add to the buffer
|
||||
try (CSVPrinter csvP = new CSVPrinter(new OutputStreamWriter(out),
|
||||
CSVFormat.DEFAULT.withHeader(headers).withDelimiter(';'))) {
|
||||
report.doReport().forEach(row -> {
|
||||
try {
|
||||
csvP.printRecord(row.valueStream().collect(Collectors.toList())); // add to CSV
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not write CSV row", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private MapOfSets<String, String> getFiltersFromJson(JsonArray filters) {
|
||||
MapOfSets<String, String> result = new MapOfSets<>();
|
||||
if (filters == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// go through all filters and add to the map of sets
|
||||
for (JsonElement elem : filters.getAsJsonArray()) {
|
||||
if (!elem.isJsonObject()) {
|
||||
logger.warn("There are wrong formated filters:\n" + elem.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject filter = elem.getAsJsonObject();
|
||||
filter.get(PARAM_FACET_FILTERS).getAsJsonArray()
|
||||
.forEach(f -> result.addElement(filter.get(PARAM_FACET_TYPE).getAsString(), f.getAsString()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package li.strolch.execution.policy;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.exception.StrolchModelException;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -29,7 +31,6 @@ import li.strolch.persistence.api.StrolchTransaction;
|
|||
public class ReservationExection extends DurationExecution {
|
||||
|
||||
public static final String PARAM_RESERVED = "reserved";
|
||||
public static final String BAG_PARAMETERS = "parameters";
|
||||
public static final String TYPE_RESERVE = "Reserve";
|
||||
public static final String TYPE_RELEASE = "Release";
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package li.strolch.migrations;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -15,11 +15,8 @@
|
|||
*/
|
||||
package li.strolch.migrations;
|
||||
|
||||
import static li.strolch.migrations.Migration.BAG_PARAMETERS;
|
||||
import static li.strolch.migrations.Migration.MIGRATIONS_ID;
|
||||
import static li.strolch.migrations.Migration.MIGRATIONS_TYPE;
|
||||
import static li.strolch.migrations.Migration.PARAM_CURRENT_DATA_VERSION;
|
||||
import static li.strolch.migrations.Migration.PARAM_CURRENT_CODE_VERSION;
|
||||
import static li.strolch.migrations.Migration.*;
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -38,9 +35,6 @@ public class CurrentMigrationVersionQuery {
|
|||
private ComponentContainer container;
|
||||
private Map<String, MigrationVersion> currentVersions;
|
||||
|
||||
/**
|
||||
* @param container
|
||||
*/
|
||||
public CurrentMigrationVersionQuery(ComponentContainer container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
@ -56,47 +50,45 @@ public class CurrentMigrationVersionQuery {
|
|||
|
||||
Resource migrationsRes = tx.getResourceBy(MIGRATIONS_TYPE, MIGRATIONS_ID);
|
||||
if (migrationsRes == null) {
|
||||
this.currentVersions.put(realmName, new MigrationVersion(Version.emptyVersion,Version.emptyVersion));
|
||||
this.currentVersions
|
||||
.put(realmName, new MigrationVersion(Version.emptyVersion, Version.emptyVersion));
|
||||
continue;
|
||||
}
|
||||
|
||||
StringParameter currentDataVersionP = migrationsRes.getParameter(BAG_PARAMETERS, PARAM_CURRENT_DATA_VERSION);
|
||||
StringParameter currentCodeVersionP = migrationsRes.getParameter(BAG_PARAMETERS, PARAM_CURRENT_CODE_VERSION);
|
||||
|
||||
StringParameter currentDataVersionP = migrationsRes
|
||||
.getParameter(BAG_PARAMETERS, PARAM_CURRENT_DATA_VERSION);
|
||||
StringParameter currentCodeVersionP = migrationsRes
|
||||
.getParameter(BAG_PARAMETERS, PARAM_CURRENT_CODE_VERSION);
|
||||
|
||||
if (currentDataVersionP == null && currentCodeVersionP == null) {
|
||||
this.currentVersions.put(realmName, new MigrationVersion(Version.emptyVersion,Version.emptyVersion));
|
||||
} else if(currentDataVersionP == null && currentCodeVersionP != null) {
|
||||
this.currentVersions
|
||||
.put(realmName, new MigrationVersion(Version.emptyVersion, Version.emptyVersion));
|
||||
} else if (currentDataVersionP == null) {
|
||||
Version codeVersion = getVersionFromParam(currentCodeVersionP);
|
||||
this.currentVersions.put(realmName, new MigrationVersion(Version.emptyVersion,codeVersion));
|
||||
} else if (currentDataVersionP != null && currentCodeVersionP == null) {
|
||||
this.currentVersions.put(realmName, new MigrationVersion(Version.emptyVersion, codeVersion));
|
||||
} else if (currentCodeVersionP == null) {
|
||||
Version dataVersion = getVersionFromParam(currentDataVersionP);
|
||||
this.currentVersions.put(realmName, new MigrationVersion(dataVersion,Version.emptyVersion));
|
||||
this.currentVersions.put(realmName, new MigrationVersion(dataVersion, Version.emptyVersion));
|
||||
} else {
|
||||
Version dataVersion = getVersionFromParam(currentDataVersionP);
|
||||
Version codeVersion = getVersionFromParam(currentCodeVersionP);
|
||||
this.currentVersions.put(realmName, new MigrationVersion(dataVersion,codeVersion));
|
||||
this.currentVersions.put(realmName, new MigrationVersion(dataVersion, codeVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionS
|
||||
* @return
|
||||
*/
|
||||
private Version getVersionFromParam(StringParameter versionP) {
|
||||
String versionS = versionP.getValue();
|
||||
if (!Version.isParseable(versionS)) {
|
||||
throw new StrolchConfigurationException("Version value " + versionS + " is not valid for "
|
||||
+ versionP.getLocator());
|
||||
throw new StrolchConfigurationException(
|
||||
"Version value " + versionS + " is not valid for " + versionP.getLocator());
|
||||
}
|
||||
|
||||
Version version = Version.valueOf(versionS);
|
||||
return version;
|
||||
return Version.valueOf(versionS);
|
||||
}
|
||||
|
||||
public Map<String, MigrationVersion> getCurrentVersions() {
|
||||
return this.currentVersions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package li.strolch.migrations;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package li.strolch.migrations;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
|
@ -31,7 +33,6 @@ public abstract class Migration {
|
|||
|
||||
public static final String MIGRATIONS_TYPE = "Migrations";
|
||||
public static final String MIGRATIONS_ID = "migrations";
|
||||
public static final String BAG_PARAMETERS = "parameters";
|
||||
public static final String PARAM_CURRENT_DATA_VERSION = "currentDataVersion";
|
||||
public static final String PARAM_CURRENT_CODE_VERSION = "currentCodeVersion";
|
||||
|
||||
|
|
|
@ -5,9 +5,7 @@ public class ReportConstants {
|
|||
public static final String TYPE_REPORT = "Report";
|
||||
public static final String TYPE_FILTER = "Filter";
|
||||
|
||||
public static final String BAG_RELATIONS = "relations";
|
||||
public static final String BAG_JOINS = "joins";
|
||||
public static final String BAG_PARAMETERS = "parameters";
|
||||
public static final String BAG_COLUMNS = "columns";
|
||||
public static final String BAG_ORDERING = "ordering";
|
||||
|
||||
|
@ -15,8 +13,14 @@ public class ReportConstants {
|
|||
public static final String PARAM_DESCENDING = "descending";
|
||||
public static final String PARAM_DATE_RANGE_SEL = "dateRangeSel";
|
||||
public static final String PARAM_FIELD_REF = "fieldRef";
|
||||
public static final String PARAM_POLICY = "policy";
|
||||
public static final String PARAM_ALLOW_MISSING_COLUMNS = "allowMissingColumns";
|
||||
public static final String PARAM_POLICY = "policy";
|
||||
|
||||
public static final String PARAM_COLUMNS = "columns";
|
||||
public static final String PARAM_ROWS = "rows";
|
||||
public static final String PARAM_DURATION = "duration";
|
||||
public static final String PARAM_FACET_FILTERS = "facetFilters";
|
||||
public static final String PARAM_FACET_TYPE = "facetType";
|
||||
|
||||
public static final String COL_OBJECT = "$object";
|
||||
public static final String COL_ID = "$id";
|
||||
|
@ -26,8 +30,7 @@ public class ReportConstants {
|
|||
public static final String COL_DATE = "$date";
|
||||
public static final String COL_SEARCH = "$search";
|
||||
|
||||
public static final String LOCALES_JSON = "locales.json";
|
||||
|
||||
public static final String SEARCH_SEPARATOR = ":";
|
||||
|
||||
public static final String SUFFIX_REF = "-Ref";
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package li.strolch.report;
|
||||
|
||||
import static li.strolch.report.ReportConstants.TYPE_REPORT;
|
||||
|
||||
import li.strolch.search.ResourceSearch;
|
||||
|
||||
/**
|
||||
* Query to get report resources
|
||||
*
|
||||
* @author mvoigt
|
||||
*/
|
||||
public class ReportSearch extends ResourceSearch {
|
||||
|
||||
public ReportSearch() {
|
||||
types(TYPE_REPORT);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package li.strolch.report.policy;
|
||||
|
||||
import static java.util.Comparator.comparingInt;
|
||||
import static li.strolch.model.StrolchModelConstants.*;
|
||||
import static li.strolch.report.ReportConstants.*;
|
||||
import static li.strolch.utils.helper.StringHelper.EMPTY;
|
||||
|
||||
|
@ -10,6 +11,7 @@ import java.util.stream.Collector;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.model.*;
|
||||
import li.strolch.model.parameter.AbstractParameter;
|
||||
|
@ -39,8 +41,6 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
private Resource reportRes;
|
||||
|
||||
private String objectType;
|
||||
|
||||
private ParameterBag columnsBag;
|
||||
private List<StringParameter> orderingParams;
|
||||
private Map<String, StringParameter> filterCriteriaParams;
|
||||
|
@ -55,13 +55,15 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
private long counter;
|
||||
|
||||
protected JsonObject i18nData;
|
||||
|
||||
public GenericReport(ComponentContainer container, StrolchTransaction tx) {
|
||||
super(container, tx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>Resource</code> with the given ID, and initializes this instance with the data specified on
|
||||
* the report
|
||||
* Retrieves the {@code Resource} with the given ID, and initializes this instance with the data specified on the
|
||||
* report
|
||||
*
|
||||
* @param reportId
|
||||
* the report to use
|
||||
|
@ -72,7 +74,7 @@ public class GenericReport extends ReportPolicy {
|
|||
this.reportRes = tx().getResourceBy(TYPE_REPORT, reportId, true);
|
||||
|
||||
StringParameter objectTypeP = this.reportRes.getParameter(BAG_PARAMETERS, PARAM_OBJECT_TYPE);
|
||||
this.objectType = objectTypeP.getValue();
|
||||
String objectType = objectTypeP.getValue();
|
||||
|
||||
this.columnsBag = this.reportRes.getParameterBag(BAG_COLUMNS, true);
|
||||
|
||||
|
@ -92,8 +94,8 @@ public class GenericReport extends ReportPolicy {
|
|||
// evaluate filter criteria params
|
||||
this.filterCriteriaParams = new HashMap<>();
|
||||
StringParameter objectTypeFilterCriteriaP = objectTypeP.getClone();
|
||||
objectTypeFilterCriteriaP.setId(this.objectType);
|
||||
this.filterCriteriaParams.put(this.objectType, objectTypeFilterCriteriaP);
|
||||
objectTypeFilterCriteriaP.setId(objectType);
|
||||
this.filterCriteriaParams.put(objectType, objectTypeFilterCriteriaP);
|
||||
if (this.reportRes.hasParameterBag(BAG_JOINS)) {
|
||||
ParameterBag joinBag = this.reportRes.getParameterBag(BAG_JOINS);
|
||||
joinBag.getParameters()
|
||||
|
@ -127,6 +129,10 @@ public class GenericReport extends ReportPolicy {
|
|||
}
|
||||
}
|
||||
|
||||
public void setI18nData(JsonObject i18nData) {
|
||||
this.i18nData = i18nData;
|
||||
}
|
||||
|
||||
public long getCounter() {
|
||||
return this.counter;
|
||||
}
|
||||
|
@ -134,7 +140,7 @@ public class GenericReport extends ReportPolicy {
|
|||
/**
|
||||
* Returns true if the report has a date range selector specified
|
||||
*
|
||||
* @return
|
||||
* @return true if the report has a date range selector specified
|
||||
*/
|
||||
public boolean hasDateRangeSelector() {
|
||||
return this.dateRangeSelP != null;
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.model.StrolchRootElement;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
@ -19,6 +20,8 @@ public abstract class ReportPolicy extends StrolchPolicy {
|
|||
super(container, tx);
|
||||
}
|
||||
|
||||
public abstract void setI18nData(JsonObject i18nData);
|
||||
|
||||
public abstract void initialize(String reportId);
|
||||
|
||||
public abstract boolean hasDateRangeSelector();
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
package li.strolch.execution;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static li.strolch.execution.policy.ReservationExection.PARAM_RESERVED;
|
||||
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.execution.policy.ReservationExection;
|
||||
import li.strolch.execution.service.StartActivityExecutionService;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.Resource;
|
||||
|
@ -25,6 +20,9 @@ import li.strolch.service.LocatorArgument;
|
|||
import li.strolch.service.parameter.SetParameterService;
|
||||
import li.strolch.service.parameter.SetParameterService.SetParameterArg;
|
||||
import li.strolch.testbase.runtime.RuntimeMock;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ReservationExecutionTest extends RuntimeMock {
|
||||
|
||||
|
@ -50,8 +48,8 @@ public class ReservationExecutionTest extends RuntimeMock {
|
|||
// before we execute, we reserve, so execution can't be done
|
||||
SetParameterService setParamSvc = new SetParameterService();
|
||||
SetParameterArg setParamArg = new SetParameterArg();
|
||||
setParamArg.locator = Locator.valueOf(Tags.RESOURCE, "Machine", "machine1", Tags.BAG,
|
||||
ReservationExection.BAG_PARAMETERS, ReservationExection.PARAM_RESERVED);
|
||||
setParamArg.locator = Locator
|
||||
.valueOf(Tags.RESOURCE, "Machine", "machine1", Tags.BAG, BAG_PARAMETERS, PARAM_RESERVED);
|
||||
setParamArg.valueAsString = "true";
|
||||
|
||||
doServiceAssertResult(cert, setParamSvc, setParamArg);
|
||||
|
@ -84,8 +82,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
|||
|
||||
// verify that the machine is not reserved
|
||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||
BooleanParameter reservedP = machine.getParameter(ReservationExection.BAG_PARAMETERS,
|
||||
ReservationExection.PARAM_RESERVED);
|
||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||
assertFalse(reservedP.getValue());
|
||||
}
|
||||
|
||||
|
@ -107,8 +104,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
|||
|
||||
// verify that the machine is reserved
|
||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||
BooleanParameter reservedP = machine.getParameter(ReservationExection.BAG_PARAMETERS,
|
||||
ReservationExection.PARAM_RESERVED);
|
||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||
assertTrue(reservedP.getValue());
|
||||
}
|
||||
|
||||
|
@ -123,8 +119,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
|||
|
||||
// verify that the machine is not reserved anymore
|
||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||
BooleanParameter reservedP = machine.getParameter(ReservationExection.BAG_PARAMETERS,
|
||||
ReservationExection.PARAM_RESERVED);
|
||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||
assertFalse(reservedP.getValue());
|
||||
}
|
||||
}
|
||||
|
|
7
pom.xml
7
pom.xml
|
@ -87,6 +87,7 @@
|
|||
<javaxmail.version>1.6.0</javaxmail.version>
|
||||
<serverlet.version>3.1.0</serverlet.version>
|
||||
<jaxrs.api.version>2.1</jaxrs.api.version>
|
||||
<csv.version>1.4</csv.version>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<hamcrest.version>1.3</hamcrest.version>
|
||||
|
@ -219,9 +220,9 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.petitparser.java-petitparser</groupId>
|
||||
<artifactId>petitparser-core</artifactId>
|
||||
<version>${petitparser.version}</version>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>${csv.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Database -->
|
||||
|
|
Loading…
Reference in New Issue