diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..24dceb6
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,8 @@
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+# Changelog for Accounting Analytics Backend Connector for PostgreSQL
+
+
+## [v1.0.0-SNAPSHOT]
+
+- First Release
diff --git a/README.md b/README.md
index ef8f1b2..299fcc7 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,71 @@
-# accounting-analytics-persistence-postgresql
+# Accounting Analytics Backend Connector for PostgreSQL
+
+Accounting Analytics Backend Connector for PostgreSQL
+
+## Built With
+
+* [OpenJDK](https://openjdk.java.net/) - The JDK used
+* [Maven](https://maven.apache.org/) - Dependency Management
+
+## Documentation
+
+[Accounting Analytics Backend Connector for PostgreSQL](https://wiki.gcube-system.org/gcube/Accounting_Analytics)
+
+## Change log
+
+See [Releases](https://code-repo.d4science.org/gCubeSystem/accounting-analytics-persistence-postgresql/releases).
+
+## Authors
+
+* **Luca Frosini** ([ORCID](https://orcid.org/0000-0003-3183-2291)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
+
+## How to Cite this Software
+
+Tell people how to cite this software.
+* Cite an associated paper?
+* Use a specific BibTeX entry for the software?
+
+
+ @Manual{,
+ title = {Accounting Analytics Backend Connector for PostgreSQL},
+ author = {{Frosini, Luca}},
+ organization = {ISTI - CNR},
+ address = {Pisa, Italy},
+ year = 2021,
+ url = {http://www.gcube-system.org/}
+ }
+
+## License
+
+This project is licensed under the EUPL V.1.2 License - see the [LICENSE.md](LICENSE.md) file for details.
+
+
+## About the gCube Framework
+This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an
+open-source software toolkit used for building and operating Hybrid Data
+Infrastructures enabling the dynamic deployment of Virtual Research Environments
+by favouring the realisation of reuse oriented policies.
+
+The projects leading to this software have received funding from a series of European Union programmes including:
+
+- the Sixth Framework Programme for Research and Technological Development
+ - DILIGENT (grant no. 004260).
+- the Seventh Framework Programme for research, technological development and demonstration
+ - D4Science (grant no. 212488);
+ - D4Science-II (grant no.239019);
+ - ENVRI (grant no. 283465);
+ - iMarine(grant no. 283644);
+ - EUBrazilOpenBio (grant no. 288754).
+- the H2020 research and innovation programme
+ - SoBigData (grant no. 654024);
+ - PARTHENOS (grant no. 654119);
+ - EGIEngage (grant no. 654142);
+ - ENVRIplus (grant no. 654182);
+ - BlueBRIDGE (grant no. 675680);
+ - PerformFish (grant no. 727610);
+ - AGINFRAplus (grant no. 731001);
+ - DESIRA (grant no. 818194);
+ - ARIADNEplus (grant no. 823914);
+ - RISIS2 (grant no. 824091);
+
-Accounting Analytics Backend Connector for PostgreSQL
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 46b5426..63878be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,11 @@
accounting-analytics
[3.0.0-SNAPSHOT, 4.0.0-SNAPSHOT)
+
+ org.gcube.accounting
+ accounting-postgresql-utilities
+ [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)
+
org.slf4j
slf4j-api
@@ -56,7 +61,7 @@
postgresql
42.2.19
-
+
junit
junit
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/AccountingPersistenceQueryPostgreSQL.java b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/AccountingPersistenceQueryPostgreSQL.java
index 5cece82..78b5137 100644
--- a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/AccountingPersistenceQueryPostgreSQL.java
+++ b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/AccountingPersistenceQueryPostgreSQL.java
@@ -8,7 +8,6 @@ import java.sql.ResultSet;
import java.sql.Statement;
import java.time.OffsetDateTime;
import java.util.Calendar;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -30,6 +29,9 @@ import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQu
import org.gcube.accounting.datamodel.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.persistence.AccountingPersistenceConfiguration;
+import org.gcube.accounting.utility.postgresql.RecordToDBFields;
+import org.gcube.accounting.utility.postgresql.RecordToDBConnection;
+import org.gcube.accounting.utility.postgresql.RecordToDBMapping;
import org.gcube.documentstore.records.AggregatedRecord;
import org.gcube.documentstore.records.RecordUtility;
import org.json.JSONObject;
@@ -41,7 +43,7 @@ import org.slf4j.LoggerFactory;
*/
public class AccountingPersistenceQueryPostgreSQL implements AccountingPersistenceBackendQuery {
- private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceQueryPostgreSQL.class);
+ protected static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceQueryPostgreSQL.class);
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS Z";
@@ -50,40 +52,32 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
protected AccountingPersistenceBackendQueryConfiguration configuration;
- protected Map>, UsageRecordDBInfo> usageRecordDB;
-
static {
// One Record per package is enough
RecordUtility.addRecordPackage(ServiceUsageRecord.class.getPackage());
RecordUtility.addRecordPackage(AggregatedServiceUsageRecord.class.getPackage());
- Map>> aggregatedRecords = RecordUtility.getAggregatedRecordClassesFound();
- for(String typeName : aggregatedRecords.keySet()) {
- try {
- Class extends AggregatedRecord,?>> clz = aggregatedRecords.get(typeName);
- UsageRecordToDBMapping.getRecordToDB(clz);
- } catch (Exception e) {
- new RuntimeException(e);
- }
- }
}
protected Connection getConnection(Class extends AggregatedRecord, ?>> clz) throws Exception {
- UsageRecordDBInfo usageRecordDBInfo = usageRecordDB.get(clz);
- if(usageRecordDBInfo == null) {
- usageRecordDBInfo = new UsageRecordDBInfo(clz, configuration);
- usageRecordDB.put(clz, usageRecordDBInfo);
+ RecordToDBConnection recordDBInfo = RecordToDBMapping.getRecordDBInfo(clz);
+ if(recordDBInfo == null) {
+ RecordToDBMapping.addRecordToDB(clz, configuration);
}
- return usageRecordDBInfo.getConnection();
+ return recordDBInfo.getConnection();
}
-
-
@Override
public void prepareConnection(AccountingPersistenceBackendQueryConfiguration configuration) throws Exception {
- logger.trace("prepareConnection");
this.configuration = configuration;
- // this.baseURL = configuration.getProperty(URL_PROPERTY_KEY);
- this.usageRecordDB = new HashMap<>();
+ Map>> aggregatedRecords = RecordUtility.getAggregatedRecordClassesFound();
+ for(String typeName : aggregatedRecords.keySet()) {
+ try {
+ Class extends AggregatedRecord,?>> clz = aggregatedRecords.get(typeName);
+ RecordToDBMapping.getRecordToDB(clz);
+ } catch (Exception e) {
+ new RuntimeException(e);
+ }
+ }
}
public SortedMap getTimeSeries(Class extends AggregatedRecord, ?>> clz,
@@ -103,7 +97,7 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
String sql = query.getTimeSeriesQuery();
List requestedTableField = query.getRequestedTableField();
- RecordToDBMapper recordToDBMapper = query.getRecordToDBMapper();
+ RecordToDBFields recordToDBMapper = query.getRecordToDBMapper();
ResultSet resultSet = statement.executeQuery(sql);
@@ -114,7 +108,7 @@ public class AccountingPersistenceQueryPostgreSQL implements AccountingPersisten
JSONObject jsonObject = new JSONObject();
for(String tableField : requestedTableField) {
- String usageRecordField = recordToDBMapper.getUsageRecordField(tableField);
+ String usageRecordField = recordToDBMapper.getRecordField(tableField);
Object object = resultSet.getObject(tableField);
jsonObject.put(usageRecordField, object);
}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/Query.java b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/Query.java
index 081e8f8..4dd3bc1 100644
--- a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/Query.java
+++ b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/Query.java
@@ -14,6 +14,8 @@ import org.gcube.accounting.analytics.TemporalConstraint.AggregationMode;
import org.gcube.accounting.analytics.TemporalConstraint.CalendarEnum;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.aggregation.AggregatedServiceUsageRecord;
+import org.gcube.accounting.utility.postgresql.RecordToDBFields;
+import org.gcube.accounting.utility.postgresql.RecordToDBMapping;
import org.gcube.documentstore.records.AggregatedRecord;
public class Query {
@@ -22,7 +24,7 @@ public class Query {
public static final String DATE_OF_TIMESERIES_AS_FIELD = AggregatedRecord.START_TIME;
private Class extends AggregatedRecord, ?>> clz;
- private final RecordToDBMapper recordToDBMapper;
+ private final RecordToDBFields recordToDBMapper;
private List requestedTableField;
private StringBuffer stringBuffer;
@@ -33,7 +35,7 @@ public class Query {
public Query(Class extends AggregatedRecord, ?>> clz) throws Exception {
this.clz = clz;
- this.recordToDBMapper = UsageRecordToDBMapping.getRecordToDB(clz);
+ this.recordToDBMapper = RecordToDBMapping.getRecordToDB(clz);
}
public List getRequestedTableField() {
@@ -60,7 +62,7 @@ public class Query {
}
- public RecordToDBMapper getRecordToDBMapper() {
+ public RecordToDBFields getRecordToDBMapper() {
return recordToDBMapper;
}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/RecordToDBMapper.java b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/RecordToDBMapper.java
deleted file mode 100644
index 15b701d..0000000
--- a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/RecordToDBMapper.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.gcube.accounting.analytics.persistence.postgresql;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.gcube.documentstore.records.AggregatedRecord;
-import org.gcube.documentstore.records.Record;
-
-public class RecordToDBMapper {
-
- 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 getKey(String fieldName) {
- StringBuffer stringBuffer = new StringBuffer();
- int lenght = fieldName.length();
- boolean lastLowerCase = true;
- for (int i=0; i> clz;
-
- protected final String typeName;
- protected final String tableName;
-
- protected final Map tableFieldToUsageRecordField;
- protected final Map usageRecordFieldToTableField;
-
- public RecordToDBMapper(Class extends AggregatedRecord, ?>> clz) throws Exception {
- this.clz = clz;
- this.typeName = getRecordTypeByClass(clz);
- this.tableName = typeName.toLowerCase();
- this.tableFieldToUsageRecordField = new HashMap<>();
- this.usageRecordFieldToTableField = new HashMap<>();
- mapFields();
- }
-
- public RecordToDBMapper(String typeName, Class extends AggregatedRecord, ?>> clz) throws Exception {
- this.clz = clz;
- this.typeName = typeName;
- this.tableName = typeName.toLowerCase();
- this.tableFieldToUsageRecordField = new HashMap<>();
- this.usageRecordFieldToTableField = new HashMap<>();
- mapFields();
- }
-
- protected void mapFields() throws Exception {
- Set requiredFields = clz.newInstance().getRequiredFields();
- for(String usageRecordField : requiredFields) {
- String dbField = getKey(usageRecordField);
- tableFieldToUsageRecordField.put(dbField, usageRecordField);
- usageRecordFieldToTableField.put(usageRecordField, dbField);
- }
- }
-
- public String getTableField(String usageRecordField) {
- return usageRecordFieldToTableField.get(usageRecordField);
- }
-
- public String getUsageRecordField(String tableField) {
- String ret = tableFieldToUsageRecordField.get(tableField);
- if(ret==null && usageRecordFieldToTableField.keySet().contains(tableField)) {
- ret = tableField;
- }
- return ret;
- }
-
- public String getTypeName() {
- return typeName;
- }
-
- public String getTableName() {
- return tableName;
- }
-
-}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordDBInfo.java b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordDBInfo.java
deleted file mode 100644
index cf81b28..0000000
--- a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordDBInfo.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.gcube.accounting.analytics.persistence.postgresql;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-
-import org.gcube.accounting.analytics.persistence.AccountingPersistenceBackendQueryConfiguration;
-import org.gcube.accounting.persistence.AccountingPersistenceConfiguration;
-import org.gcube.documentstore.records.AggregatedRecord;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class UsageRecordDBInfo {
-
- private static final Logger logger = LoggerFactory.getLogger(UsageRecordDBInfo.class);
-
- public static final String URL_PROPERTY_KEY = AccountingPersistenceConfiguration.URL_PROPERTY_KEY;
- public static final String DB_SUFFIX = "-db";
- public static final String USERNAME_SUFFIX = "-username";
- public static final String PASSWORD_SUFFIX = "-password";
-
- private final String baseURL;
- private final String dbName;
- private final String url;
- private final String username;
- private final String password;
-
- protected final Class extends AggregatedRecord, ?>> clz;
- protected final String typeName;
-
- public UsageRecordDBInfo(Class extends AggregatedRecord, ?>> clz, AccountingPersistenceBackendQueryConfiguration configuration) throws Exception {
- this.clz = clz;
- this.typeName = UsageRecordToDBMapping.getRecordToDB(clz).getTypeName();
-
- this.baseURL = configuration.getProperty(URL_PROPERTY_KEY);
- this.dbName = configuration.getProperty(typeName+DB_SUFFIX);
- this.url = baseURL + "/" + dbName;
-
- this.username = configuration.getProperty(typeName+USERNAME_SUFFIX);
- this.password = configuration.getProperty(typeName+PASSWORD_SUFFIX);
-
- }
-
- protected Connection getConnection() throws Exception {
- Class.forName("org.postgresql.Driver");
- Connection connection = DriverManager.getConnection(url, username, password);
- logger.trace("Database {} opened successfully", url);
- connection.setAutoCommit(false);
- return connection;
- }
-
-}
diff --git a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordToDBMapping.java b/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordToDBMapping.java
deleted file mode 100644
index bfa3b28..0000000
--- a/src/main/java/org/gcube/accounting/analytics/persistence/postgresql/UsageRecordToDBMapping.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.gcube.accounting.analytics.persistence.postgresql;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gcube.documentstore.records.AggregatedRecord;
-
-public class UsageRecordToDBMapping {
-
- protected final static Map>, RecordToDBMapper> classToRecordToDBMapper;
-
- static {
- classToRecordToDBMapper = new HashMap<>();
- }
-
- public static synchronized RecordToDBMapper getRecordToDB(Class extends AggregatedRecord, ?>> clz) throws Exception {
- RecordToDBMapper recordToDBMapper = classToRecordToDBMapper.get(clz);
- if(recordToDBMapper==null) {
- recordToDBMapper = new RecordToDBMapper(clz);
- classToRecordToDBMapper.put(clz, recordToDBMapper);
- }
- return recordToDBMapper;
- }
-
-}