diff --git a/src/main/java/org/gcube/accounting/analytics/ResourceRecordQuery.java b/src/main/java/org/gcube/accounting/analytics/ResourceRecordQuery.java index 372b04b..c44a6cd 100644 --- a/src/main/java/org/gcube/accounting/analytics/ResourceRecordQuery.java +++ b/src/main/java/org/gcube/accounting/analytics/ResourceRecordQuery.java @@ -14,8 +14,8 @@ import java.util.Set; import org.gcube.accounting.analytics.exception.NoAvailableScopeException; import org.gcube.accounting.analytics.exception.NoUsableAccountingPersistenceQueryFound; -import org.gcube.accounting.analytics.persistence.AccountingPersistenceQuery; -import org.gcube.accounting.analytics.persistence.AccountingPersistenceQueryFactory; +import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQuery; +import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQueryFactory; import org.gcube.accounting.datamodel.AggregatedUsageRecord; import org.gcube.accounting.datamodel.SingleUsageRecord; import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord; @@ -60,7 +60,7 @@ public class ResourceRecordQuery { } - protected AccountingPersistenceQuery accountingPersistenceQuery; + protected AccountingPersistenceBackendQuery accountingPersistenceQuery; /** * Instantiate the ResourceRecord for the current scope @@ -70,7 +70,7 @@ public class ResourceRecordQuery { * instance which can query in that scope */ public ResourceRecordQuery() throws NoAvailableScopeException, NoUsableAccountingPersistenceQueryFound { - this.accountingPersistenceQuery = AccountingPersistenceQueryFactory.getInstance(); + this.accountingPersistenceQuery = AccountingPersistenceBackendQueryFactory.getInstance(); } /** @@ -83,7 +83,7 @@ public class ResourceRecordQuery { */ public ResourceRecordQuery(String scope) throws NoAvailableScopeException, NoUsableAccountingPersistenceQueryFound { ScopeProvider.instance.set(scope); - this.accountingPersistenceQuery = AccountingPersistenceQueryFactory.getInstance(); + this.accountingPersistenceQuery = AccountingPersistenceBackendQueryFactory.getInstance(); } protected static JSONObject getPaddingJSONObject(Map unpaddedResults) throws JSONException{ diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java new file mode 100644 index 0000000..5d01de6 --- /dev/null +++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQuery.java @@ -0,0 +1,76 @@ +/** + * + */ +package org.gcube.accounting.analytics.persistence; + +import java.util.Calendar; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.gcube.accounting.analytics.Filter; +import org.gcube.accounting.analytics.Info; +import org.gcube.accounting.analytics.TemporalConstraint; +import org.gcube.accounting.datamodel.AggregatedUsageRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public abstract class AccountingPersistenceBackendQuery { + + private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendQuery.class); + + protected abstract void prepareConnection(AccountingPersistenceBackendQueryConfiguration configuration) throws Exception; + + protected abstract Map reallyQuery(@SuppressWarnings("rawtypes") Class usageRecordType, + TemporalConstraint temporalConstraint, List filters) throws Exception; + + /** + * Query the persistence obtaining a Map where the date is the key and + * the #Info is the value. The result is relative to an Usage Record Type, + * respect a TemporalConstraint and can be applied one or more filters. + * @param usageRecordType the Usage Record Type of interest + * @param temporalConstraint the TemporalConstraint (interval and aggregation) + * @param filters the filter for the query. If null or empty string get all + * data. The filters are evaluated in the order the are presented and are + * considered in AND + * @return the Map containing for each date in the required interval the + * requested data + * @throws Exception if fails + */ + public Map query(@SuppressWarnings("rawtypes") Class usageRecordType, + TemporalConstraint temporalConstraint, List filters) throws Exception{ + logger.trace("Request query: UsageRecordType={}, {}={}, {}s={}", usageRecordType.newInstance().getUsageRecordType(), + TemporalConstraint.class.getSimpleName(), temporalConstraint.toString(), + Filter.class.getSimpleName(), filters); + return reallyQuery(usageRecordType, temporalConstraint, filters); + } + + /** + * Return the list of key valid for queries a certain usage record type + * @param usageRecordType the usage record type + * @return a set containing the list of key + * @throws Exception if fails + */ + public abstract Set getKeys(@SuppressWarnings("rawtypes") Class usageRecordType) throws Exception; + + + /** + * Return the list of possible values for a key for a certain usage record type + * @param usageRecordType the usage record type + * @param key the key + * @return a set containing the list of possible values + * @throws Exception if fails + */ + public abstract Set getPossibleValuesForKey(@SuppressWarnings("rawtypes") Class usageRecordType, String key) throws Exception; + + /** + * Close the connection to persistence + * @throws Exception if the close fails + */ + public abstract void close() throws Exception; + +} diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryConfiguration.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryConfiguration.java similarity index 70% rename from src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryConfiguration.java rename to src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryConfiguration.java index 5cc05ad..e6d5fc1 100644 --- a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryConfiguration.java +++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryConfiguration.java @@ -9,12 +9,12 @@ import org.gcube.common.resources.gcore.ServiceEndpoint; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ -public class AccountingPersistenceQueryConfiguration extends AccountingPersistenceConfiguration { +public class AccountingPersistenceBackendQueryConfiguration extends AccountingPersistenceConfiguration { /** * Default Constructor */ - public AccountingPersistenceQueryConfiguration(){ + public AccountingPersistenceBackendQueryConfiguration(){ super(); } @@ -23,7 +23,7 @@ public class AccountingPersistenceQueryConfiguration extends AccountingPersisten * @param username the username to connect to persistence * @param password the password to connect to persistence */ - public AccountingPersistenceQueryConfiguration(URI uri, String username, String password){ + public AccountingPersistenceBackendQueryConfiguration(URI uri, String username, String password){ super(uri, username, password); } @@ -31,7 +31,7 @@ public class AccountingPersistenceQueryConfiguration extends AccountingPersisten * @param persistenceClassName The classname of the persistence to instantiate * @throws Exception if fails */ - public AccountingPersistenceQueryConfiguration(String persistenceClassName) throws Exception{ + public AccountingPersistenceBackendQueryConfiguration(String persistenceClassName) throws Exception{ super.init(); ServiceEndpoint serviceEndpoint = getServiceEndpoint(SERVICE_ENDPOINT_CATEGORY, SERVICE_ENDPOINT_NAME, persistenceClassName); setValues(serviceEndpoint, persistenceClassName); diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryFactory.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryFactory.java new file mode 100644 index 0000000..a33db39 --- /dev/null +++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceBackendQueryFactory.java @@ -0,0 +1,82 @@ +/** + * + */ +package org.gcube.accounting.analytics.persistence; + +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +import org.gcube.accounting.analytics.exception.NoAvailableScopeException; +import org.gcube.accounting.analytics.exception.NoUsableAccountingPersistenceQueryFound; +import org.gcube.common.scope.api.ScopeProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + */ +public abstract class AccountingPersistenceBackendQueryFactory { + + private static Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendQueryFactory.class); + + private static Map accountingPersistenceQueries; + + static { + accountingPersistenceQueries = new HashMap(); + } + + /** + * @return AccountingPersistenceQuery instance + * @throws NoAvailableScopeException if no configuration is found on IS for + * the current scope + * @throws NoUsableAccountingPersistenceQueryFound if fails to instantiate + * the #AccountingPersistenceQuery + */ + public synchronized static AccountingPersistenceBackendQuery getInstance() throws NoAvailableScopeException, NoUsableAccountingPersistenceQueryFound { + String scope = ScopeProvider.instance.get(); + if(scope==null){ + throw new NoAvailableScopeException(); + } + + AccountingPersistenceBackendQuery accountingPersistenceQuery = accountingPersistenceQueries.get(scope); + if(accountingPersistenceQuery==null){ + + try { + ServiceLoader serviceLoader = ServiceLoader.load(AccountingPersistenceBackendQuery.class); + for (AccountingPersistenceBackendQuery found : serviceLoader) { + try { + String foundClassName = found.getClass().getSimpleName(); + logger.debug("Testing {}", foundClassName); + + AccountingPersistenceBackendQueryConfiguration configuration = new AccountingPersistenceBackendQueryConfiguration(foundClassName); + found.prepareConnection(configuration); + accountingPersistenceQuery = found; + break; + } catch (Exception e) { + logger.debug(String.format("%s not initialized correctly. It will not be used", found.getClass().getSimpleName())); + } + } + } catch(Exception e){ + throw new NoUsableAccountingPersistenceQueryFound(); + } + + if(accountingPersistenceQuery==null){ + throw new NoUsableAccountingPersistenceQueryFound(); + } + + accountingPersistenceQueries.put(scope, accountingPersistenceQuery); + } + + return accountingPersistenceQuery; + } + + + protected AccountingPersistenceBackendQueryFactory(){ + + } + + + + +} 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 5dcfe49..507cb6c 100644 --- a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java +++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQuery.java @@ -12,21 +12,25 @@ import org.gcube.accounting.analytics.Filter; import org.gcube.accounting.analytics.Info; import org.gcube.accounting.analytics.TemporalConstraint; import org.gcube.accounting.datamodel.AggregatedUsageRecord; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ -public abstract class AccountingPersistenceQuery { +public class AccountingPersistenceQuery { + + private static final AccountingPersistenceQuery accountingPersistenceQuery; - private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceQuery.class); + private AccountingPersistenceQuery(){} - protected abstract void prepareConnection(AccountingPersistenceQueryConfiguration configuration) throws Exception; + static { + accountingPersistenceQuery = new AccountingPersistenceQuery(); + } + + protected static synchronized AccountingPersistenceQuery getInstance(){ + return accountingPersistenceQuery; + } - protected abstract Map reallyQuery(@SuppressWarnings("rawtypes") Class usageRecordType, - TemporalConstraint temporalConstraint, List filters) throws Exception; /** * Query the persistence obtaining a Map where the date is the key and @@ -43,10 +47,7 @@ public abstract class AccountingPersistenceQuery { */ public Map query(@SuppressWarnings("rawtypes") Class usageRecordType, TemporalConstraint temporalConstraint, List filters) throws Exception{ - logger.trace("Request query: UsageRecordType={}, {}={}, {}s={}", usageRecordType.newInstance().getUsageRecordType(), - TemporalConstraint.class.getSimpleName(), temporalConstraint.toString(), - Filter.class.getSimpleName(), filters); - return reallyQuery(usageRecordType, temporalConstraint, filters); + return AccountingPersistenceBackendQueryFactory.getInstance().query(usageRecordType, temporalConstraint, filters); } /** @@ -55,7 +56,9 @@ public abstract class AccountingPersistenceQuery { * @return a set containing the list of key * @throws Exception if fails */ - public abstract Set getKeys(@SuppressWarnings("rawtypes") Class usageRecordType) throws Exception; + public Set getKeys(@SuppressWarnings("rawtypes") Class usageRecordType) throws Exception { + return AccountingPersistenceBackendQueryFactory.getInstance().getKeys(usageRecordType); + } /** @@ -65,12 +68,16 @@ public abstract class AccountingPersistenceQuery { * @return a set containing the list of possible values * @throws Exception if fails */ - public abstract Set getPossibleValuesForKey(@SuppressWarnings("rawtypes") Class usageRecordType, String key) throws Exception; + public Set getPossibleValuesForKey(@SuppressWarnings("rawtypes") Class usageRecordType, String key) throws Exception { + return AccountingPersistenceBackendQueryFactory.getInstance().getPossibleValuesForKey(usageRecordType, key); + } /** * Close the connection to persistence * @throws Exception if the close fails */ - public abstract void close() throws Exception; + public void close() throws Exception { + AccountingPersistenceBackendQueryFactory.getInstance().close(); + } } diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryFactory.java b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryFactory.java index 1f7301f..e8e8d4e 100644 --- a/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryFactory.java +++ b/src/main/java/org/gcube/accounting/analytics/persistence/AccountingPersistenceQueryFactory.java @@ -3,80 +3,14 @@ */ package org.gcube.accounting.analytics.persistence; -import java.util.HashMap; -import java.util.Map; -import java.util.ServiceLoader; - -import org.gcube.accounting.analytics.exception.NoAvailableScopeException; -import org.gcube.accounting.analytics.exception.NoUsableAccountingPersistenceQueryFound; -import org.gcube.common.scope.api.ScopeProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * */ -public abstract class AccountingPersistenceQueryFactory { - - private static Logger logger = LoggerFactory.getLogger(AccountingPersistenceQueryFactory.class); +public class AccountingPersistenceQueryFactory { - private static Map accountingPersistenceQueries; - - static { - accountingPersistenceQueries = new HashMap(); + public static AccountingPersistenceQuery getInstance() { + return AccountingPersistenceQuery.getInstance(); } - - /** - * @return AccountingPersistenceQuery instance - * @throws NoAvailableScopeException if no configuration is found on IS for - * the current scope - * @throws NoUsableAccountingPersistenceQueryFound if fails to instantiate - * the #AccountingPersistenceQuery - */ - public synchronized static AccountingPersistenceQuery getInstance() throws NoAvailableScopeException, NoUsableAccountingPersistenceQueryFound { - String scope = ScopeProvider.instance.get(); - if(scope==null){ - throw new NoAvailableScopeException(); - } - - AccountingPersistenceQuery accountingPersistenceQuery = accountingPersistenceQueries.get(scope); - if(accountingPersistenceQuery==null){ - - try { - ServiceLoader serviceLoader = ServiceLoader.load(AccountingPersistenceQuery.class); - for (AccountingPersistenceQuery found : serviceLoader) { - try { - String foundClassName = found.getClass().getSimpleName(); - logger.debug("Testing {}", foundClassName); - - AccountingPersistenceQueryConfiguration configuration = new AccountingPersistenceQueryConfiguration(foundClassName); - found.prepareConnection(configuration); - accountingPersistenceQuery = found; - break; - } catch (Exception e) { - logger.debug(String.format("%s not initialized correctly. It will not be used", found.getClass().getSimpleName())); - } - } - } catch(Exception e){ - throw new NoUsableAccountingPersistenceQueryFound(); - } - - if(accountingPersistenceQuery==null){ - throw new NoUsableAccountingPersistenceQueryFound(); - } - - accountingPersistenceQueries.put(scope, accountingPersistenceQuery); - } - - return accountingPersistenceQuery; - } - - - protected AccountingPersistenceQueryFactory(){ - - } - - - - }