2015-07-08 15:24:32 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
package org.gcube.accounting.analytics;
|
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Calendar;
|
2015-12-18 17:13:22 +01:00
|
|
|
import java.util.Collection;
|
2015-07-09 16:39:25 +02:00
|
|
|
import java.util.HashMap;
|
2015-07-21 16:33:36 +02:00
|
|
|
import java.util.Iterator;
|
2015-07-08 15:24:32 +02:00
|
|
|
import java.util.List;
|
2015-07-09 16:39:25 +02:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
2015-07-08 15:24:32 +02:00
|
|
|
|
2015-07-13 15:34:52 +02:00
|
|
|
import org.gcube.accounting.analytics.exception.NoAvailableScopeException;
|
|
|
|
import org.gcube.accounting.analytics.exception.NoUsableAccountingPersistenceQueryFound;
|
2015-10-14 15:10:06 +02:00
|
|
|
import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQuery;
|
|
|
|
import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQueryFactory;
|
2015-12-18 17:13:22 +01:00
|
|
|
import org.gcube.documentstore.records.AggregatedRecord;
|
|
|
|
import org.gcube.documentstore.records.Record;
|
|
|
|
import org.gcube.documentstore.records.RecordUtility;
|
2015-07-21 16:33:36 +02:00
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
2015-07-09 16:39:25 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2015-07-08 15:24:32 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
|
|
|
*/
|
|
|
|
public class ResourceRecordQuery {
|
2016-03-16 13:29:03 +01:00
|
|
|
|
|
|
|
private static Logger logger = LoggerFactory
|
|
|
|
.getLogger(ResourceRecordQuery.class);
|
|
|
|
|
2015-12-18 17:13:22 +01:00
|
|
|
protected static Map<Class<? extends Record>, Set<String>> resourceRecords = null;
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-09-07 16:36:08 +02:00
|
|
|
/**
|
2016-03-16 13:29:03 +01:00
|
|
|
* Return a Map containing a set of required fields for each Resource
|
2015-09-07 16:36:08 +02:00
|
|
|
* Records Types
|
2016-03-16 13:29:03 +01:00
|
|
|
*
|
2015-09-07 16:36:08 +02:00
|
|
|
* @return the Map
|
|
|
|
*/
|
2015-12-18 17:13:22 +01:00
|
|
|
public static synchronized Map<Class<? extends Record>, Set<String>> getResourceRecordsTypes() {
|
2016-03-16 13:29:03 +01:00
|
|
|
if (resourceRecords == null) {
|
2015-12-18 17:13:22 +01:00
|
|
|
resourceRecords = new HashMap<Class<? extends Record>, Set<String>>();
|
2016-03-16 13:29:03 +01:00
|
|
|
Collection<Class<? extends Record>> resourceRecordsTypes = RecordUtility
|
|
|
|
.getRecordClassesFound().values();
|
|
|
|
for (Class<? extends Record> resourceRecordsType : resourceRecordsTypes) {
|
2015-07-09 16:39:25 +02:00
|
|
|
try {
|
2015-12-18 17:13:22 +01:00
|
|
|
Record record = resourceRecordsType.newInstance();
|
2016-03-16 13:29:03 +01:00
|
|
|
resourceRecords.put(resourceRecordsType,
|
|
|
|
record.getRequiredFields());
|
2015-07-09 16:39:25 +02:00
|
|
|
} catch (InstantiationException | IllegalAccessException e) {
|
2016-03-16 13:29:03 +01:00
|
|
|
logger.error(String.format(
|
|
|
|
"Unable to correctly istantiate %s",
|
|
|
|
resourceRecordsType.getSimpleName()), e);
|
2015-07-09 16:39:25 +02:00
|
|
|
}
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-09 16:39:25 +02:00
|
|
|
}
|
|
|
|
return resourceRecords;
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-10-14 15:10:06 +02:00
|
|
|
protected AccountingPersistenceBackendQuery accountingPersistenceQuery;
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-09-07 16:36:08 +02:00
|
|
|
/**
|
|
|
|
* Instantiate the ResourceRecord for the current scope
|
2016-03-16 13:29:03 +01:00
|
|
|
*
|
|
|
|
* @throws NoAvailableScopeException
|
|
|
|
* if there is not possible to query in the current scope
|
|
|
|
* @throws NoUsableAccountingPersistenceQueryFound
|
|
|
|
* if there is no available instance which can query in that
|
|
|
|
* scope
|
2015-09-07 16:36:08 +02:00
|
|
|
*/
|
2016-03-16 13:29:03 +01:00
|
|
|
public ResourceRecordQuery() throws NoAvailableScopeException,
|
|
|
|
NoUsableAccountingPersistenceQueryFound {
|
|
|
|
this.accountingPersistenceQuery = AccountingPersistenceBackendQueryFactory
|
|
|
|
.getInstance();
|
2015-07-13 15:34:52 +02:00
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
|
|
|
protected static JSONObject getPaddingJSONObject(
|
|
|
|
Map<Calendar, Info> unpaddedResults) throws JSONException {
|
2015-07-21 16:33:36 +02:00
|
|
|
Info auxInfo = new ArrayList<Info>(unpaddedResults.values()).get(0);
|
2016-03-16 13:29:03 +01:00
|
|
|
JSONObject auxJsonObject = auxInfo.getValue();
|
2015-07-21 16:33:36 +02:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Iterator<String> keys = auxJsonObject.keys();
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
JSONObject jsonObject = new JSONObject();
|
2016-03-16 13:29:03 +01:00
|
|
|
while (keys.hasNext()) {
|
2015-07-21 16:33:36 +02:00
|
|
|
String key = keys.next();
|
|
|
|
jsonObject.put(key, 0);
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
return jsonObject;
|
2015-07-08 15:24:32 +02:00
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-09-07 16:36:08 +02:00
|
|
|
/**
|
|
|
|
* Pad the data
|
2016-03-16 13:29:03 +01:00
|
|
|
*
|
|
|
|
* @param unpaddedData
|
|
|
|
* the data to be pad
|
|
|
|
* @param temporalConstraint
|
|
|
|
* temporalConstraint the temporal interval and the granularity
|
|
|
|
* of the data to pad
|
2015-09-07 16:36:08 +02:00
|
|
|
* @return the data padded taking in account the TemporalConstraint
|
2016-03-16 13:29:03 +01:00
|
|
|
* @throws Exception
|
|
|
|
* if fails
|
2015-09-07 16:36:08 +02:00
|
|
|
*/
|
2016-03-16 13:29:03 +01:00
|
|
|
public static List<Info> getPaddedResults(Map<Calendar, Info> unpaddedData,
|
2015-09-07 16:36:08 +02:00
|
|
|
TemporalConstraint temporalConstraint) throws Exception {
|
|
|
|
JSONObject jsonObject = getPaddingJSONObject(unpaddedData);
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
List<Info> paddedResults = new ArrayList<Info>();
|
|
|
|
List<Calendar> sequence = temporalConstraint.getCalendarSequence();
|
|
|
|
|
2016-03-16 13:29:03 +01:00
|
|
|
for (Calendar progressTime : sequence) {
|
|
|
|
if (unpaddedData.get(progressTime) != null) {
|
2015-09-07 16:36:08 +02:00
|
|
|
paddedResults.add(unpaddedData.get(progressTime));
|
2016-03-16 13:29:03 +01:00
|
|
|
} else {
|
2015-09-08 11:49:47 +02:00
|
|
|
Info info = new Info(progressTime, jsonObject);
|
2015-07-21 16:33:36 +02:00
|
|
|
paddedResults.add(info);
|
|
|
|
}
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
return paddedResults;
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
/**
|
|
|
|
* Return results with padding if pad is set to true.
|
2016-03-16 13:29:03 +01:00
|
|
|
*
|
|
|
|
* @param aggregatedRecordClass
|
|
|
|
* the UsageRecord type to query
|
|
|
|
* @param temporalConstraint
|
|
|
|
* the temporal interval and the granularity
|
|
|
|
* @param filters
|
|
|
|
* the list keys to filter (in AND)
|
|
|
|
* @param pad
|
|
|
|
* indicate is the results have to be padded with zeros when
|
|
|
|
* there is no data available at certain data points of sequence
|
|
|
|
* @return the requested list of Info
|
|
|
|
* @throws Exception
|
|
|
|
* if fails
|
2015-07-21 16:33:36 +02:00
|
|
|
*/
|
2016-03-16 13:29:03 +01:00
|
|
|
public List<Info> getInfo(
|
|
|
|
Class<? extends AggregatedRecord<?,?>> aggregatedRecordClass,
|
|
|
|
TemporalConstraint temporalConstraint, List<Filter> filters,
|
|
|
|
boolean pad) throws Exception {
|
|
|
|
|
|
|
|
Map<Calendar, Info> unpaddedResults = accountingPersistenceQuery
|
|
|
|
.getTimeSeries(aggregatedRecordClass, temporalConstraint,
|
|
|
|
filters);
|
|
|
|
|
|
|
|
if (!pad) {
|
2015-07-21 16:33:36 +02:00
|
|
|
return new ArrayList<Info>(unpaddedResults.values());
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
return getPaddedResults(unpaddedResults, temporalConstraint);
|
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-21 16:33:36 +02:00
|
|
|
/**
|
2015-09-07 16:36:08 +02:00
|
|
|
* Return unpadded results
|
2016-03-16 13:29:03 +01:00
|
|
|
*
|
|
|
|
* @param aggregatedRecordClass
|
|
|
|
* the UsageRecord type to query
|
|
|
|
* @param temporalConstraint
|
|
|
|
* the temporal interval and the granularity
|
|
|
|
* @param filters
|
|
|
|
* the list keys to filter (in AND)
|
|
|
|
* @return the requested list of Info
|
|
|
|
* @throws Exception
|
|
|
|
* if fails
|
2015-09-08 17:04:56 +02:00
|
|
|
*/
|
2016-03-16 13:29:03 +01:00
|
|
|
public List<Info> getInfo(
|
|
|
|
Class<? extends AggregatedRecord<?,?>> aggregatedRecordClass,
|
|
|
|
TemporalConstraint temporalConstraint, List<Filter> filters)
|
|
|
|
throws Exception {
|
|
|
|
|
|
|
|
return getInfo(aggregatedRecordClass, temporalConstraint, filters,
|
|
|
|
false);
|
|
|
|
|
2015-10-01 17:35:09 +02:00
|
|
|
}
|
2016-03-16 13:29:03 +01:00
|
|
|
|
2015-07-08 15:24:32 +02:00
|
|
|
}
|