commit e1d1fe5d66bebc4cfdf036774f2233f691eaccb7 Author: Alessandro Pieve Date: Wed May 3 09:18:10 2017 +0000 first release git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/document-store-lib-accounting-service@148247 82a268e6-3cf1-43bd-a215-b396298e98cf diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..e43402f --- /dev/null +++ b/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..3036598 --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + document-store-lib-accounting-service + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ec4300d --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..cdf50bd --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,4 @@ +gCube System - License +------------------------------------------------------------ + +${gcube.license} \ No newline at end of file diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..d05477e --- /dev/null +++ b/distro/README @@ -0,0 +1,66 @@ +The gCube System - ${name} +-------------------------------------------------- + +${description} + + +${gcube.description} + +${gcube.funding} + + +Version +-------------------------------------------------- + +${version} (${buildDate}) + +Please see the file named "changelog.xml" in this directory for the release notes. + + +Authors +-------------------------------------------------- + +* Alessandro Pieve (alessandro.pieve-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). + + + +Maintainers +----------- + +* Alessandro Pieve (alessandro.pieve-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). + +Download information +-------------------------------------------------- + +Source code is available from SVN: + ${scm.url} + +Binaries can be downloaded from the gCube website: + ${gcube.website} + + +Installation +-------------------------------------------------- + +Installation documentation is available on-line in the gCube Wiki: + ${gcube.wikiRoot}/Document_Store_Lib + + +Documentation +-------------------------------------------------- + +Documentation is available on-line in the gCube Wiki: + ${gcube.wikiRoot}/Document_Store_Lib + + +Support +-------------------------------------------------- + +Bugs and support requests can be reported in the gCube issue tracking tool: + ${gcube.issueTracking} + + +Licensing +-------------------------------------------------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..f13a1c0 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,5 @@ + + + First Release + + \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..089683d --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,31 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + changelog.xml + profile.xml + + 755 + true + + + + + target/${build.finalName}.jar + /${artifactId} + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..014ca47 --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,26 @@ + + + + Service + + ${description} + ${serviceClass} + ${artifactId} + 1.0.0 + + + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + + ${build.finalName}.jar + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b779a17 --- /dev/null +++ b/pom.xml @@ -0,0 +1,146 @@ + + 4.0.0 + + org.gcube.tools + maven-parent + 1.0.0 + + org.gcube.data.publishing + document-store-lib-accounting-service + 1.0.0-SNAPSHOT + Document Store Accounting Service Connector + Document Store Connector for Accounting Service + + + UTF-8 + ${project.basedir}/distro + DataPublishing + + + + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId} + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId} + https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId} + + + + + + + org.gcube.distribution + gcube-bom + LATEST + pom + import + + + + + + + org.gcube.data.publishing + document-store-lib + + + org.slf4j + slf4j-api + + + org.gcube.core + common-scope + + + org.gcube.common + authorization-client + + + org.gcube.common + common-authorization + + + org.gcube.core + common-encryption + test + + + org.gcube.resources.discovery + ic-client + + + + + + + + + + + + + junit + junit + 4.11 + test + + + ch.qos.logback + logback-classic + 1.0.13 + + + org.gcube.accounting + accounting-lib + test + + + + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + ${distroDirectory}/descriptor.xml + + + jar-with-dependencies + + + + + package + + single + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/documentstore/persistence/PersistenceAccountingService.java b/src/main/java/org/gcube/documentstore/persistence/PersistenceAccountingService.java new file mode 100644 index 0000000..d68d52b --- /dev/null +++ b/src/main/java/org/gcube/documentstore/persistence/PersistenceAccountingService.java @@ -0,0 +1,247 @@ +/** + * + */ +package org.gcube.documentstore.persistence; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.io.DataOutputStream; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeoutException; + +import javax.net.ssl.HttpsURLConnection; +import javax.xml.bind.JAXBContext; + +import org.gcube.common.resources.gcore.GCoreEndpoint; +import org.gcube.common.resources.gcore.GCoreEndpoint.Profile; +import org.gcube.common.resources.gcore.GCoreEndpoint.Profile.Endpoint; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.documentstore.records.DSMapper; +import org.gcube.documentstore.records.Record; +import org.gcube.documentstore.records.SerializableList; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author Alessandro Pieve (ISTI - CNR) alessandro.pieve@isti.cnr.it + * + */ +public class PersistenceAccountingService extends PersistenceBackend { + + private static final Logger logger = LoggerFactory.getLogger(PersistenceAccountingService.class); + + public static final String URL_SERVICE_ACCOUNTING_KEY = "UrlAccountingService"; + + public static final String PATH_SERVICE_ACCOUNTING = "/accounting-service/gcube/service"; + + public static final String PATH_SERVICE_INSERT_ACCOUNTING = "/insert/record"; + public static final String PATH_SERVICE_INSERTS_ACCOUNTING = "/insert/records"; + public static final String PATH_SERVICE_STATUS_ACCOUNTING = "insert/getStatus"; + + public static final String GCORE_END_POINT_NAME="AccountService webapp"; + public static final String GCORE_END_RUNNING="RunningInstance"; + + public static final String RESOURCE_ACCOUNTING="org.gcube.data.publishing.accounting.service.AccountingResource"; + private static final String USER_AGENT = "Mozilla/5.0"; + private static final String CONTENT_TYPE_JSON = "application/json"; + private static final String CONTENT_TYPE_XML = "application/xml"; + + protected String urlService; + protected String context; + + + /** + * {@inheritDoc} + */ + @Override + protected void prepareConnection(PersistenceBackendConfiguration configuration) throws Exception { + + try{ + context = ScopeProvider.instance.get(); + logger.debug("prepareConnection context:{}",context); + ScopeProvider.instance.set(context); + SimpleQuery query = queryFor(GCoreEndpoint.class); + query.addCondition("$resource/Profile/Description/text() eq '"+ GCORE_END_POINT_NAME +"'"); + query.addCondition("$resource/Type/text() eq '"+ GCORE_END_RUNNING +"'"); + + DiscoveryClient client = clientFor(GCoreEndpoint.class); + List toReturn = client.submit(query); + + GCoreEndpoint endpoint=toReturn.get(0); + Profile profile =endpoint.profile(); + Endpoint url =profile.endpointMap().get(RESOURCE_ACCOUNTING); + + urlService=url.uri().toString(); + logger.debug("urlService from GcoreEndPoint:{}",urlService); + + + }catch(Exception e){ + try{ + urlService= configuration.getProperty(URL_SERVICE_ACCOUNTING_KEY)+PATH_SERVICE_ACCOUNTING+"/"; + logger.debug("urlService from Service End Point:{}",urlService); + }catch(Exception ex){ + logger.error("Url service not found into configuration from service point"); + throw new IllegalStateException("Url service has a null property", ex); + + } + + } + + } + + /** + * {@inheritDoc} + */ + @Override + protected void reallyAccount(Record record) throws Exception { + + logger.trace("init reallyAccount"); + String path=urlService+PATH_SERVICE_INSERT_ACCOUNTING; + + URL obj = new URL(path); + logger.trace("reallyAccount path:{}",path); + String recordMarshal=DSMapper.marshal(record); + int responseCode; + if (path.indexOf("http") != -1){ + logger.trace("accountWithFallback http path:{}",path); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", USER_AGENT); + con.setRequestProperty("Content-type", CONTENT_TYPE_JSON); + con.setRequestProperty("gcube-scope", context); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(recordMarshal); + wr.flush(); + wr.close(); + responseCode = con.getResponseCode(); + } + else{ + logger.trace("accountWithFallback https path:{}",path); + HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", USER_AGENT); + con.setRequestProperty("Content-type", CONTENT_TYPE_JSON); + con.setRequestProperty("gcube-scope", context); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(recordMarshal); + wr.flush(); + wr.close(); + responseCode = con.getResponseCode(); + } + logger.debug("reallyAccount Post parameters : " + recordMarshal); + logger.debug("reallyAccount Response Code : " + responseCode); + switch (responseCode) { + case HttpURLConnection.HTTP_OK: + logger.trace("accountWithFallback - Send records to service:{}"); + break; + case HttpURLConnection.HTTP_GATEWAY_TIMEOUT: + throw new TimeoutException("Time out for call service accounting"); + + default: + throw new Exception("Generic error for service accounting"); + + } + + } + + + @Override + protected void accountWithFallback(Record... records) throws Exception { + + logger.trace("init accountWithFallback"); + String path=urlService+PATH_SERVICE_INSERTS_ACCOUNTING; + List valuesList=new ArrayList(); + for(Record record:records){ + logger.trace("add record:{}",record); + valuesList.add(DSMapper.marshal(record)); + } + SerializableList list=new SerializableList(valuesList); + + JAXBContext contextRecord = JAXBContext.newInstance(SerializableList.class); + StringWriter writer =new StringWriter(); + contextRecord.createMarshaller().marshal(list, writer); + URL obj = new URL(path); + //check if http or https + int responseCode; + if (path.indexOf("http") != -1){ + logger.trace("accountWithFallback http path:{}",path); + HttpURLConnection con = (HttpURLConnection) obj.openConnection();//add request header + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", USER_AGENT); + con.setRequestProperty("Content-type", CONTENT_TYPE_XML); + con.setRequestProperty("gcube-scope", context); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(writer.toString()); + wr.flush(); + wr.close(); + responseCode = con.getResponseCode(); + } + else{ + logger.trace("accountWithFallback https path:{}",path); + HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", USER_AGENT); + con.setRequestProperty("Content-type", CONTENT_TYPE_XML); + con.setRequestProperty("gcube-scope", context); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(writer.toString()); + wr.flush(); + wr.close(); + responseCode = con.getResponseCode(); + } + logger.debug("accountWithFallback gcube-scope : " +context); + logger.debug("accountWithFallback Post parameters : " + writer.toString()); + logger.debug("accountWithFallback Response Code : " + responseCode); + logger.trace("accountWithFallback - Send records to service:{}"); + switch (responseCode) { + case HttpURLConnection.HTTP_OK: + logger.trace("accountWithFallback - Service respond ok :{}"); + break; + case HttpURLConnection.HTTP_GATEWAY_TIMEOUT: + throw new TimeoutException("Time out for call service accounting"); + + default: + throw new Exception("Generic error for service accounting"); + + } + } + + + /** + * {@inheritDoc} + */ + @Override + public void close() throws Exception { + //TODO + } + + @Override + protected void openConnection() throws Exception { + // TODO Auto-generated method stub + + } + + @Override + protected void closeConnection() throws Exception { + // TODO Auto-generated method stub + + } + + @Override + protected void closeAndClean() throws Exception { + // TODO Auto-generated method stub + } + +} diff --git a/src/main/resources/META-INF/services/org.gcube.documentstore.persistence.PersistenceBackend b/src/main/resources/META-INF/services/org.gcube.documentstore.persistence.PersistenceBackend new file mode 100644 index 0000000..173e478 --- /dev/null +++ b/src/main/resources/META-INF/services/org.gcube.documentstore.persistence.PersistenceBackend @@ -0,0 +1 @@ +org.gcube.documentstore.persistence.PersistenceAccountingService \ No newline at end of file diff --git a/src/test/java/org/gcube/documentstore/persistence/PersistenceAccountingServiceTest.java b/src/test/java/org/gcube/documentstore/persistence/PersistenceAccountingServiceTest.java new file mode 100644 index 0000000..7a524be --- /dev/null +++ b/src/test/java/org/gcube/documentstore/persistence/PersistenceAccountingServiceTest.java @@ -0,0 +1,150 @@ +/** + * + */ +package org.gcube.documentstore.persistence; + +import org.gcube.documentstore.records.Record; +import org.gcube.documentstore.utility.TestUsageRecord; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Alessandro Pieve (ISTI - CNR) alessandro.pieve@isti.cnr.it + * + */ +public class PersistenceAccountingServiceTest { + + private static final Logger logger = LoggerFactory.getLogger(PersistenceAccountingServiceTest.class); + + + + @Before + public void before() throws Exception{ + //SecurityTokenProvider.instance.set("36501a0d-a205-4bf1-87ad-4c7185faa0d6-98187548"); + //SecurityTokenProvider.instance.set("3acdde42-6883-4564-b3ba-69f6486f6fe0-98187548"); + + // SecurityTokenProvider.instance.set("2580f89f-d7a8-452d-a131-b3859bd771fd-98187548"); + + //ScopeProvider.instance.set("/gcube/devNext"); + //ScopeProvider.instance.set("/gcube"); + + + // ScopeProvider.instance.set("/gcube/devNext/NextNext"); + } + + @After + public void after(){ + //SecurityTokenProvider.instance.reset(); + } + + + @Test + public void testSingleInsertService() throws Exception{ + // Production-Preproduction Nodes + PersistenceBackendConfiguration persitenceConfiguration = null; + PersistenceAccountingService accountingService = new PersistenceAccountingService(); + accountingService.prepareConnection(persitenceConfiguration); + + Record record = TestUsageRecord.createTestServiceUsageRecord(); + accountingService.reallyAccount(record); + + } + + + @Test + public void testMultipleInsertService() throws Exception{ + // Production-Preproduction Nodes + PersistenceBackendConfiguration persitenceConfiguration = null; + PersistenceAccountingService accountingService = new PersistenceAccountingService(); + accountingService.prepareConnection(persitenceConfiguration); + Integer count=2; + Record[] records = new Record[count]; + for(int i=0; i inputParameters = new HashMap<>(); + inputParameters.put(TEST_PROPERTY_NAME, TEST_PROPERTY_VALUE); + inputParameters.put(TEST_PROPERTY_VALUE, TEST_PROPERTY_NAME); + + HashMap parameter = new HashMap<>(); + parameter.put(TEST_PROPERTY_NAME, TEST_PROPERTY_VALUE); + parameter.put(TEST_PROPERTY_VALUE, TEST_PROPERTY_NAME); + + inputParameters.put(TEST_NESTED_MAP, parameter); + + usageRecord.setInputParameters(inputParameters); + + } catch (InvalidValueException e) { + logger.error(" ------ You SHOULD NOT SEE THIS MESSAGE. Error Creating a test Usage Record", e); + } + + return usageRecord; + } + + + /** + * @return + */ + public static PortletUsageRecord createTestPortletUsageRecord() { + + PortletUsageRecord usageRecord = new PortletUsageRecord(); + try { + usageRecord.setConsumerId(TEST_CONSUMER_ID); + usageRecord.setOperationResult(TEST_OPERATION_RESULT); + + Calendar startTime = Calendar.getInstance(); + Calendar endTime = Calendar.getInstance(); + endTime.setTimeInMillis(startTime.getTimeInMillis() + HALF_DURATION); + startTime.setTimeInMillis(startTime.getTimeInMillis() - HALF_DURATION); + + usageRecord.setPortletId(TEST_PORTLET_ID); + usageRecord.setOperationId(TEST_PORTLET_OPERATION_ID); + usageRecord.setMessage(TEST_PORTLET_MESSAGE); + + } catch (InvalidValueException e) { + logger.error(" ------ You SHOULD NOT SEE THIS MESSAGE. Error Creating a test Usage Record", e); + } + + return usageRecord; + } + + + + +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..de895c0 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n + + + + + + + + + + + \ No newline at end of file