diff --git a/src/main/java/org/gcube/accounting/analytics/exception/DuplicatedKeyFilterException.java b/src/main/java/org/gcube/accounting/analytics/exception/DuplicatedKeyFilterException.java
new file mode 100644
index 0000000..3ec3e89
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/analytics/exception/DuplicatedKeyFilterException.java
@@ -0,0 +1,70 @@
+/**
+ *
+ */
+package org.gcube.accounting.analytics.exception;
+
+/**
+ * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
+ *
+ */
+public class DuplicatedKeyFilterException extends Exception {
+
+ /**
+ * Generated serial Version UID
+ */
+ private static final long serialVersionUID = -327144230654860518L;
+
+ /**
+ * Constructs a new exception with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public DuplicatedKeyFilterException() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The cause
+ * is not initialized, and may subsequently be initialized by a call to
+ * initCause.
+ * @param message the detail message. The detail message is saved for later
+ * retrieval by the getMessage() method.
+ */
+ public DuplicatedKeyFilterException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of (cause==null ? null : cause.toString()) (which
+ * typically contains the class and detail message of cause).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public DuplicatedKeyFilterException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
Note that the detail message associated with
+ * {@code cause} is not automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public DuplicatedKeyFilterException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/gcube/accounting/analytics/exception/KeyException.java b/src/main/java/org/gcube/accounting/analytics/exception/KeyException.java
new file mode 100644
index 0000000..02cfa91
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/analytics/exception/KeyException.java
@@ -0,0 +1,70 @@
+/**
+ *
+ */
+package org.gcube.accounting.analytics.exception;
+
+/**
+ * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
+ *
+ */
+public class KeyException extends Exception {
+
+ /**
+ * Generated serial Version UID
+ */
+ private static final long serialVersionUID = -327144230654860518L;
+
+ /**
+ * Constructs a new exception with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public KeyException() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The cause
+ * is not initialized, and may subsequently be initialized by a call to
+ * initCause.
+ * @param message the detail message. The detail message is saved for later
+ * retrieval by the getMessage() method.
+ */
+ public KeyException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of (cause==null ? null : cause.toString()) (which
+ * typically contains the class and detail message of cause).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public KeyException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
Note that the detail message associated with
+ * {@code cause} is not automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public KeyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/gcube/accounting/analytics/exception/ValueException.java b/src/main/java/org/gcube/accounting/analytics/exception/ValueException.java
new file mode 100644
index 0000000..f6a9b35
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/analytics/exception/ValueException.java
@@ -0,0 +1,70 @@
+/**
+ *
+ */
+package org.gcube.accounting.analytics.exception;
+
+/**
+ * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
+ *
+ */
+public class ValueException extends Exception {
+
+ /**
+ * Generated serial Version UID
+ */
+ private static final long serialVersionUID = -327144230654860518L;
+
+ /**
+ * Constructs a new exception with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public ValueException() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The cause
+ * is not initialized, and may subsequently be initialized by a call to
+ * initCause.
+ * @param message the detail message. The detail message is saved for later
+ * retrieval by the getMessage() method.
+ */
+ public ValueException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of (cause==null ? null : cause.toString()) (which
+ * typically contains the class and detail message of cause).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public ValueException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
Note that the detail message associated with
+ * {@code cause} is not automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public ValueException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java
index 04422be..96bf4ca 100644
--- a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java
+++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java
@@ -12,16 +12,19 @@ import org.gcube.accounting.analytics.Filter;
import org.gcube.accounting.analytics.Info;
import org.gcube.accounting.analytics.NumberedFilter;
import org.gcube.accounting.analytics.TemporalConstraint;
+import org.gcube.accounting.analytics.exception.DuplicatedKeyFilterException;
+import org.gcube.accounting.analytics.exception.KeyException;
+import org.gcube.accounting.analytics.exception.ValueException;
import org.gcube.documentstore.records.AggregatedRecord;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
-public abstract class AccountingPersistenceBackendQuery {
+public interface AccountingPersistenceBackendQuery {
public static final int KEY_VALUES_LIMIT = 25;
- protected abstract void prepareConnection(
+ public void prepareConnection(
AccountingPersistenceBackendQueryConfiguration configuration)
throws Exception;
@@ -43,13 +46,16 @@ public abstract class AccountingPersistenceBackendQuery {
* than one filter with the same key an Exception is thrown.
* @return the Map containing for each date in the required interval the
* requested data
+ * @throws DuplicatedKeyFilterException
+ * @throws KeyException
+ * @throws ValueException
* @throws Exception
- * if fails
*/
- public abstract SortedMap getTimeSeries(
- Class extends AggregatedRecord,?>> clz,
+ public SortedMap getTimeSeries(
+ Class extends AggregatedRecord, ?>> clz,
TemporalConstraint temporalConstraint, List filters)
- throws Exception;
+ throws DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception;
/**
* Return a SortedMap containing the TimeSeries for top values for a certain
@@ -63,73 +69,47 @@ public abstract class AccountingPersistenceBackendQuery {
* @param temporalConstraint
* the TemporalConstraint (interval and aggregation)
* @param filters
- * list of filter to obtain the time series. If null or empty
- * list get all data for the interested Record Class with the
- * applying temporal constraint. All Filter (except one) must
- * have not null and not empty key and value. One Filter must
- * have not null and not empty key and a null value. The filters
- * are must be related to different keys and are in AND. If the
- * list contains more than one filter with the same key an
- * Exception is thrown. If the list contains more than one filter
- * with null value an Exception is thrown.
+ * list of filter to obtain the time series of top values. If
+ * null or empty list get all data for the interested Record
+ * Class with the applying temporal constraint. All Filter must
+ * have not null and not empty key and value. The filters are
+ * must be related to different keys and are in AND. If the list
+ * contains more than one filter with the same key an Exception
+ * is thrown.
+ * @param topKey
+ * @param orderingProperty
* @return a SortedMap
+ * @throws DuplicatedKeyFilterException
+ * @throws KeyException
+ * @throws ValueException
* @throws Exception
- * if fails
*/
- public SortedMap> getTopValues(
- Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters)
- throws Exception {
- String orderingProperty = AccountingPersistenceQuery
- .getDefaultOrderingProperties(clz);
- return getTopValues(clz, temporalConstraint, filters,
- orderingProperty);
- }
-
- public abstract SortedMap> getTopValues(
- Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters,
- String orderingProperty) throws Exception;
+ public SortedMap>
+ getTopValues(Class extends AggregatedRecord,?>> clz,
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey, String orderingProperty)
+ throws DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception;
/**
- * Return the list of possible values for a key for a certain usageRecord
- * taking in account all Filters. The value for a certain key is identified
- * adding a Filter with a null value. Only one Filter with null value is
- * allowed otherwise an Exception is thrown. The values are ordered from the
- * most occurred value.
*
* @param clz
- * the Usage Record Class of interest
* @param temporalConstraint
- * the TemporalConstraint (interval and aggregation)
* @param filters
- * list of filter to obtain the time series. If null or empty
- * list get all data for the interested Record Class with the
- * applying temporal constraint. All Filter (except one) must
- * have not null and not empty key and value. One Filter must
- * have not null and not empty key and a null value. The filters
- * are must be related to different keys and are in AND. If the
- * list contains more than one filter with the same key an
- * Exception is thrown. If the list contains more than one filter
- * with null value an Exception is thrown.
- * @return a SortedSet containing the list of possible values
+ * @param topKey
+ * @param orderingProperty
+ * @return
+ * @throws DuplicatedKeyFilterException
+ * @throws KeyException
+ * @throws ValueException
* @throws Exception
- * if fails
*/
public SortedSet getNextPossibleValues(
- Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters)
- throws Exception {
- String orderingProperty = AccountingPersistenceQuery
- .getDefaultOrderingProperties(clz);
- return getNextPossibleValues(clz, temporalConstraint,
- filters, orderingProperty);
- }
-
- public abstract SortedSet getNextPossibleValues(
Class extends AggregatedRecord, ?>> clz,
TemporalConstraint temporalConstraint, List filters,
- String orderingProperty) throws Exception;
+ String topKey, String orderingProperty) throws
+ DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception;
/**
* Close the connection to persistence
@@ -137,6 +117,6 @@ public abstract class AccountingPersistenceBackendQuery {
* @throws Exception
* if the close fails
*/
- public abstract void close() throws Exception;
+ public void close() throws Exception;
}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java
index 76b9049..b164706 100644
--- a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java
+++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java
@@ -13,10 +13,15 @@ import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
+import javax.activity.InvalidActivityException;
+
import org.gcube.accounting.analytics.Filter;
import org.gcube.accounting.analytics.Info;
import org.gcube.accounting.analytics.NumberedFilter;
import org.gcube.accounting.analytics.TemporalConstraint;
+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.UsageRecord;
import org.gcube.accounting.datamodel.aggregation.AggregatedStorageUsageRecord;
import org.gcube.documentstore.records.AggregatedRecord;
@@ -28,7 +33,7 @@ import org.json.JSONObject;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
-public class AccountingPersistenceQuery {
+public class AccountingPersistenceQuery implements AccountingPersistenceBackendQuery {
private static final AccountingPersistenceQuery accountingPersistenceQuery;
@@ -68,7 +73,8 @@ public class AccountingPersistenceQuery {
return getQuerableKeys(instance);
}
- public static String getDefaultOrderingProperties(Class extends AggregatedRecord, ?>> clz){
+ public static String getDefaultOrderingProperties(
+ Class extends AggregatedRecord, ?>> clz){
if(clz.isAssignableFrom(AggregatedStorageUsageRecord.class)){
return AggregatedStorageUsageRecord.DATA_VOLUME;
}
@@ -118,11 +124,24 @@ public class AccountingPersistenceQuery {
}
return unpaddedData;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedMap getTimeSeries(
+ Class extends AggregatedRecord,?>> clz,
+ TemporalConstraint temporalConstraint, List filters)
+ throws DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception {
+
+ return this.getTimeSeries(clz, temporalConstraint, filters, false);
+ }
+
public SortedMap getTimeSeries(
Class extends AggregatedRecord,?>> clz,
TemporalConstraint temporalConstraint, List filters,
- boolean pad) throws Exception {
+ boolean pad) throws DuplicatedKeyFilterException, KeyException,
+ ValueException, Exception {
SortedMap ret =
AccountingPersistenceBackendQueryFactory.getInstance()
.getTimeSeries(clz, temporalConstraint,
@@ -136,9 +155,11 @@ public class AccountingPersistenceQuery {
}
public SortedMap> getTopValues(
- Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters,
- String orderingProperty, boolean pad, int limit) throws Exception {
+ Class extends AggregatedRecord, ?>> clz,
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey, String orderingProperty, boolean pad, int limit)
+ throws DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception {
SortedMap> got;
@@ -148,15 +169,17 @@ public class AccountingPersistenceQuery {
got = AccountingPersistenceBackendQueryFactory.getInstance()
.getTopValues(clz, temporalConstraint,
- filters, orderingProperty);
+ filters, topKey, orderingProperty);
- SortedMap> ret = new TreeMap>();
+ SortedMap> ret =
+ new TreeMap>();
if(pad){
int count = got.size() > limit ? limit : got.size();
while(--count >= 0){
for(NumberedFilter nf : got.keySet()){
- SortedMap m = padMap(got.get(nf), temporalConstraint);
+ SortedMap m =
+ padMap(got.get(nf), temporalConstraint);
ret.put(nf, m);
}
}
@@ -167,31 +190,76 @@ public class AccountingPersistenceQuery {
public SortedMap> getTopValues(
Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters)
- throws Exception {
- return AccountingPersistenceBackendQueryFactory.getInstance()
- .getTopValues(clz, temporalConstraint,
- filters);
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey) throws DuplicatedKeyFilterException,
+ KeyException, ValueException, Exception {
+ String orderingProperty = AccountingPersistenceQuery
+ .getDefaultOrderingProperties(clz);
+
+ return this.getTopValues(clz, temporalConstraint, filters, topKey,
+ orderingProperty, false, 0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SortedMap> getTopValues(
+ Class extends AggregatedRecord,?>> clz,
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey, String orderingProperty) throws
+ DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception {
+ return this.getTopValues(clz, temporalConstraint, filters, topKey,
+ orderingProperty, false, 0);
}
public SortedSet getNextPossibleValues(
Class extends AggregatedRecord,?>> clz,
- TemporalConstraint temporalConstraint, List filters)
- throws Exception {
- return AccountingPersistenceBackendQueryFactory.getInstance()
- .getNextPossibleValues(clz,
- temporalConstraint, filters);
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey) throws DuplicatedKeyFilterException, KeyException,
+ ValueException, Exception {
+
+ String orderingProperty = AccountingPersistenceQuery
+ .getDefaultOrderingProperties(clz);
+
+ return this.getNextPossibleValues(clz, temporalConstraint, filters,
+ topKey, orderingProperty);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SortedSet getNextPossibleValues(
+ Class extends AggregatedRecord, ?>> clz,
+ TemporalConstraint temporalConstraint, List filters,
+ String topKey, String orderingProperty) throws
+ DuplicatedKeyFilterException, KeyException, ValueException,
+ Exception {
+
+ return AccountingPersistenceBackendQueryFactory.getInstance()
+ .getNextPossibleValues(clz, temporalConstraint, filters,
+ topKey, orderingProperty);
+
+ }
/**
- * Close the connection to persistence
- *
- * @throws Exception
- * if the close fails
+ * {@inheritDoc}
*/
+ @Override
public void close() throws Exception {
AccountingPersistenceBackendQueryFactory.getInstance().close();
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void prepareConnection(
+ AccountingPersistenceBackendQueryConfiguration configuration)
+ throws Exception {
+ throw new InvalidActivityException();
+ }
+
}