use of org.vertx.java.core.eventbus.Message 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.eventbus.Message 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());
}
}
});
}
Aggregations