refs #1746: Separate Accounting Model and generalize solution
https://support.d4science.org/issues/1746 git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/document-store-lib--mongodb@121989 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
commit
28f552106d
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>document-store-lib-mongodb</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -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/<project>=UTF-8
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
|
@ -0,0 +1,104 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.gcube.data.publishing</groupId>
|
||||
<artifactId>document-store-lib-mongodb</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>Document Store MongoDB</name>
|
||||
<description>Document Store MongoDB Implementation</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId}</connection>
|
||||
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId}</developerConnection>
|
||||
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.data.publishing</groupId>
|
||||
<artifactId>document-store-lib</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>[3.0.0, 3.0.7]</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.9-RC1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test Dependency -->
|
||||
<dependency>
|
||||
<groupId>org.gcube.accounting</groupId>
|
||||
<artifactId>accounting-lib</artifactId>
|
||||
<version>[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-encryption</artifactId>
|
||||
<version>[1.0.2-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.resources</groupId>
|
||||
<artifactId>registry-publisher</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT,)</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.0.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.documentstore.persistence;
|
||||
|
||||
import org.bson.BsonReader;
|
||||
import org.bson.BsonWriter;
|
||||
import org.bson.codecs.Codec;
|
||||
import org.bson.codecs.DecoderContext;
|
||||
import org.bson.codecs.EncoderContext;
|
||||
|
||||
public class EnumCodec<E extends Enum<E>> implements Codec<E> {
|
||||
|
||||
protected final Class<E> eClass;
|
||||
|
||||
public EnumCodec(Class<E> eClass){
|
||||
this.eClass = eClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(BsonWriter writer, E e, EncoderContext ec) {
|
||||
writer.writeString(e.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<E> getEncoderClass() {
|
||||
return this.eClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E decode(BsonReader reader, DecoderContext dc) {
|
||||
String enumString = reader.readString();
|
||||
return (E) Enum.valueOf(getEncoderClass(), enumString);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.documentstore.persistence;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bson.BsonReader;
|
||||
import org.bson.BsonWriter;
|
||||
import org.bson.codecs.Codec;
|
||||
import org.bson.codecs.DecoderContext;
|
||||
import org.bson.codecs.EncoderContext;
|
||||
|
||||
public class GenericCodec<T extends Comparable<? extends Serializable>> implements Codec<T> {
|
||||
|
||||
protected final Class<T> tClass;
|
||||
|
||||
public GenericCodec(Class<T> tClass){
|
||||
this.tClass = tClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(BsonWriter writer, T t, EncoderContext ec) {
|
||||
writer.writeString(t.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getEncoderClass() {
|
||||
return tClass;
|
||||
}
|
||||
|
||||
public T getFromString(String stringRepresentation) throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class[] argTypes = { String.class };
|
||||
Constructor<T> constructor = getEncoderClass().getDeclaredConstructor(argTypes);
|
||||
Object[] arguments = {stringRepresentation};
|
||||
return constructor.newInstance(arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decode(BsonReader reader, DecoderContext dc) {
|
||||
String stringRepresentation = reader.readString();
|
||||
try {
|
||||
return getFromString(stringRepresentation);
|
||||
} catch(Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.documentstore.persistence;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.codecs.Codec;
|
||||
import org.bson.codecs.configuration.CodecConfigurationException;
|
||||
import org.bson.codecs.configuration.CodecRegistries;
|
||||
import org.bson.codecs.configuration.CodecRegistry;
|
||||
import org.gcube.documentstore.records.Record;
|
||||
import org.gcube.documentstore.records.RecordUtility;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ReadPreference;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
public class PersistenceMongoDB extends PersistenceBackend {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PersistenceMongoDB.class);
|
||||
|
||||
public static final String URL_PROPERTY_KEY = "URL";
|
||||
public static final String USERNAME_PROPERTY_KEY = "username";
|
||||
public static final String PASSWORD_PROPERTY_KEY = "password";
|
||||
public static final String DB_NAME = "dbName";
|
||||
public static final String COLLECTION_NAME = "collectionName";
|
||||
|
||||
protected String collectionName;
|
||||
|
||||
protected static final ReadPreference READ_PREFERENCE;
|
||||
protected static final MongoClientOptions MONGO_CLIENT_OPTIONS;
|
||||
|
||||
static {
|
||||
READ_PREFERENCE = ReadPreference.secondaryPreferred();
|
||||
|
||||
List<? extends Codec<?>> additionalCodecs = discoverAdditionalCodecs();
|
||||
CodecRegistry mongoDefaultCR = MongoClient.getDefaultCodecRegistry();
|
||||
CodecRegistry cr = addCoded(mongoDefaultCR, additionalCodecs);
|
||||
MONGO_CLIENT_OPTIONS = createMongoClientOptions(cr);
|
||||
|
||||
}
|
||||
|
||||
protected PersistenceBackendConfiguration configuration;
|
||||
protected MongoClient mongoClient;
|
||||
protected MongoClientOptions mongoClientOptions;
|
||||
protected MongoDatabase mongoDatabase;
|
||||
|
||||
public static CodecRegistry addCoded(CodecRegistry cr, List<? extends Codec<?>> codecs){
|
||||
CodecRegistry crFromCodes = CodecRegistries.fromCodecs(codecs);
|
||||
return CodecRegistries.fromRegistries(cr, crFromCodes);
|
||||
}
|
||||
|
||||
protected static MongoClientOptions createMongoClientOptions(CodecRegistry cr){
|
||||
/*
|
||||
mongoClientOptions = MongoClientOptions.builder().
|
||||
codecRegistry(cr).connectionsPerHost(10).connectTimeout(30000).
|
||||
readPreference(READ_PREFERENCE).build();
|
||||
*/
|
||||
return MongoClientOptions.builder().codecRegistry(cr).build();
|
||||
}
|
||||
|
||||
public PersistenceMongoDB() throws Exception {
|
||||
super();
|
||||
mongoClientOptions = MONGO_CLIENT_OPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
mongoClient.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static List<? extends Codec<?>> discoverAdditionalCodecs(){
|
||||
List codecs = new ArrayList();
|
||||
|
||||
Set<Class<? extends Enum>> enumClasses = new HashSet<>();
|
||||
|
||||
Reflections recordClassesReflections = new Reflections();
|
||||
Set<Class<? extends Record>> recordClasses = recordClassesReflections.getSubTypesOf(Record.class);
|
||||
for(Class<? extends Record> recordClass : recordClasses){
|
||||
Class<?> auxClass = recordClass;
|
||||
while(auxClass!=null){
|
||||
Class<?>[] classes = auxClass.getClasses();
|
||||
for(Class<?> clz : classes){
|
||||
if(clz.isEnum()){
|
||||
if(!enumClasses.contains((Class<? extends Enum>) clz)){
|
||||
logger.trace("Found Enum {}", clz);
|
||||
enumClasses.add((Class<? extends Enum>) clz);
|
||||
}
|
||||
}
|
||||
}
|
||||
auxClass = auxClass.getSuperclass();
|
||||
}
|
||||
|
||||
}
|
||||
logger.trace("Found Enums : {}",enumClasses);
|
||||
|
||||
for(Class<? extends Enum> enumClass : enumClasses){
|
||||
EnumCodec<? extends Enum> enumCodec = new EnumCodec<>(enumClass);
|
||||
codecs.add(enumCodec);
|
||||
}
|
||||
|
||||
GenericCodec<URI> uriCodec = new GenericCodec<>(URI.class);
|
||||
codecs.add(uriCodec);
|
||||
return (List<? extends Codec<?>>) codecs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void prepareConnection(PersistenceBackendConfiguration configuration) throws Exception {
|
||||
logger.debug("Preparing Connection for {}", this.getClass().getSimpleName());
|
||||
this.configuration = configuration;
|
||||
|
||||
String url = configuration.getProperty(URL_PROPERTY_KEY);
|
||||
String username = configuration.getProperty(USERNAME_PROPERTY_KEY);
|
||||
String password = configuration.getProperty(PASSWORD_PROPERTY_KEY);
|
||||
String dbName = configuration.getProperty(DB_NAME);
|
||||
|
||||
MongoCredential credential = MongoCredential.createScramSha1Credential(
|
||||
username, dbName, password.toCharArray());
|
||||
|
||||
url = url.startsWith("http://") ? url.replace("http://", "") : url;
|
||||
ServerAddress serverAddress = new ServerAddress(url);
|
||||
|
||||
mongoClient = new MongoClient(serverAddress,
|
||||
Arrays.asList(credential), mongoClientOptions); //, MONGO_CLIENT_OPTIONS);
|
||||
|
||||
mongoDatabase = mongoClient.getDatabase(dbName);
|
||||
|
||||
collectionName = configuration.getProperty(COLLECTION_NAME);
|
||||
if(mongoDatabase.getCollection(collectionName)==null){
|
||||
mongoDatabase.createCollection(collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void createItem(Document document) throws Exception {
|
||||
mongoDatabase.getCollection(collectionName).insertOne(document);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static List<? extends Codec<?>> findMissingCodecs(CodecRegistry cr, Record record){
|
||||
@SuppressWarnings("rawtypes")
|
||||
List<Codec> codecs = new ArrayList<>();
|
||||
Collection<Comparable<? extends Serializable>> properties = record.getResourceProperties().values();
|
||||
for(@SuppressWarnings("rawtypes") Comparable value : properties){
|
||||
try {
|
||||
try {
|
||||
cr.get(value.getClass());
|
||||
logger.trace("Codec found for {} : {}", value.getClass(), value);
|
||||
}catch(CodecConfigurationException cce){
|
||||
logger.trace("No Codec found for {} : {}", value.getClass(), value);
|
||||
if(value.getClass().isEnum()){
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
EnumCodec<? extends Enum> enumCodec =
|
||||
new EnumCodec<>((Class<? extends Enum>) value.getClass());
|
||||
codecs.add(enumCodec);
|
||||
logger.trace("Adding {} to manage {} : {}", enumCodec, value.getClass(), value);
|
||||
}else{
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
GenericCodec genericCodec = new GenericCodec<>(value.getClass());
|
||||
try {
|
||||
Comparable<? extends Serializable> recreatedValue = genericCodec.getFromString(value.toString());
|
||||
if(value.compareTo(recreatedValue)==0){
|
||||
codecs.add(genericCodec);
|
||||
logger.trace("Adding {} to manage {} : {}", genericCodec, value.getClass(), value);
|
||||
}else{
|
||||
String message = String.format("%s != %s", value, recreatedValue);
|
||||
throw new Exception(message);
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("{} cannot be used for {} : {}", GenericCodec.class.getSimpleName(), value.getClass(), value, e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception ex){
|
||||
logger.error("Error evaluating if {} can be serialized as bson Object", value, ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return (List<? extends Codec<?>>) codecs;
|
||||
}
|
||||
|
||||
|
||||
protected void checkSerializability(Record record) throws Exception{
|
||||
CodecRegistry cr = mongoClientOptions.getCodecRegistry();
|
||||
List<? extends Codec<?>> codecs = findMissingCodecs(cr, record);
|
||||
|
||||
if(!codecs.isEmpty()){
|
||||
logger.debug("Recreating Mongo CLient to Add Codecs");
|
||||
CodecRegistry newCR = addCoded(cr, (List<? extends Codec<?>>) codecs);
|
||||
mongoClientOptions = createMongoClientOptions(newCR);
|
||||
mongoClient.close();
|
||||
prepareConnection(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void reallyAccount(Record record) throws Exception {
|
||||
checkSerializability(record);
|
||||
Document document = usageRecordToDocument(record);
|
||||
createItem(document);
|
||||
}
|
||||
|
||||
public static Document usageRecordToDocument(Record record) throws Exception {
|
||||
Document document = new Document();
|
||||
document.putAll(record.getResourceProperties());
|
||||
return document;
|
||||
}
|
||||
|
||||
protected static Record documentToUsageRecord(Document document) throws Exception {
|
||||
Map<String, Comparable<? extends Serializable>> map = new
|
||||
HashMap<String, Comparable<? extends Serializable>>();
|
||||
Set<Entry<String, Object>> set = document.entrySet();
|
||||
for(Entry<String, Object> entry : set){
|
||||
@SuppressWarnings("unchecked")
|
||||
Comparable<? extends Serializable> value =
|
||||
(Comparable<? extends Serializable>) entry.getValue();
|
||||
map.put(entry.getKey(), value);
|
||||
}
|
||||
Record record = RecordUtility.getRecord(map);
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.gcube.documentstore.persistence.PersistenceMongoDB
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.persistence;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.resources.gcore.Resource;
|
||||
import org.gcube.common.resources.gcore.Resources;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.documentstore.persistence.PersistenceMongoDB;
|
||||
import org.gcube.documentstore.persistence.PersistenceBackend;
|
||||
import org.gcube.documentstore.persistence.PersistenceBackendFactory;
|
||||
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
|
||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
||||
import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PersistenceMongoDBTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PersistenceMongoDBTest.class);
|
||||
|
||||
public static PersistenceBackend getPersistence(){
|
||||
ScopeProvider.instance.set("/gcube/devNext");
|
||||
PersistenceBackendFactory.setFallbackLocation(null);
|
||||
return PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceIsMongoDB() {
|
||||
PersistenceBackend accountingPersistence = getPersistence();
|
||||
Assert.assertTrue(accountingPersistence instanceof PersistenceMongoDB);
|
||||
}
|
||||
|
||||
private static void publishScopedResource(Resource resource, List<String> scopes) throws Exception {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Resources.marshal(resource, stringWriter);
|
||||
|
||||
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
|
||||
try {
|
||||
logger.debug("Trying to publish to {}:\n{}", scopes, stringWriter);
|
||||
scopedPublisher.create(resource, scopes);
|
||||
} catch (Exception e) {
|
||||
logger.error("The resource was not published", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static void unPublishScopedResource(Resource resource, List<String> scopes) throws RegistryNotFoundException, Exception {
|
||||
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
|
||||
String id = resource.id();
|
||||
logger.debug("Trying to remove {} with ID {} from {}", resource.getClass().getSimpleName(), id, scopes);
|
||||
scopedPublisher.remove(resource, scopes);
|
||||
logger.debug("{} with ID {} removed successfully", resource.getClass().getSimpleName(), id);
|
||||
}
|
||||
|
||||
public void testScopeRecheck() throws Exception {
|
||||
final String vreScopeToUse = "/gcube/devsec/LucioVRE";
|
||||
final String parentVREScopeToUse = "/gcube/devsec";
|
||||
|
||||
ScopeProvider.instance.set(vreScopeToUse);
|
||||
|
||||
ServiceEndpoint serviceEndpoint = null;
|
||||
try {
|
||||
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(PersistenceMongoDB.class);
|
||||
serviceEndpoint = persitenceConfiguration.getServiceEndpoint(
|
||||
AccountingPersistenceConfiguration.SERVICE_ENDPOINT_CATEGORY, AccountingPersistenceConfiguration.SERVICE_ENDPOINT_NAME,
|
||||
PersistenceMongoDB.class);
|
||||
List<String> scopes = new ArrayList<String>();
|
||||
scopes.add(ScopeProvider.instance.get());
|
||||
unPublishScopedResource(serviceEndpoint, scopes);
|
||||
} catch(IndexOutOfBoundsException e){
|
||||
ScopeProvider.instance.set(parentVREScopeToUse);
|
||||
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(PersistenceMongoDB.class);
|
||||
serviceEndpoint = persitenceConfiguration.getServiceEndpoint(
|
||||
AccountingPersistenceConfiguration.SERVICE_ENDPOINT_CATEGORY,
|
||||
AccountingPersistenceConfiguration.SERVICE_ENDPOINT_NAME,
|
||||
PersistenceMongoDB.class);
|
||||
ScopeProvider.instance.set(vreScopeToUse);
|
||||
}
|
||||
|
||||
|
||||
long startTime = Calendar.getInstance().getTimeInMillis();
|
||||
long endTime = startTime;
|
||||
while(endTime <= (startTime + 10*1000)){ // 10 sec
|
||||
endTime = Calendar.getInstance().getTimeInMillis();
|
||||
}
|
||||
|
||||
logger.debug("Going to check First Time");
|
||||
PersistenceBackend first = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
|
||||
logger.debug("First {} : {}", PersistenceBackend.class.getSimpleName(), first);
|
||||
|
||||
List<String> scopes = new ArrayList<String>();
|
||||
scopes.add(ScopeProvider.instance.get());
|
||||
publishScopedResource(serviceEndpoint, scopes);
|
||||
|
||||
startTime = Calendar.getInstance().getTimeInMillis();
|
||||
endTime = startTime;
|
||||
while(endTime <= (startTime + (PersistenceBackendFactory.FALLBACK_RETRY_TIME + 100))){
|
||||
endTime = Calendar.getInstance().getTimeInMillis();
|
||||
}
|
||||
|
||||
logger.debug("Going to check Second Time");
|
||||
PersistenceBackend second = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
|
||||
logger.debug("Second {} : {}", PersistenceBackend.class.getSimpleName(), second);
|
||||
|
||||
Assert.assertNotEquals(first, second);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.documentstore.persistence;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.gcube.accounting.datamodel.UsageRecord;
|
||||
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.OperationType;
|
||||
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.documentstore.records.Record;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PersistenceMongoDBTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PersistenceMongoDBTest.class);
|
||||
|
||||
@Test
|
||||
public void testJsonNodeUsageRecordConversions() throws Exception {
|
||||
Record record = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
|
||||
logger.debug("UsageRecord : {}", record.toString());
|
||||
Document document = PersistenceMongoDB.usageRecordToDocument(record);
|
||||
logger.debug("Document : {}", document.toString());
|
||||
Record r = PersistenceMongoDB.documentToUsageRecord(document);
|
||||
Assert.assertEquals(0, record.compareTo(r));
|
||||
Assert.assertEquals(0, r.compareTo(record));
|
||||
}
|
||||
|
||||
public enum AUX {
|
||||
TEST, TESTER, TESTING
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfiguration() throws Exception{
|
||||
ScopeProvider.instance.set("/gcube/devNext");
|
||||
URL url = new URL("http://mongo-test.d4science.org");
|
||||
|
||||
PersistenceBackendConfiguration persitenceConfiguration = PersistenceBackendConfiguration.getUnconfiguredInstance();
|
||||
persitenceConfiguration.addProperty(PersistenceMongoDB.URL_PROPERTY_KEY, url.toString());
|
||||
persitenceConfiguration.addProperty(PersistenceMongoDB.USERNAME_PROPERTY_KEY, "accounting");
|
||||
persitenceConfiguration.addProperty(PersistenceMongoDB.PASSWORD_PROPERTY_KEY, "testpwd");
|
||||
persitenceConfiguration.addProperty(PersistenceMongoDB.DB_NAME,"accounting");
|
||||
persitenceConfiguration.addProperty(PersistenceMongoDB.COLLECTION_NAME, UsageRecord.class.getSimpleName());
|
||||
PersistenceMongoDB mongo = new PersistenceMongoDB();
|
||||
mongo.prepareConnection(persitenceConfiguration);
|
||||
|
||||
|
||||
Record record = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
|
||||
record.setResourceProperty("Test", AUX.TESTER);
|
||||
mongo.reallyAccount(record);
|
||||
|
||||
record = TestUsageRecord.createTestStorageUsageRecordAutomaticScope();
|
||||
record.setResourceProperty("Test", AUX.TESTER);
|
||||
mongo.reallyAccount(record);
|
||||
|
||||
record = TestUsageRecord.createTestJobUsageRecordAutomaticScope();
|
||||
mongo.reallyAccount(record);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
EnumCodec<OperationType> enumCodec = new EnumCodec<OperationType>(OperationType.class);
|
||||
Assert.assertEquals(OperationType.class, enumCodec.getEncoderClass());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="org.gcube" level="TRACE" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
Reference in New Issue