use of org.vertx.java.core.json.JsonArray in project statistics by OPEN-ENT-NG.
the class StatisticsServiceMongoImpl method getStatistics.
private void getStatistics(final List<String> schoolIds, final JsonObject params, final Handler<Either<String, JsonArray>> handler, boolean isExport) {
if (schoolIds == null || schoolIds.isEmpty()) {
throw new IllegalArgumentException("schoolIds is null or empty");
}
String indicator = params.getString(PARAM_INDICATOR);
Long start = (Long) params.getNumber(PARAM_START_DATE);
Long end = (Long) params.getNumber(PARAM_END_DATE);
boolean isActivatedAccountsIndicator = STATS_FIELD_ACTIVATED_ACCOUNTS.equals(indicator);
boolean isAccessIndicator = TRACE_TYPE_SVC_ACCESS.equals(indicator);
String groupedBy = isAccessIndicator ? "module/structures/profil" : "structures/profil";
final QueryBuilder criteriaQuery = QueryBuilder.start(STATS_FIELD_GROUPBY).is(groupedBy).and(STATS_FIELD_DATE).greaterThanEquals(formatTimestamp(start)).lessThan(formatTimestamp(end)).and(indicator).exists(true);
String module = params.getString(PARAM_MODULE);
boolean moduleIsEmpty = module == null || module.trim().isEmpty();
boolean isAccessAllModules = isAccessIndicator && moduleIsEmpty;
if (isAccessIndicator && !moduleIsEmpty) {
criteriaQuery.and(MODULE_ID).is(module);
}
if (schoolIds.size() > 1) {
criteriaQuery.and(STRUCTURES_ID).in(schoolIds);
} else {
criteriaQuery.and(STRUCTURES_ID).is(schoolIds.get(0));
// When getting data for only one module, a "find" is enough (no need to aggregate data)
if (!isExport && !isAccessAllModules) {
JsonObject projection = new JsonObject();
projection.putNumber("_id", 0).putNumber(indicator, 1).putNumber(PROFILE_ID, 1).putNumber(STATS_FIELD_DATE, 1);
if (isActivatedAccountsIndicator) {
projection.putNumber(STATS_FIELD_ACCOUNTS, 1);
}
mongo.find(collection, MongoQueryBuilder.build(criteriaQuery), sortByDateProfile, projection, MongoDbResult.validResultsHandler(handler));
return;
}
}
// Aggregate data
final JsonObject aggregation = new JsonObject();
JsonArray pipeline = new JsonArray();
aggregation.putString("aggregate", collection).putBoolean("allowDiskUse", true).putArray("pipeline", pipeline);
pipeline.addObject(new JsonObject().putObject("$match", MongoQueryBuilder.build(criteriaQuery)));
JsonObject id = new JsonObject().putString(PROFILE_ID, "$" + PROFILE_ID);
if (isAccessAllModules && !isExport) {
// Case : get JSON data for indicator "access to all modules"
id.putString(MODULE_ID, "$" + MODULE_ID);
} else {
id.putString(STATS_FIELD_DATE, "$" + STATS_FIELD_DATE);
}
JsonObject group = new JsonObject().putObject("_id", id).putObject(indicator, new JsonObject().putString("$sum", "$" + indicator));
if (isActivatedAccountsIndicator) {
group.putObject(STATS_FIELD_ACCOUNTS, new JsonObject().putString("$sum", "$" + STATS_FIELD_ACCOUNTS));
}
JsonObject groupBy = new JsonObject().putObject("$group", group);
pipeline.addObject(groupBy);
QueryBuilder projection = QueryBuilder.start("_id").is(0).and(PROFILE_ID).is("$_id." + PROFILE_ID);
if (isActivatedAccountsIndicator) {
projection.and(STATS_FIELD_ACCOUNTS).is(1);
}
if (!isExport) {
projection.and(indicator).is(1);
if (isAccessAllModules) {
projection.and(MODULE_ID).is("$_id." + MODULE_ID);
} else {
projection.and(STATS_FIELD_DATE).is("$_id." + STATS_FIELD_DATE);
}
// Sum stats for all structure_ids
pipeline.addObject(new JsonObject().putObject("$project", MongoQueryBuilder.build(projection)));
} else {
// Projection : keep 'yyyy-MM' from 'yyyy-MM-dd HH:mm.ss.SSS'
DBObject dateSubstring = new BasicDBObject();
BasicDBList dbl = new BasicDBList();
dbl.add("$_id." + STATS_FIELD_DATE);
dbl.add(0);
dbl.add(7);
dateSubstring.put("$substr", dbl);
projection.and(STATS_FIELD_DATE).is(dateSubstring).and("indicatorValue").is(// Replace indicatorName by label "indicatorValue", so that the mustache template can be generic
"$" + indicator);
JsonObject sort = sortByStructureDateProfile;
// Export stats for each structure_id
id.putString(STRUCTURES_ID, "$" + STRUCTURES_ID);
projection.and(STRUCTURES_ID).is("$_id." + STRUCTURES_ID);
if (isAccessIndicator) {
if (isAccessAllModules) {
sort = sort.copy().putNumber(MODULE_ID, 1);
}
// Export stats for each module_id
id.putString(MODULE_ID, "$" + MODULE_ID);
projection.and(MODULE_ID).is("$_id." + MODULE_ID);
}
pipeline.addObject(new JsonObject().putObject("$project", MongoQueryBuilder.build(projection)));
pipeline.addObject(new JsonObject().putObject("$sort", sort));
}
mongo.command(aggregation.toString(), new Handler<Message<JsonObject>>() {
@Override
public void handle(Message<JsonObject> message) {
if ("ok".equals(message.body().getString("status")) && message.body().getObject("result", new JsonObject()).getInteger("ok") == 1) {
JsonArray result = message.body().getObject("result").getArray("result");
handler.handle(new Either.Right<String, JsonArray>(result));
} else {
String error = message.body().toString();
handler.handle(new Either.Left<String, JsonArray>(error));
}
}
});
}
use of org.vertx.java.core.json.JsonArray in project statistics by OPEN-ENT-NG.
the class IndicatorCustomImpl method aggregate.
@Override
public void aggregate(final Handler<JsonObject> callBack) {
final Date start = new Date();
this.getAccounts(new Handler<Either<String, JsonArray>>() {
@Override
public void handle(Either<String, JsonArray> event) {
if (event.isLeft()) {
log.error(event.left().getValue());
callBack.handle(new JsonObject());
return;
}
try {
JsonArray results = event.right().getValue();
// If no documents found, write nothing
if (results.size() == 0) {
callBack.handle(new JsonObject());
return;
}
// Synchronization handler
final AtomicInteger countDown = new AtomicInteger(results.size());
Handler<Message<JsonObject>> synchroHandler = new Handler<Message<JsonObject>>() {
@Override
public void handle(Message<JsonObject> message) {
if (!"ok".equals(message.body().getString("status"))) {
log.error("Error in method aggregate of IndicatorCustomImpl : " + message.body().toString());
}
if (countDown.decrementAndGet() == 0) {
final Date end = new Date();
log.info("[Aggregation]{" + IndicatorCustomImpl.this.getKey() + "} Took [" + (end.getTime() - start.getTime()) + "] ms");
callBack.handle(new JsonObject().putString("status", "ok"));
}
}
};
for (int i = 0; i < results.size(); i++) {
JsonObject jo = results.get(i);
String structure = jo.getString("structure");
String profile = jo.getString("profile");
Number accounts = jo.getNumber("accounts");
Number activatedAccounts = jo.getNumber("activatedAccounts");
String date = MongoDb.formatDate(IndicatorCustomImpl.this.getWriteDate());
MongoDBBuilder criteriaQuery = new MongoDBBuilder();
criteriaQuery.put(STATS_FIELD_DATE).is(date).put(STATS_FIELD_GROUPBY).is(TRACE_FIELD_STRUCTURES + "/" + TRACE_FIELD_PROFILE).put(PROFILE_ID).is(profile).put(STRUCTURES_ID).is(structure);
MongoUpdateBuilder update = new MongoUpdateBuilder().set(STATS_FIELD_ACCOUNTS, accounts).set(STATS_FIELD_ACTIVATED_ACCOUNTS, activatedAccounts);
// Upsert data in MongoDB
mongo.update(COLLECTIONS.stats.name(), MongoQueryBuilder.build(criteriaQuery), update.build(), true, true, synchroHandler);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
callBack.handle(new JsonObject());
}
}
});
}
use of org.vertx.java.core.json.JsonArray in project statistics by OPEN-ENT-NG.
the class StatisticsController method generation.
@Get("/generation")
@SecuredAction(value = "", type = ActionType.RESOURCE)
@ResourceFilter(SuperAdminFilter.class)
public /**
* Generation of statistics to mongoDB database. Calls the same treatment as the one called by cron
* Before the generation, deletes the records who will be regenerated.
*/
void generation(final HttpServerRequest request) {
RequestUtils.bodyToJson(request, pathPrefix + "schoolquery", new Handler<JsonObject>() {
@Override
public void handle(JsonObject data) {
// parameters from the model (schoolIdArray / indicator / startDate / endDate / module)
final JsonObject params = data;
UserUtils.getUserInfos(eb, request, new Handler<UserInfos>() {
@Override
public void handle(final UserInfos user) {
final Date startDate = new Date(params.getLong("startDate") * 1000L);
final Date endDate = new Date(params.getLong("endDate") * 1000L);
// final Date startDate = new Date(Long.parseLong(request.params().get(PARAM_START_DATE)) * 1000L);
// final Date endDate = new Date(Long.parseLong(request.params().get(PARAM_END_DATE)) * 1000L);
deleteRegeneratedStatistics(startDate, endDate, new Handler<Either<String, JsonArray>>() {
@Override
public void handle(Either<String, JsonArray> event) {
if (event.isLeft()) {
log.error(event.left().getValue());
renderError(request);
} else {
if (user != null) {
Statistics st = new Statistics();
st.aggregateEvents(StatisticsController.this.vertx, startDate, endDate);
JsonArray jarray = new JsonArray();
jarray.add(String.valueOf(params.getInteger("startDate")));
renderJson(request, jarray);
}
}
}
});
}
});
}
});
}
use of org.vertx.java.core.json.JsonArray in project statistics by OPEN-ENT-NG.
the class Statistics method start.
@Override
public void start() {
super.start();
JsonArray accessModules = container.config().getArray("access-modules", null);
if (accessModules == null || accessModules.size() == 0) {
log.error("Parameter access-modules is null or empty");
return;
}
// 1) Schedule daily aggregation
/* By default, fire aggregate-cron at 1:15am every day.
* Be careful when setting fire times between midnight and 1:00 AM
* - "daylight savings" can cause a skip or a repeat depending on whether the time moves back or jumps forward.
*/
final String aggregateEventsCron = container.config().getString("aggregate-cron", "0 15 1 ? * * *");
AggregateTask aggTask = new AggregateTask();
try {
new CronTrigger(vertx, aggregateEventsCron).schedule(aggTask);
} catch (ParseException e) {
log.fatal(e.getMessage(), e);
return;
}
// In development environment, launch aggregations if parameter "aggregateOnStart" is set to true in module configuration
if ("dev".equals(container.config().getString("mode", null)) && container.config().getBoolean("aggregateOnStart", false)) {
Date startDate = new Date();
// Thu, 30 Apr 2015 00:00:00 GMT
startDate.setTime(1430352000000L);
Date endDate = new Date();
// Fri, 01 May 2015 00:00:00 GMT
endDate.setTime(1430438400000L);
this.aggregateEvents(vertx, startDate, endDate);
}
// 2) Init controller
addController(new StatisticsController(vertx, MongoConstants.COLLECTIONS.stats.toString(), accessModules));
MongoDbConf.getInstance().setCollection(MongoConstants.COLLECTIONS.stats.toString());
// FIXME : the statistics will be kept one year to antoher. No repositoryEvents management
}
Aggregations