Implementing library

This commit is contained in:
Luca Frosini 2021-03-16 10:37:52 +01:00
parent 02dd0297f2
commit 24e31d7248
2 changed files with 161 additions and 4 deletions

View File

@ -3,10 +3,13 @@
*/
package org.gcube.accounting.analytics.persistence.postgresql;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
@ -24,6 +27,7 @@ import org.gcube.accounting.datamodel.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.persistence.AccountingPersistenceConfiguration;
import org.gcube.documentstore.records.AggregatedRecord;
import org.gcube.documentstore.records.Record;
import org.gcube.documentstore.records.RecordUtility;
import org.json.JSONObject;
import org.slf4j.Logger;
@ -36,6 +40,8 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceQueryPostgreSQL.class);
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS Z";
public static final String URL_PROPERTY_KEY = AccountingPersistenceConfiguration.URL_PROPERTY_KEY;
public static final String PASSWORD_PROPERTY_KEY = AccountingPersistenceConfiguration.PASSWORD_PROPERTY_KEY;
@ -43,11 +49,13 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
protected Map<String,String> connectionMap;
protected static Map<Class<? extends AggregatedRecord<?, ?>>, String> recordTypes;
static {
// One Record per package is enough
RecordUtility.addRecordPackage(ServiceUsageRecord.class.getPackage());
RecordUtility.addRecordPackage(AggregatedServiceUsageRecord.class.getPackage());
recordTypes = new HashMap<>();
}
@Override
@ -57,7 +65,28 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
this.configuration = configuration;
this.connectionMap = new HashMap<>();
}
protected static String getRecordTypeByClass(Class<? extends AggregatedRecord<?, ?>> clz) {
try {
Record r = clz.newInstance();
return r.getRecordType();
}catch (Exception e) {
String type = clz.getSimpleName();
type = type.replace("Abstract", "");
type = type.replace("Aggregated", "");
return type;
}
}
protected static String getRecordType(Class<? extends AggregatedRecord<?, ?>> clz) {
String type = recordTypes.get(clz);
if(type == null) {
type = getRecordTypeByClass(clz);
recordTypes.put(clz, type);
}
return type;
}
@Override
public SortedMap<Calendar, Info> getTimeSeries(Class<? extends AggregatedRecord<?, ?>> clz,
TemporalConstraint temporalConstraint, List<Filter> filters)
@ -65,12 +94,115 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
// TODO Auto-generated method stub
return null;
}
protected void appendString(StringBuffer query, String string) {
query.append("'");
query.append(string);
query.append("'");
}
protected void appendValue(StringBuffer values, Serializable serializable) {
if(serializable instanceof Number) {
values.append(serializable.toString());
return;
}
if(serializable instanceof Calendar) {
Calendar calendar = (Calendar) serializable;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATETIME_PATTERN);
String date = simpleDateFormat.format(calendar.getTime());
appendString(values, date);
return;
}
if(serializable instanceof Enum) {
Enum<?> e = (Enum<?>) serializable;
appendString(values, e.name());
return;
}
// String, URI etc
appendString(values, serializable.toString());
}
protected void appendKey(StringBuffer query, String fieldName) {
int lenght = fieldName.length();
boolean lastLowerCase = true;
for (int i=0; i<lenght; i++) {
Character ch = fieldName.charAt(i); /*traversing String one by one*/
if (Character.isUpperCase(ch)) {
if(lastLowerCase) {
query.append("_");
}
lastLowerCase = false;
}else {
lastLowerCase = true;
}
query.append(Character.toLowerCase(ch));
}
}
/* this solution does not works because postgres deos not support upper case charaters
protected void appendKeyAs(StringBuffer query, String fieldName) {
appendKey(query, fieldName);
query.append(" AS ");
query.append(fieldName);
}
*/
protected String getNoContextTimeSeriesQuery(Class<? extends AggregatedRecord<?, ?>> clz,
TemporalConstraint temporalConstraint, List<Filter> filters)
throws DuplicatedKeyFilterException, KeyException, ValueException, Exception {
Set<String> aggregatedField = clz.newInstance().getAggregatedFields();
StringBuffer query = new StringBuffer();
query.append("SELECT ");
/*
* We want StartTime as first field for this reason has been
* excluded from cycle
*/
appendKey(query, AggregatedRecord.START_TIME);
for(String fieldName : aggregatedField) {
switch (fieldName) {
case AggregatedRecord.START_TIME:
case AggregatedRecord.END_TIME:
case AggregatedRecord.AGGREGATED:
continue;
default:
query.append(", ");
appendKey(query, fieldName);
break;
}
}
query.append(" FROM ");
query.append(getRecordType(clz));
query.append(" WHERE ");
appendKey(query, AggregatedRecord.START_TIME);
query.append(" > ");
appendValue(query, temporalConstraint.getAlignedStartTime());
query.append(" AND ");
appendKey(query, AggregatedRecord.START_TIME);
query.append(" < ");
appendValue(query, temporalConstraint.getAlignedEndTime());
return query.toString();
}
@Override
public SortedMap<Calendar, Info> getNoContextTimeSeries(Class<? extends AggregatedRecord<?, ?>> clz,
TemporalConstraint temporalConstraint, List<Filter> filters)
throws DuplicatedKeyFilterException, KeyException, ValueException, Exception {
// TODO Auto-generated method stub
return null;
}

View File

@ -3,6 +3,14 @@
*/
package org.gcube.accounting.analytics.persistence.postgresql;
import java.util.Calendar;
import org.gcube.accounting.analytics.TemporalConstraint;
import org.gcube.accounting.analytics.TemporalConstraint.AggregationMode;
import org.gcube.accounting.analytics.exception.DuplicatedKeyFilterException;
import org.gcube.accounting.analytics.exception.KeyException;
import org.gcube.accounting.analytics.exception.ValueException;
import org.gcube.accounting.datamodel.aggregation.AggregatedServiceUsageRecord;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,8 +23,25 @@ public class AccountingPersistenceQueryPostgreSQLTest extends ContextTest {
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceQueryPostgreSQLTest.class);
@Test
public void test() {
public void testGetNoContextTimeSeriesQuery() throws DuplicatedKeyFilterException, KeyException, ValueException, Exception {
logger.debug("test");
Calendar startTimeCalendar = Calendar.getInstance();
startTimeCalendar.set(Calendar.MONTH, Calendar.MARCH);
startTimeCalendar.set(Calendar.DAY_OF_MONTH, 15);
startTimeCalendar.set(Calendar.HOUR_OF_DAY, 16);
startTimeCalendar.set(Calendar.MINUTE, 15);
Calendar entTimeCalendar = Calendar.getInstance();
entTimeCalendar.set(Calendar.MONTH, Calendar.MARCH);
entTimeCalendar.set(Calendar.DAY_OF_MONTH, 15);
entTimeCalendar.set(Calendar.HOUR_OF_DAY, 16);
entTimeCalendar.set(Calendar.MINUTE, 17);
TemporalConstraint temporalConstraint = new TemporalConstraint(startTimeCalendar.getTimeInMillis(), entTimeCalendar.getTimeInMillis(), AggregationMode.MINUTELY);
AccountingPersistenceQueryPostgreSQL accountingPersistenceQueryPostgreSQL = new AccountingPersistenceQueryPostgreSQL();
String ret = accountingPersistenceQueryPostgreSQL.getNoContextTimeSeriesQuery(AggregatedServiceUsageRecord.class, temporalConstraint, null);
logger.debug(ret);
}
}