commit 43175131bdfcdaa20bb00e3a3137fd19f2ea6ea8 Author: luca.frosini Date: Mon Jul 18 09:57:12 2016 +0000 Creating Trunk Branch git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/resource-registry@130462 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..e3ebbb8 --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + resource-registry + + + + + + 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..80e728d --- /dev/null +++ b/distro/README @@ -0,0 +1,65 @@ +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 +-------------------------------------------------- + +* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). + +Maintainers +----------- + +* Luca Frosini (luca.frosini-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}/InformationSystem + + +Documentation +-------------------------------------------------- + +Documentation is available on-line in the gCube Wiki: + ${gcube.wikiRoot}/InformationSystem + + +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..20e84a4 --- /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..8a335f7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,175 @@ + + 4.0.0 + + org.gcube.tools + maven-parent + 1.0.0 + + org.gcube.information-system + resource-registry + 1.0.0-SNAPSHOT + Information Collector + Information Collector + + + UTF-8 + ${project.basedir}/distro + InformationSystem + + + + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/${project.artifactId} + scm:https://svn.d4science.research-infrastructures.eu/gcube//trunk/information-system/${project.artifactId} + https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/${project.artifactId} + + + + + + org.gcube.distribution + maven-smartgears-bom + LATEST + pom + import + + + + + + + + org.gcube.core + common-encryption + provided + + + org.gcube.core + common-smartgears-app + provided + + + + org.gcube.common + authorization-client + provided + + + org.gcube.common + common-authorization + provided + + + + org.gcube.information-system + resource-registry-api + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + + org.gcube.information-system + information-system-model + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + + org.gcube.information-system + information-system-model-orientdb-binding + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + + + com.orientechnologies + orientdb-graphdb + 2.2.0 + + + + com.tinkerpop + frames + 2.5.0 + + + + + + javax.ws.rs + javax.ws.rs-api + 2.0 + + + org.glassfish.jersey.containers + jersey-container-servlet + 2.13 + + + org.glassfish.jersey.containers.glassfish + jersey-gf-cdi + 2.13 + + + + javax.transaction + javax.transaction-api + 1.2 + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + org.slf4j + slf4j-api + provided + + + + + javax.enterprise + cdi-api + 1.1 + + + org.jboss.weld.servlet + weld-servlet + 2.2.4.Final + + + org.jboss + jandex + 1.2.2.Final + + + + + junit + junit + 4.11 + test + + + + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-simple + 2.17 + test + + + + org.gcube.information-system + gcube-resources + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + test + + + + ch.qos.logback + logback-classic + 1.0.13 + test + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ResourceInitializer.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ResourceInitializer.java new file mode 100644 index 0000000..8445be6 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ResourceInitializer.java @@ -0,0 +1,16 @@ +package org.gcube.informationsystem.resourceregistry; + +import javax.ws.rs.ApplicationPath; + +import org.glassfish.jersey.server.ResourceConfig; + +@ApplicationPath("/") +public class ResourceInitializer extends ResourceConfig { + + public ResourceInitializer(){ + packages("org.gcube.informationsystem.resourceregistry.resources"); + + } + + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java new file mode 100644 index 0000000..d31c104 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java @@ -0,0 +1,48 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.HashMap; +import java.util.Map; + +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; + + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class DatabaseEnvironment { + + /* --- TODO START OF VARIABLES TO GET FROM CONFIGURATION FILE */ + // public static final String HOST = "orientdb01-d-d4s.d4science.org"; + public static final String HOST = "pc-frosini.isti.cnr.it"; + public static final String REMOTE_PROTOCOL = "remote:"; + public static final String REMOTE_URI = REMOTE_PROTOCOL + HOST; + public static final String HTTP_PROTOCOL = "http://"; + public static final String HTTP_PORT = ":2480"; + public static final String HTTP_URL_STRING = HTTP_PROTOCOL + HOST + HTTP_PORT; + public static final String DB = "IS"; + public static final String URI_DB = REMOTE_URI + "/" + DB; + public static final String USERNAME = "root"; + public static final String PASSWORD = "testpwd"; //"D4S*ll2T16"; + public static final String CHANGED_ADMIN_PASSWORD = "D4S*ll2T16"; + /* --- END OF VARIABLES TO GET FROM CONFIGURATION FILE */ + + public static final String DEFAULT_ADMIN_USERNAME = "admin"; + public static final String DEFAULT_ADMIN_PASSWORD = "admin"; + + private static final String DEFAULT_CREATED_WRITER_USER_PASSWORD = "Choomae5"; + private static final String DEFAULT_CREATED_READER_USER_PASSWORD = "Chetho4s"; + + public static final Map DEFAULT_PASSWORDS; + + static { + DEFAULT_PASSWORDS = new HashMap(); + + DEFAULT_PASSWORDS.put(PermissionMode.WRITER, DEFAULT_CREATED_WRITER_USER_PASSWORD); + DEFAULT_PASSWORDS.put(PermissionMode.READER, DEFAULT_CREATED_READER_USER_PASSWORD); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseIntializator.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseIntializator.java new file mode 100644 index 0000000..c05e5c6 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseIntializator.java @@ -0,0 +1,118 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.HashSet; +import java.util.Set; + +import org.gcube.informationsystem.model.embedded.Embedded; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.orientechnologies.orient.client.remote.OServerAdmin; +import com.orientechnologies.orient.core.metadata.OMetadata; +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OSchema; +import com.orientechnologies.orient.core.metadata.security.OSecurity; +import com.orientechnologies.orient.core.metadata.security.OUser; +import com.tinkerpop.blueprints.impls.orient.OrientEdgeType; +import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; +import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx; +import com.tinkerpop.blueprints.impls.orient.OrientVertexType; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class DatabaseIntializator { + + private static Logger logger = LoggerFactory.getLogger(DatabaseIntializator.class); + + private static final String DATABASE_TYPE = "graph"; + private static final String STORAGE_MODE = "plocal"; + + private static final String O_RESTRICTED_CLASS = "ORestricted"; + + + + private static Set packages; + + public static void addPackage(Package p){ + packages.add(p); + } + + static { + packages = new HashSet<>(); + } + + public static boolean initGraphDB() throws Exception { + + logger.trace("Connecting to {} as {} to create new DB", DatabaseEnvironment.URI_DB, DatabaseEnvironment.USERNAME); + OServerAdmin serverAdmin = new OServerAdmin(DatabaseEnvironment.URI_DB).connect(DatabaseEnvironment.USERNAME, + DatabaseEnvironment.PASSWORD); + + if (!serverAdmin.existsDatabase()) { + + logger.trace("Creating Database {}", DatabaseEnvironment.URI_DB); + serverAdmin.createDatabase(DatabaseEnvironment.DB, DATABASE_TYPE, STORAGE_MODE); + + logger.trace( + "Connecting to newly created database {} as {} with default password", + DatabaseEnvironment.URI_DB, DatabaseEnvironment.DEFAULT_ADMIN_USERNAME); + OrientGraphFactory factory = new OrientGraphFactory(DatabaseEnvironment.URI_DB, + DatabaseEnvironment.DEFAULT_ADMIN_USERNAME, DatabaseEnvironment.DEFAULT_ADMIN_PASSWORD).setupPool( + 1, 10); + + OrientGraphNoTx orientGraphNoTx = factory.getNoTx(); + + OMetadata oMetadata = orientGraphNoTx.getRawGraph().getMetadata(); + OSecurity oSecurity = oMetadata.getSecurity(); + + logger.trace("Changing {} password", DatabaseEnvironment.DEFAULT_ADMIN_USERNAME); + OUser admin = oSecurity.getUser(DatabaseEnvironment.DEFAULT_ADMIN_USERNAME); + admin.setPassword(DatabaseEnvironment.CHANGED_ADMIN_PASSWORD); + admin.save(); + + for (PermissionMode permissionMode : DatabaseEnvironment.DEFAULT_PASSWORDS.keySet()) { + OUser oUser = oSecurity.getUser(permissionMode.toString()); + oUser.setPassword(DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode)); + oUser.save(); + logger.trace("Updating password for user {}", permissionMode.toString()); + } + + logger.trace("Setting Record-level Security (see https://orientdb.com/docs/last/Database-Security.html)"); + OSchema oSchema = oMetadata.getSchema(); + OClass oRestricted = oSchema.getClass(O_RESTRICTED_CLASS); + + OrientVertexType v = orientGraphNoTx.getVertexBaseType(); + v.addSuperClass(oRestricted); + + OrientEdgeType e = orientGraphNoTx.getEdgeBaseType(); + e.addSuperClass(oRestricted); + + orientGraphNoTx.commit(); + orientGraphNoTx.shutdown(); + + factory.close(); + + return true; + } + + return false; + } + + public static void createEntitiesAndRelations() throws Exception{ + SchemaInitializator.addPackage(Embedded.class.getPackage()); + SchemaInitializator.addPackage(Entity.class.getPackage()); + SchemaInitializator.addPackage(Relation.class.getPackage()); + for(Package p : packages){ + SchemaInitializator.addPackage(p); + } + SchemaInitializator.createTypes(); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ReflectionUtility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ReflectionUtility.java new file mode 100644 index 0000000..d01b0ed --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ReflectionUtility.java @@ -0,0 +1,199 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * Got from + * http://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection#answer-22462785 + * + * The method first gets the current ClassLoader. It then fetches all resources + * that contain said package and iterates of these URLs. It then creates a + * URLConnection and determines what type of URL we have. It can either be a + * directory (FileURLConnection) or a directory inside a jar or zip file + * (JarURLConnection). Depending on what type of connection we have two + * different methods will be called. + * + * First lets see what happens if it is a FileURLConnection. + * + * It first checks if the passed File exists and is a directory. If that's the + * case it checks if it is a class file. If so a Class object will be created + * and put in the List. If it is not a class file but is a directory, we + * simply iterate into it and do the same thing. All other cases/files will be + * ignored. + * + * If the URLConnection is a JarURLConnection the other private helper method + * will be called. This method iterates over all Entries in the zip/jar + * archive. If one entry is a class file and is inside of the package a Class + * object will be created and stored in the ArrayList. + * + * After all resources have been parsed it (the main method) returns the + * ArrayList containing all classes in the given package, that the current + * ClassLoader knows about. + * + * If the process fails at any point a ClassNotFoundException will be thrown + * containing detailed information about the exact cause. + * + */ +class ReflectionUtility { + + /** + * Private helper method + * + * @param directory + * The directory to start with + * @param pckgname + * The package name to search for. Will be needed for getting the + * Class object. + * @param classes + * if a file isn't loaded but still is in the directory + * @throws ClassNotFoundException + */ + private static void checkDirectory(File directory, String pckgname, + List> classes) throws ClassNotFoundException { + File tmpDirectory; + + if (directory.exists() && directory.isDirectory()) { + final String[] files = directory.list(); + + for (final String file : files) { + if (file.endsWith(".class")) { + try { + classes.add(Class.forName(pckgname + '.' + + file.substring(0, file.length() - 6))); + } catch (final NoClassDefFoundError e) { + // do nothing. this class hasn't been found by the + // loader, and we don't care. + } + } else if ((tmpDirectory = new File(directory, file)) + .isDirectory()) { + checkDirectory(tmpDirectory, pckgname + "." + file, classes); + } + } + } + } + + /** + * Private helper method. + * + * @param connection + * the connection to the jar + * @param pckgname + * the package name to search for + * @param classes + * the current ArrayList of all classes. This method will simply + * add new classes. + * @throws ClassNotFoundException + * if a file isn't loaded but still is in the jar file + * @throws IOException + * if it can't correctly read from the jar file. + */ + private static void checkJarFile(JarURLConnection connection, + String pckgname, List> classes) + throws ClassNotFoundException, IOException { + final JarFile jarFile = connection.getJarFile(); + final Enumeration entries = jarFile.entries(); + String name; + + for (JarEntry jarEntry = null; entries.hasMoreElements() + && ((jarEntry = entries.nextElement()) != null);) { + name = jarEntry.getName(); + + if (name.contains(".class")) { + name = name.substring(0, name.length() - 6).replace('/', '.'); + + if (name.contains(pckgname)) { + classes.add(Class.forName(name)); + } + } + } + } + + public static List> getClassesForPackage(Package packageObject) + throws ClassNotFoundException { + return getClassesForPackage(packageObject.getName()); + } + + /** + * Attempts to list all the classes in the specified package as determined + * by the context class loader + * + * @param pckgname + * the package name to search + * @return a list of classes that exist within that package + * @throws ClassNotFoundException + * if something went wrong + */ + @SuppressWarnings("restriction") + public static List> getClassesForPackage(String pckgname) + throws ClassNotFoundException { + final List> classes = new ArrayList>(); + + try { + final ClassLoader cld = Thread.currentThread() + .getContextClassLoader(); + + if (cld == null) + throw new ClassNotFoundException("Can't get class loader."); + + final Enumeration resources = cld.getResources(pckgname + .replace('.', '/')); + URLConnection connection; + + for (URL url = null; resources.hasMoreElements() + && ((url = resources.nextElement()) != null);) { + try { + connection = url.openConnection(); + + if (connection instanceof JarURLConnection) { + checkJarFile((JarURLConnection) connection, pckgname, + classes); + } else if (connection instanceof sun.net.www.protocol.file.FileURLConnection) { + try { + checkDirectory( + new File(URLDecoder.decode(url.getPath(), + "UTF-8")), pckgname, classes); + } catch (final UnsupportedEncodingException ex) { + throw new ClassNotFoundException( + pckgname + + " does not appear to be a valid package (Unsupported encoding)", + ex); + } + } else + throw new ClassNotFoundException(pckgname + " (" + + url.getPath() + + ") does not appear to be a valid package"); + } catch (final IOException ioex) { + throw new ClassNotFoundException( + "IOException was thrown when trying to get all resources for " + + pckgname, ioex); + } + } + } catch (final NullPointerException ex) { + throw new ClassNotFoundException( + pckgname + + " does not appear to be a valid package (Null pointer exception)", + ex); + } catch (final IOException ioex) { + throw new ClassNotFoundException( + "IOException was thrown when trying to get all resources for " + + pckgname, ioex); + } + + return classes; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaInitializator.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaInitializator.java new file mode 100644 index 0000000..07db14b --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaInitializator.java @@ -0,0 +1,416 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.gcube.informationsystem.model.embedded.Embedded; +import org.gcube.informationsystem.model.embedded.ValueSchema; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.model.entity.Resource; +import org.gcube.informationsystem.model.relation.ConsistOf; +import org.gcube.informationsystem.model.relation.RelatedTo; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.resourceregistry.dbinitialization.Tree.Node; +import org.gcube.informationsystem.resourceregistry.dbinitialization.Tree.NodeVisitor; +import org.gcube.informationsystem.resourceregistry.resources.impl.SchemaManagementImpl; +import org.gcube.informationsystem.types.TypeBinder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +@SuppressWarnings("rawtypes") +public class SchemaInitializator { + + private static Logger logger = LoggerFactory.getLogger(SchemaInitializator.class); + + private static Set packages; + + private static final Comparator> entityComparator; + private static final Comparator> relationComparator; + private static final Comparator> embeddedComparator; + + + private static boolean DRY_RUN; + + static { + DRY_RUN = false; + packages = new HashSet<>(); + + entityComparator = new Comparator>() { + + @Override + public int compare(Class o1, Class o2) { + //logger.trace("Comparing {} with {}", o1, o2); + return String.valueOf(o1).compareTo(String.valueOf(o2)); + } + }; + + relationComparator = new Comparator>() { + + @Override + public int compare(Class o1, Class o2) { + //logger.trace("Comparing {} with {}", o1, o2); + return String.valueOf(o1).compareTo(String.valueOf(o2)); + } + }; + + embeddedComparator = new Comparator>() { + + @Override + public int compare(Class o1, Class o2) { + //logger.trace("Comparing {} with {}", o1, o2); + return String.valueOf(o1).compareTo(String.valueOf(o2)); + } + }; + + } + + protected static void addPackage(Package p){ + packages.add(p); + } + + @SuppressWarnings("unchecked") + protected static void analizeVertex(Map,Node>> visitedVertex, Class clz) { + logger.trace(" --- Analizyng Entity {}", clz.getCanonicalName()); + if(visitedVertex.containsKey(clz)){ + logger.trace(" --------- discarding {} because was already managed", clz); + return; + }else{ + //logger.trace(" --------- Adding {} to {}", clz, ); + + Class[] interfaces = clz.getInterfaces(); + List> interfaceList = new ArrayList<>(); + + for (Class interfaceClass : interfaces) { + if(!Entity.class.isAssignableFrom(interfaceClass)){ + logger.trace(" --------- discarding {} because is not a {}", interfaceClass, Entity.class.getSimpleName()); + continue; + } + + Class v = (Class) interfaceClass; + + if(visitedVertex.containsKey(v)){ + Node> root = visitedVertex.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedVertex.put(clz, node); + break; + }else{ + interfaceList.add((Class) interfaceClass); + } + } + + if(!visitedVertex.containsKey(clz)){ + for(Class interfaceClass : interfaceList){ + analizeVertex(visitedVertex, interfaceClass); + Class v = (Class) interfaceClass; + Node> root = visitedVertex.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedVertex.put(clz, node); + break; + } + } + + logger.trace("{}", (Object[]) interfaces); + } + } + + + @SuppressWarnings("unchecked") + protected static void analizeEmbedded(Map,Node>> visitedEmbedded, Class clz) { + logger.trace(" --- Analizyng Embedded {}", clz.getCanonicalName()); + if(visitedEmbedded.containsKey(clz)){ + logger.trace(" --------- discarding {} because was already managed", clz); + return; + }else{ + //logger.trace(" --------- Adding {} to {}", clz, ); + + Class[] interfaces = clz.getInterfaces(); + List> interfaceList = new ArrayList<>(); + + for (Class interfaceClass : interfaces) { + if(!Embedded.class.isAssignableFrom(interfaceClass)){ + logger.trace(" --------- discarding {} because is not a {}", interfaceClass, Embedded.class.getSimpleName()); + continue; + } + + Class v = (Class) interfaceClass; + + if(visitedEmbedded.containsKey(v)){ + Node> root = visitedEmbedded.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedEmbedded.put(clz, node); + break; + }else{ + interfaceList.add((Class) interfaceClass); + } + } + + if(!visitedEmbedded.containsKey(clz)){ + for(Class interfaceClass : interfaceList){ + analizeEmbedded(visitedEmbedded, interfaceClass); + Class v = (Class) interfaceClass; + Node> root = visitedEmbedded.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedEmbedded.put(clz, node); + break; + } + } + + logger.trace("{}", (Object[]) interfaces); + } + } + + @SuppressWarnings({ "unchecked"}) + protected static void analizeEdge(Map,Node>> visitedEdge, Class clz) { + logger.trace(" --- Analizyng Relation {}", clz.getCanonicalName()); + if(visitedEdge.containsKey(clz)){ + logger.trace(" --------- discarding {} because was already managed", clz); + return; + }else{ + + Class[] interfaces = clz.getInterfaces(); + List> interfaceList = new ArrayList<>(); + + for (Class interfaceClass : interfaces) { + if(!Relation.class.isAssignableFrom(interfaceClass)){ + logger.trace(" --------- discarding {} because is not a {}", interfaceClass, Relation.class.getSimpleName()); + continue; + } + Class v = (Class) interfaceClass; + + if(visitedEdge.containsKey(v)){ + Node> root = visitedEdge.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedEdge.put(clz, node); + break; + }else{ + interfaceList.add((Class) interfaceClass); + } + } + + if(!visitedEdge.containsKey(clz)){ + for(Class interfaceClass : interfaceList){ + analizeEdge(visitedEdge, interfaceClass); + Class v = (Class) interfaceClass; + Node> root = visitedEdge.get(v); + logger.trace(" --------- Adding {} to {}", clz, root); + Node> node = root.addChild(clz); + visitedEdge.put(clz, node); + break; + } + } + + logger.trace("{}", (Object[]) interfaces); + } + } + + + protected static NodeVisitor> printNodeVisitor(Class t) { + return new NodeVisitor>() { + + @Override + public boolean visit(final Node> node) { + final StringBuilder sb = new StringBuilder(); + Node> curr = node; + do { + if (sb.length() > 0) { + sb.insert(0, " > "); + } + sb.insert(0, String.valueOf(curr.getValue())); + curr = curr.getParent(); + } while (curr != null); + logger.debug(sb.toString()); + return true; + } + }; + } + + protected static void createEmbedded(final Node> node){ + + @SuppressWarnings("unchecked") + Class clz = (Class) node.getValue(); + + if(clz==Embedded.class){ + logger.trace("Discarding {} because is just a convenient interface", clz); + return; + } + + if(ValueSchema.class.isAssignableFrom(clz)){ + logger.trace("Discarding {} because was programmatically already created", clz); + return; + } + + try{ + String json = TypeBinder.serializeType(clz); + logger.trace(json); + if(!DRY_RUN){ + new SchemaManagementImpl().registerEmbeddedTypeSchema(json); + } + } catch(Exception e){ + logger.error("error serializing schema", e); + } + + } + + protected static void createVertex(final Node> node){ + + @SuppressWarnings("unchecked") + Class clz = (Class) node.getValue(); + + try{ + String json = TypeBinder.serializeType(clz); + logger.trace(json); + if(!DRY_RUN){ + if (Facet.class.isAssignableFrom(clz)) { + new SchemaManagementImpl().registerFacetSchema(json); + } else if(Resource.class.isAssignableFrom(clz)){ + new SchemaManagementImpl().registerResourceSchema(json); + } else { + new SchemaManagementImpl().registerEntitySchema(json); + } + } + } catch(Exception e){ + logger.error("error serializing schema", e); + } + + } + + protected static void createEdge(final Node> node){ + + @SuppressWarnings("unchecked") + Class clz = (Class) node.getValue(); + + try{ + String json = TypeBinder.serializeType(clz); + logger.trace(json); + if(!DRY_RUN){ + if (ConsistOf.class.isAssignableFrom(clz)) { + new SchemaManagementImpl().registerConsistOfSchema(json); + } else if(RelatedTo.class.isAssignableFrom(clz)){ + new SchemaManagementImpl().registerRelatedToSchema(json); + } else { + new SchemaManagementImpl().registerRelationSchema(json); + } + } + } catch(Exception e){ + logger.error("error serializing schema", e); + } + + } + + protected static NodeVisitor> getNodeVisitor(Class t) { + return new NodeVisitor>() { + + @Override + public boolean visit(final Node> node) { + Class clz = node.getValue(); + if(Embedded.class.isAssignableFrom(clz)) { + createEmbedded(node); + }else if (Entity.class.isAssignableFrom(clz)) { + createVertex(node); + }else if (Relation.class.isAssignableFrom(clz)) { + createEdge(node); + } + return true; + } + }; + } + + + @SuppressWarnings({ "unchecked"}) + public static void createTypes() throws Exception{ + + Tree> embeddeds = new Tree<>(embeddedComparator); + Tree> vertexes = new Tree<>(entityComparator); + Tree> edges = new Tree<>(relationComparator); + + + Map, Node>> addedEmbedded = new TreeMap<>(embeddedComparator); + Map, Node>> addedVertex = new TreeMap<>(entityComparator); + Map, Node>> addedEdge = new TreeMap<>(relationComparator); + + + Node> rootEmbedded = embeddeds.getRootElement(); + rootEmbedded.setValue(Embedded.class); + addedEmbedded.put(Embedded.class, rootEmbedded); + + Node> rootVertex = vertexes.getRootElement(); + rootVertex.setValue(Entity.class); + addedVertex.put(Entity.class, rootVertex); + + Node> rootEdge = edges.getRootElement(); + rootEdge.setValue(Relation.class); + addedEdge.put(Relation.class, rootEdge); + + + for (Package p : packages) { + logger.trace("Analyzing {}", p); + try { + List> classes = ReflectionUtility.getClassesForPackage(p); + for (Class clz : classes) { + //logger.trace("Analyzing {}", clz); + if(!clz.isInterface()){ + logger.trace("Discarding {} that is not an interface", clz); + continue; + } + + if (Embedded.class.isAssignableFrom(clz)) { + analizeEmbedded(addedEmbedded, (Class) clz); + } + + if (Entity.class.isAssignableFrom(clz)) { + analizeVertex(addedVertex, (Class) clz); + } + + if (Relation.class.isAssignableFrom(clz)) { + analizeEdge(addedEdge, (Class) clz); + } + } + } catch (ClassNotFoundException e) { + logger.error("Error discovering classes inside package {}", + p.getName(), e); + throw e; + } + } + + + try{ + String json = TypeBinder.serializeType(ValueSchema.class); + logger.trace(json); + if(!DRY_RUN){ + new SchemaManagementImpl().registerEmbeddedTypeSchema(json); + } + } catch(Exception e){ + logger.error("error serializing schema", e); + } + createEmbedded(addedEmbedded.get(ValueSchema.class)); + + NodeVisitor> embeddedNodeVisitor = getNodeVisitor(Embedded.class); + embeddeds.visitNodes(embeddedNodeVisitor); + + NodeVisitor> vertexNodeVisitor = getNodeVisitor(Entity.class); + vertexes.visitNodes(vertexNodeVisitor); + + NodeVisitor> edgeNodeVisitor = getNodeVisitor(Relation.class); + edges.visitNodes(edgeNodeVisitor); + + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContext.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContext.java new file mode 100644 index 0000000..0af6a5e --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContext.java @@ -0,0 +1,129 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.Iterator; + +import com.orientechnologies.orient.core.metadata.security.ORestrictedOperation; +import com.orientechnologies.orient.core.metadata.security.ORole; +import com.orientechnologies.orient.core.metadata.security.OSecurity; +import com.orientechnologies.orient.core.metadata.security.OSecurityRole.ALLOW_MODES; +import com.orientechnologies.orient.core.record.impl.ODocument; +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.orient.OrientEdge; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientVertex; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class SecurityContext { + + public static final String DEFAULT_WRITER_ROLE = "writer"; + public static final String DEFAULT_READER_ROLE = "reader"; + + public static void addToSecurityContext(OrientGraph orientGraph, Vertex vertex, String contextID){ + OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() + .getSecurity(); + SecurityContext.addToSecurityContext(oSecurity, vertex, contextID); + } + + public static void addToSecurityContext(OSecurity oSecurity, Vertex vertex, String contextID){ + OrientVertex orientVertex = (OrientVertex) vertex; + + SecurityContext.allowSecurityContextRoles(oSecurity, orientVertex.getRecord(), contextID); + + Iterable iterable = vertex.getEdges(Direction.BOTH); + Iterator iterator = iterable.iterator(); + while(iterator.hasNext()){ + OrientEdge edge = (OrientEdge) iterator.next(); + SecurityContext.allowSecurityContextRoles(oSecurity, edge.getRecord(), contextID); + } + } + + public static void addToSecurityContext(OrientGraph orientGraph, Edge edge, String contextID){ + OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() + .getSecurity(); + SecurityContext.addToSecurityContext(oSecurity, edge, contextID); + } + + public static void addToSecurityContext(OSecurity oSecurity, Edge edge, String contextID){ + OrientEdge orientEdge = (OrientEdge) edge; + SecurityContext.allowSecurityContextRoles(oSecurity, orientEdge.getRecord(), contextID); + } + + protected static void allowSecurityContextRoles(OSecurity oSecurity, ODocument oDocument, String contextID){ + oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_ALL, + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.ROLE, contextID)); + + oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.ROLE, contextID)); + + oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_ALL, DEFAULT_WRITER_ROLE); + + oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, DEFAULT_READER_ROLE); + } + + public static void createSecurityContext(OrientGraph orientGraph, String contextID){ + OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() + .getSecurity(); + + ORole writer = oSecurity.getRole(DEFAULT_WRITER_ROLE); + ORole reader = oSecurity.getRole(DEFAULT_READER_ROLE); + + ORole writerRole = oSecurity.createRole( + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.ROLE, contextID), + writer, ALLOW_MODES.DENY_ALL_BUT); + + ORole readerRole = oSecurity.createRole( + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.ROLE, contextID), + reader, ALLOW_MODES.DENY_ALL_BUT); + + oSecurity.createUser( + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.USER, contextID), + DatabaseEnvironment.DEFAULT_PASSWORDS.get(SecurityContextMapper.PermissionMode.WRITER) , + writerRole); + oSecurity.createUser( + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.USER, contextID), + DatabaseEnvironment.DEFAULT_PASSWORDS.get(SecurityContextMapper.PermissionMode.READER), + readerRole); + + orientGraph.commit(); + } + + public static void deleteSecurityContext(OrientGraph orientGraph, + String contextID) { + OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() + .getSecurity(); + + oSecurity.dropUser(SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.USER, contextID)); + oSecurity.dropUser(SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.USER, contextID)); + oSecurity.dropRole(SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.ROLE, contextID)); + oSecurity.dropRole(SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.ROLE, contextID)); + + } +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContextMapper.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContextMapper.java new file mode 100644 index 0000000..270576f --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SecurityContextMapper.java @@ -0,0 +1,131 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public abstract class SecurityContextMapper { + + private static Logger logger = LoggerFactory.getLogger(SecurityContextMapper.class); + + public static final String MANAGEMENT_SECURITY_CONTEXT = "ManagementSecurityContext"; + + private static final Map> securityContextFactories; + + static { + try { + boolean created = DatabaseIntializator.initGraphDB(); + + logger.trace("Creating factory for {} connecting as {}", + DatabaseEnvironment.URI_DB, + DatabaseEnvironment.DEFAULT_ADMIN_USERNAME); + + securityContextFactories = new HashMap<>(); + + OrientGraphFactory factory = new OrientGraphFactory( + DatabaseEnvironment.URI_DB, + DatabaseEnvironment.DEFAULT_ADMIN_USERNAME, + DatabaseEnvironment.CHANGED_ADMIN_PASSWORD) + .setupPool(1, 10); + + for(PermissionMode p : PermissionMode.values()){ + Map map = new HashMap<>(); + map.put(null, factory); + securityContextFactories.put(p, map); + map.put(null, factory); + } + + if(created){ + SecurityContext.createSecurityContext(factory.getTx(), MANAGEMENT_SECURITY_CONTEXT); + getSecurityContextFactory(MANAGEMENT_SECURITY_CONTEXT, PermissionMode.READER); + getSecurityContextFactory(MANAGEMENT_SECURITY_CONTEXT, PermissionMode.WRITER); + + DatabaseIntializator.createEntitiesAndRelations(); + } + + } catch (Exception e) { + logger.error("Error initializing database connection", e); + throw new RuntimeException( + "Error initializing database connection", e); + } + } + + public enum SecurityType { + ROLE("Role"), USER("User"); + + private final String name; + + private SecurityType(String name) { + this.name = name; + } + + public String toString() { + return name; + } + } + + public enum PermissionMode { + READER("Reader"), WRITER("Writer"); + + private final String name; + + private PermissionMode(String name) { + this.name = name; + } + + public String toString() { + return name; + } + } + + /** + * @param contextID + * use null for no context (used for admin operations) + * @return + */ + public static OrientGraphFactory getSecurityContextFactory(String contextID, PermissionMode permissionMode) { + OrientGraphFactory factory = null; + + Map permissionSecurityContextFactories = + securityContextFactories.get(permissionMode); + + factory = permissionSecurityContextFactories.get(contextID); + + if (factory == null) { + + String username = getSecurityRoleOrUserName(permissionMode, + SecurityType.USER, contextID); + String password = DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode); + + factory = new OrientGraphFactory(DatabaseEnvironment.URI_DB, + username, password).setupPool(1, 10); + + permissionSecurityContextFactories.put(contextID, factory); + } + + return factory; + } + + public static String getSecurityRoleOrUserName( + PermissionMode permissionMode, SecurityType securityType, + String contextID) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(permissionMode); + stringBuilder.append(securityType); + stringBuilder.append("_"); + stringBuilder.append(contextID); + return stringBuilder.toString(); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/Tree.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/Tree.java new file mode 100644 index 0000000..325ba07 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/Tree.java @@ -0,0 +1,137 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + */ +class Tree { + + private final Node rootElement; + + public void visitNodes(final NodeVisitor visitor) { + doVisit(rootElement, visitor); + } + + private static boolean doVisit(final Node node, + final NodeVisitor visitor) { + boolean result = visitor.visit(node); + if (result) { + for (final Node subNode : node.children) { + if (!doVisit(subNode, visitor)) { + result = false; + break; + } + } + } + return result; + } + + public interface NodeVisitor { + + boolean visit(Node node); + } + + public Node getRootElement() { + return rootElement; + } + + private static final class NodeComparator implements Comparator> { + + private final Comparator wrapped; + + @Override + public int compare(final Node o1, final Node o2) { + return wrapped.compare(o1.value, o2.value); + } + + public NodeComparator(final Comparator wrappedComparator) { + this.wrapped = wrappedComparator; + } + + } + + public static class Node { + + private final SortedSet> children; + + private final Node parent; + + private T value; + + private final Comparator comparator; + + @SuppressWarnings("unchecked") + Node(final T value, final Node parent, final Comparator comparator) { + this.value = value; + this.parent = parent; + this.comparator = comparator; + children = new TreeSet>(new NodeComparator( + (Comparator) comparator)); + } + + public List> getChildren() { + return new ArrayList>(children); + } + + public Node getParent() { + return parent; + } + + public T getValue() { + return value; + } + + public void setValue(final T value) { + this.value = value; + } + + public Node addChild(final T value) { + final Node node = new Node(value, this, comparator); + return children.add(node) ? node : null; + } + + @Override + public String toString(){ + return String.valueOf(value); + } + + } + + @SuppressWarnings("rawtypes") + private static final Comparator NATURAL_ORDER = new Comparator() { + + @SuppressWarnings("unchecked") + @Override + public int compare(final Object o1, final Object o2) { + return ((Comparable) o1).compareTo(o2); + } + }; + + private final Comparator comparator; + + public Tree() { + this(null, null); + } + + public Tree(final Comparator comparator) { + this(comparator, null); + } + + public Tree(final Comparator comparator, final T rootValue) { + this.comparator = comparator == null ? NATURAL_ORDER : comparator; + this.rootElement = new Node(rootValue, null, this.comparator); + } + + public Tree(final T rootValue) { + this(null, rootValue); + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/exceptions/ResourceRegistryExceptionMapper.java b/src/main/java/org/gcube/informationsystem/resourceregistry/exceptions/ResourceRegistryExceptionMapper.java new file mode 100644 index 0000000..b95f40f --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/exceptions/ResourceRegistryExceptionMapper.java @@ -0,0 +1,27 @@ +package org.gcube.informationsystem.resourceregistry.exceptions; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; + +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotAllowedException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ObjectNotFound; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; + +public class ResourceRegistryExceptionMapper implements ExceptionMapper{ + + @Override + public Response toResponse(ResourceRegistryException exception) { + if(ObjectNotFound.class.isAssignableFrom(exception.getClass())){ + return Response.status(Status.NOT_FOUND).entity(exception.getMessage()).build(); + } + + if(NotAllowedException.class.isAssignableFrom(exception.getClass())){ + return Response.status(Status.FORBIDDEN).entity(exception.getMessage()).build(); + } + + return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build(); + + + } +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/Access.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/Access.java new file mode 100644 index 0000000..7254256 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/Access.java @@ -0,0 +1,89 @@ +package org.gcube.informationsystem.resourceregistry.resources; + +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; + +import org.gcube.informationsystem.resourceregistry.AccessRESTPath; +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.api.SchemaManagement; +import org.gcube.informationsystem.resourceregistry.api.Query; +import org.gcube.informationsystem.resourceregistry.api.exceptions.InvalidQueryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.ResourceNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author lucio lelii (lucio.lelii@isti.cnr.it) + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + */ +@Path(AccessRESTPath.ACCESS_PATH_PART) +public class Access { + + private static Logger logger = LoggerFactory.getLogger(Access.class); + + @Inject + Query queryManager; + + @Inject + EntityManagement entityManager; + + @Inject + SchemaManagement entityRegistrationManager; + + @GET + public String query(@QueryParam(AccessRESTPath.QUERY_PARAM) String query, + @QueryParam(AccessRESTPath.FETCH_PLAN_PARAM) String fetchPlan) + throws InvalidQueryException { + logger.trace("Requested query (fetch plan {}):\n{}", fetchPlan, query); + return queryManager.execute(query, fetchPlan); + } + + @GET + @Path(AccessRESTPath.FACET_PATH_PART + "/{" + + AccessRESTPath.FACET_ID_PATH_PARAM + "}") + public String getFacet( + @PathParam(AccessRESTPath.FACET_ID_PATH_PARAM) String facetId) + throws FacetNotFoundException, ResourceRegistryException { + logger.trace("Requested Facet with id {}", facetId); + return entityManager.readFacet(facetId); + } + + @GET + @Path(AccessRESTPath.FACET_PATH_PART + "/" + + AccessRESTPath.SCHEMA_PATH_PART + "/{" + + AccessRESTPath.FACET_TYPE_PATH_PARAM + "}") + public String getFacetSchema( + @PathParam(AccessRESTPath.FACET_TYPE_PATH_PARAM) String facetType) + throws SchemaNotFoundException { + logger.trace("Requested Facet Schema for type {}", facetType); + return entityRegistrationManager.getFacetSchema(facetType); + } + + @GET + @Path(AccessRESTPath.RESOURCE_PATH_PART + "/{" + + AccessRESTPath.RESOURCE_ID_PATH_PARAM + "}") + public String getResource( + @PathParam(AccessRESTPath.RESOURCE_ID_PATH_PARAM) String resourceId) + throws ResourceNotFoundException, ResourceRegistryException { + logger.trace("Requested Resource with id {}", resourceId); + return entityManager.readResource(resourceId); + } + + @GET + @Path(AccessRESTPath.RESOURCE_PATH_PART + "/" + + AccessRESTPath.SCHEMA_PATH_PART + "/{" + + AccessRESTPath.RESOURCE_TYPE_PATH_PARAM + "}") + public String getResourceSchema( + @PathParam(AccessRESTPath.RESOURCE_TYPE_PATH_PARAM) String resourceType) + throws SchemaNotFoundException { + logger.trace("Requested Resource Schema for type {}", resourceType); + return entityRegistrationManager.getResourceSchema(resourceType); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/ContextManager.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/ContextManager.java new file mode 100644 index 0000000..8f1327e --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/ContextManager.java @@ -0,0 +1,71 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources; + +import javax.inject.Inject; +import javax.ws.rs.DELETE; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.gcube.informationsystem.resourceregistry.api.ContextManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * @author lucio lelii (lucio.lelii@isti.cnr.it) + * + */ + + +@Path("context") +public class ContextManager { + /** + * Logger + */ + private static Logger logger = LoggerFactory.getLogger(ContextManager.class); + + public static final String URI = "remote:orientdb0-d-d4s.d4science.org/"; + public static final String DB = "IS"; + public static final String USERNAME = "root"; + public static final String PASSWORD = "D4S*ll2T16"; + + @Inject + ContextManagement contextManager; + + @PUT + @Path("create/{parentContextId}") + public String create(@PathParam("parentContextId") String parentContextId, String jsonRepresentation) throws Exception { + logger.trace("requested create context with json : {} ",jsonRepresentation); + return contextManager.create(parentContextId, jsonRepresentation); + } + + @PUT + @Path("rename/{contextId}") + public String rename(@PathParam("contextId") String uuid, String name) + throws ContextNotFoundException, ContextException{ + logger.trace("requested rename context id {} with {} ", uuid, name); + return contextManager.rename(uuid, name); + } + + @PUT + @Path("move/{contextId}") + public String move(@PathParam("contextId") String uuid, String newParentId) + throws ContextNotFoundException , ContextException{ + logger.trace("requested move context id {} with new parend id {} ", uuid, newParentId); + return contextManager.move(newParentId, uuid); + } + + @DELETE + @Path("delete/{id}") + public String delete(@PathParam("id") String uuid) throws ContextNotFoundException { + logger.trace("requested delete context with id {} ",uuid); + return uuid; + } + + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/EntityManager.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/EntityManager.java new file mode 100644 index 0000000..f6ad0f2 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/EntityManager.java @@ -0,0 +1,137 @@ +package org.gcube.informationsystem.resourceregistry.resources; + +import javax.inject.Inject; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; + +import org.gcube.informationsystem.model.orientdb.impl.relation.ConsistOf; +import org.gcube.informationsystem.model.relation.RelatedTo; +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.ResourceNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author lucio lelii (lucio.lelii@isti.cnr.it) + * + */ + +@Path("entity") +public class EntityManager { + + private static Logger logger = LoggerFactory.getLogger(SchemaManager.class); + + @Inject + EntityManagement entityManager; + + /* Facets Methods */ + + @Path("facet/{facetType}") + @PUT + public String createFacet(@PathParam("facetType") String facetType, + String jsonRepresentation) throws EntityException, + ResourceRegistryException { + logger.trace("requested facet creation for type {} with json {} ", + facetType, jsonRepresentation); + return entityManager.createFacet(facetType, jsonRepresentation); + } + + @Path("facet/{facetId}") + @POST + public String updateFacet(@PathParam("facetId") String facetId, + String jsonRepresentation) throws FacetNotFoundException, + ResourceRegistryException { + logger.trace("requested facet update for id {} with json", facetId, + jsonRepresentation); + return entityManager.updateFacet(facetId, jsonRepresentation); + } + + @Path("facet/{facetId}") + @DELETE + public boolean deleteFacet(@PathParam("facetId") String facetId) + throws FacetNotFoundException, ResourceRegistryException { + logger.trace("requested facet deletion for id {}", facetId); + return entityManager.deleteFacet(facetId); + } + + /* Resources Methods */ + + @Path("resource/{resourceType}") + @PUT + public String createResource( + @PathParam("resourceType") String resourceType, + String jsonRepresentation) throws FacetNotFoundException, + ResourceRegistryException { + logger.trace("requested resource creation for type {} with json {}", + resourceType, jsonRepresentation); + return entityManager.createResource(resourceType, jsonRepresentation); + } + + @Path("resource/{resourceId}") + @DELETE + public boolean deleteResource(@PathParam("resourceId") String resourceId) + throws ResourceNotFoundException, Exception { + logger.trace("requested resource deletion for id {}", resourceId); + return entityManager.deleteResource(resourceId); + } + + /* Relations Methods */ + + @Path("consistOf/source/{resourceId}/target/{facetId}") + @PUT + public String attachFacet(@PathParam("resourceId") String resourceUUID, + @PathParam("facetId") String facetUUID, + @QueryParam("consistOfType") String consistOfType, + @QueryParam("jsonProperties") String jsonProperties) + throws FacetNotFoundException, ResourceNotFoundException, + ResourceRegistryException { + logger.trace( + "requested to attach resource {} to facet {} ({} Type {}) with properties {}", + resourceUUID, facetUUID, ConsistOf.class.getSimpleName(), + consistOfType, jsonProperties); + return entityManager.attachFacet(resourceUUID, facetUUID, + consistOfType, jsonProperties); + } + + @Path("consistOf/{consistOfId}") + @DELETE + public boolean detachFacet(@PathParam("consistOfId") String consistOfUUID) + throws ResourceRegistryException { + logger.trace("requested to detach {}", consistOfUUID); + return entityManager.detachFacet(consistOfUUID); + } + + @Path("relatedTo/source/{sourceResourceId}/target/{targetResourceId}") + @PUT + public String attachResource( + @PathParam("sourceResourceId") String sourceResourceUuid, + @PathParam("targetResourceId") String targetResourceUuid, + @QueryParam("relatedToType") String relatedToType, + @QueryParam("jsonProperties") String jsonProperties) + throws ResourceNotFoundException, ResourceRegistryException { + logger.trace( + "requested to attach source resource {} and target resource {} ({} Type {}) with properties {}", + sourceResourceUuid, targetResourceUuid, + RelatedTo.class.getSimpleName(), relatedToType, jsonProperties); + return entityManager.attachResource(sourceResourceUuid, + targetResourceUuid, relatedToType, jsonProperties); + } + + @Path("relatedTo/{relatedToId}") + @DELETE + public boolean detachResource( + @PathParam("relatedToId") String relatedToUUID) + throws ResourceRegistryException { + logger.trace("requested to detach {}", relatedToUUID); + return entityManager.detachResource(relatedToUUID); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/SchemaManager.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/SchemaManager.java new file mode 100644 index 0000000..4755666 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/SchemaManager.java @@ -0,0 +1,62 @@ +package org.gcube.informationsystem.resourceregistry.resources; + +import javax.inject.Inject; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; + +import org.gcube.informationsystem.resourceregistry.api.SchemaManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * @author lucio lelii (lucio.lelii@isti.cnr.it) + * + */ +@ApplicationPath("schema") +public class SchemaManager { + + + private static Logger logger = LoggerFactory.getLogger(SchemaManager.class); + + @Inject + SchemaManagement schemaManager; + + @Path("embedded") + @PUT + public String registerEmbeddedTypeSchema(String jsonSchema) throws SchemaException { + logger.trace("Requested Embedded registration with schema {} ",jsonSchema); + return schemaManager.registerEmbeddedTypeSchema(jsonSchema); + } + + @Path("facet") + @PUT + public String registerFacetSchema(String jsonSchema) throws SchemaException { + logger.trace("Requested Facet registration with schema {} ",jsonSchema); + return schemaManager.registerFacetSchema(jsonSchema); + } + + @Path("resource") + @PUT + public String registerResourceSchema(String jsonSchema) throws SchemaException { + logger.trace("Requested Resource registration with schema {} ",jsonSchema); + return schemaManager.registerResourceSchema(jsonSchema); + } + + @Path("consistof") + @PUT + public String registerConsistOfSchema(String jsonSchema) throws SchemaException { + logger.trace("Requested ConsistOf registration with schema {} ",jsonSchema); + return schemaManager.registerConsistOfSchema(jsonSchema); + } + + @Path("relatedto") + @PUT + public String registerRelatedToSchema(String jsonSchema) throws SchemaException { + logger.trace("Requested RelatedTo registration with schema {} ",jsonSchema); + return schemaManager.registerRelatedToSchema(jsonSchema); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImpl.java new file mode 100644 index 0000000..1d850e8 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImpl.java @@ -0,0 +1,259 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import java.util.Iterator; +import java.util.UUID; + +import org.codehaus.jettison.json.JSONException; +import org.gcube.informationsystem.model.embedded.Header; +import org.gcube.informationsystem.model.orientdb.impl.entity.Context; +import org.gcube.informationsystem.model.relation.ParentOf; +import org.gcube.informationsystem.resourceregistry.api.ContextManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextCreationException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContext; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.gcube.informationsystem.resourceregistry.resources.utils.HeaderUtility; +import org.gcube.informationsystem.resourceregistry.resources.utils.Utility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.frames.FramedGraph; +import com.tinkerpop.frames.FramedGraphFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + */ +public class ContextManagementImpl implements ContextManagement { + + private static Logger logger = LoggerFactory.getLogger(ContextManagementImpl.class); + + protected Vertex checkContext(OrientGraph orientGraph, + String parentContextUUID, String contextName) + throws ContextNotFoundException, ContextException { + + Vertex parent = null; + + if (parentContextUUID != null) { + + parent = getContext(orientGraph, parentContextUUID); + + // TODO Rewrite using Gremlin + String select = "SELECT FROM (TRAVERSE out(\"ParentOf\") FROM " + + parent.getId() + " MAXDEPTH 1) WHERE " + + Context.NAME_PROPERTY + "=\"" + contextName + "\" AND "+ + Context.HEADER_PROPERTY + "." + Header.UUID_PROPERTY + + "<>\""+ parentContextUUID + "\""; + + logger.trace(select); + + String message = "A context with the same name (" + contextName + + ") has been already created as child of " + + parentContextUUID + "(name=" + + parent.getProperty(Context.NAME_PROPERTY).toString() + ")"; + + logger.trace("Checking if {} -> {}", message, select); + + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery(select); + Iterable vertexes = orientGraph.command(osqlSynchQuery).execute(); + + if(vertexes!=null && vertexes.iterator().hasNext()) { + throw new ContextException(message); + } + + + } else { + // TODO Rewrite using Gremlin + String select = "SELECT FROM " + Context.class.getSimpleName() + " WHERE " + + Context.NAME_PROPERTY + " = \"" + contextName + "\"" + + " AND in(\"" + ParentOf.class.getSimpleName() + "\").size() = 0"; + + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery(select); + Iterable vertexes = orientGraph.command(osqlSynchQuery).execute(); + + if (vertexes != null && vertexes.iterator().hasNext()) { + throw new ContextException("A root context with the same name (" + + contextName + ") already exist"); + } + + } + + return parent; + + } + + public Vertex getContext(OrientGraph orientGraph, String contextUUID) throws ContextNotFoundException { + try { + return Utility.getEntityByUUID(orientGraph, org.gcube.informationsystem.model.entity.Context.NAME, contextUUID); + } catch (ResourceRegistryException e) { + throw new ContextNotFoundException(e.getMessage()); + } + } + + @Override + public String create(String parentContextUUID, String name) + throws ContextCreationException { + + if (parentContextUUID != null && parentContextUUID.compareTo("") == 0) { + parentContextUUID = null; + } + + OrientGraph orientGraph = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.WRITER).getTx(); + + Vertex parent; + try { + parent = checkContext(orientGraph, parentContextUUID, name); + } catch (ContextException e) { + throw new ContextCreationException(e.getMessage()); + } + + try { + UUID uuid = UUID.randomUUID(); + String uuidString = uuid.toString(); + + SecurityContext.createSecurityContext(orientGraph, uuidString); + + FramedGraphFactory framedGraphFactory = new FramedGraphFactory(); + FramedGraph framedGraph = framedGraphFactory.create(orientGraph); + + Context context = framedGraph.addVertex("class:"+Context.class.getSimpleName(), Context.class); + context.setName(name); + + HeaderUtility.addHeader(context, uuid); + + if (parentContextUUID != null) { + orientGraph.addEdge(null, parent, context.asVertex(), ParentOf.class.getSimpleName()); + } + + SecurityContext.addToSecurityContext(orientGraph, context.asVertex(), uuidString); + + logger.trace("Creating {}", Utility.vertexToJsonString(context.asVertex())); + + orientGraph.commit(); + orientGraph.shutdown(); + + return uuidString; + + } catch (Exception e) { + orientGraph.rollback(); + throw new ContextCreationException(e.getMessage()); + } + + } + + @Override + public String read(String contextUUID) + throws ContextNotFoundException, ContextException { + + OrientGraph orientGraph = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.READER).getTx(); + Vertex context = getContext(orientGraph, contextUUID); + try { + return Utility.vertexToJsonString(context, false); + } catch (JSONException e) { + throw new ContextException(e.getCause()); + } + + } + + @Override + public String rename(String contextUUID, String newName) + throws ContextNotFoundException, ContextException { + + OrientGraph orientGraph = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.WRITER).getTx(); + + Vertex context = getContext(orientGraph, contextUUID); + + String parentUUID = null; + + Iterable edges = context.getEdges(Direction.IN, ParentOf.class.getSimpleName()); + if (edges != null && edges.iterator().hasNext()) { + Iterator iteratorEdge = edges.iterator(); + Edge edge = iteratorEdge.next(); + + if(iteratorEdge.hasNext()){ + throw new ContextException(""); + } + + Vertex parent = edge.getVertex(Direction.OUT); + parentUUID = parent.getProperty(Context.HEADER_PROPERTY + "." + Header.UUID_PROPERTY).toString(); + } + + + checkContext(orientGraph, parentUUID, newName); + context.setProperty(Context.NAME_PROPERTY, newName); + + + orientGraph.commit(); + orientGraph.shutdown(); + + return contextUUID; + } + + + @Override + public String move(String newParentUUID, String contextToMoveUUID) + throws ContextNotFoundException, ContextException{ + + OrientGraph orientGraph = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.WRITER).getTx(); + Vertex context = getContext(orientGraph, contextToMoveUUID); + + logger.trace("Context to move {}", Utility.vertexToJsonString(context)); + + checkContext(orientGraph, newParentUUID, context.getProperty(Context.NAME_PROPERTY).toString()); + + // Removing the old parent relationship if any + Iterable edges = context.getEdges(Direction.IN, ParentOf.class.getSimpleName()); + if (edges != null && edges.iterator().hasNext()) { + Iterator edgeIterator = edges.iterator(); + Edge edge = edgeIterator.next(); + logger.trace("Removing {} {}", Edge.class.getSimpleName(), edge); + edge.remove(); + } + + if(newParentUUID!=null){ + Vertex parent = getContext(orientGraph, newParentUUID); + logger.trace("New Parent Context {}", Utility.vertexToJsonString(parent)); + orientGraph.addEdge(null, parent, context, ParentOf.class.getSimpleName()); + } + + orientGraph.commit(); + orientGraph.shutdown(); + + return contextToMoveUUID; + } + + @Override + public String delete(String uuid) throws ContextNotFoundException, ContextException { + + OrientGraph orientGraph = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.WRITER).getTx(); + Vertex context = getContext(orientGraph, uuid); + logger.trace("Context to be delete {}", Utility.vertexToJsonString(context)); + + Iterable edges = context.getEdges(Direction.OUT, ParentOf.class.getSimpleName()); + if (edges != null && edges.iterator().hasNext()) { + throw new ContextException("Only context with no children can be deleted"); + } + + SecurityContext.deleteSecurityContext(orientGraph, uuid); + + context.remove(); + + orientGraph.commit(); + orientGraph.shutdown(); + + return uuid; + } + + + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImpl.java new file mode 100644 index 0000000..04f38cf --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImpl.java @@ -0,0 +1,527 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.model.entity.Resource; +import org.gcube.informationsystem.model.relation.RelatedTo; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.model.relation.ConsistOf; +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.ResourceNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.gcube.informationsystem.resourceregistry.resources.utils.ContextUtility; +import org.gcube.informationsystem.resourceregistry.resources.utils.HeaderUtility; +import org.gcube.informationsystem.resourceregistry.resources.utils.Utility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.orient.OrientEdge; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientVertex; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class EntityManagementImpl implements EntityManagement { + + private static Logger logger = LoggerFactory + .getLogger(EntityManagementImpl.class); + + public Vertex getEntity(OrientGraph orientGraph, String uuid, + String entityType, Class entityClass) + throws FacetNotFoundException, ResourceNotFoundException, + ResourceRegistryException { + try { + if (entityType == null || entityType.compareTo("") == 0) { + if (Facet.class.isAssignableFrom(entityClass)) { + entityType = Facet.NAME; + } + if (Resource.class.isAssignableFrom(entityClass)) { + entityType = Resource.NAME; + } + } + return Utility.getEntityByUUID(orientGraph, entityType, uuid); + } catch (ResourceRegistryException e) { + if (Facet.class.isAssignableFrom(entityClass)) { + throw new FacetNotFoundException(e.getMessage()); + } + if (Resource.class.isAssignableFrom(entityClass)) { + throw new ResourceNotFoundException(e.getMessage()); + } + throw e; + } + + } + + public Edge getRelation( + OrientGraph orientGraph, + String uuid, + String relationType, + @SuppressWarnings("rawtypes") Class relationClass) + throws ResourceRegistryException { + try { + if (relationType == null || relationType.compareTo("") == 0) { + if (RelatedTo.class.isAssignableFrom(relationClass)) { + relationType = RelatedTo.NAME; + } + if (ConsistOf.class.isAssignableFrom(relationClass)) { + relationType = ConsistOf.NAME; + } + } + return Utility.getRelationByUUID(orientGraph, relationType, uuid); + } catch (ResourceRegistryException e) { + throw e; + } catch (Exception e) { + throw new ResourceRegistryException(e); + } + + } + + public String createVertexEntity(String entityType, + Class entity, String jsonRepresentation) + throws ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + SchemaManagementImpl schemaManagement = new SchemaManagementImpl(); + try { + schemaManagement.getTypeSchema(entityType, + entity.getSimpleName()); + } catch (SchemaNotFoundException e) { + throw e; + } + + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(jsonRepresentation); + + OrientVertex entityVertex = orientGraph.addVertex("class:" + + entityType); + + if (Resource.class.isAssignableFrom(entity)) { + // TODO + } else { + Iterator> iterator = jsonNode.fields(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + JsonNode value = entry.getValue(); + entityVertex.setProperty(entry.getKey(), value.asText()); + } + } + + HeaderUtility.addHeader(entityVertex, null); + ContextUtility.addToActualContext(orientGraph, entityVertex); + + entityVertex.save(); + orientGraph.commit(); + + return Utility + .orientVertexToJsonString((OrientVertex) entityVertex); + + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceRegistryException("Error Creating " + entityType + + " with " + jsonRepresentation, e.getCause()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + public String createEdgeRelation(String sourceUUID, + Class sourceClass, String targetUUID, + Class targetClass, String relationType, + String jsonProperties) throws FacetNotFoundException, + ResourceNotFoundException, ResourceRegistryException { + OrientGraph orientGraph = null; + + if (relationType == null || relationType.compareTo("") == 0) { + throw new ResourceRegistryException(Relation.class.getSimpleName() + + "type cannot be empty or null"); + } + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + SchemaManagementImpl schemaManagement = new SchemaManagementImpl(); + try { + schemaManagement.getTypeSchema(relationType, Relation.NAME); + } catch (SchemaNotFoundException e) { + throw e; + } + + Vertex source = getEntity(orientGraph, sourceUUID, null, + sourceClass); + Vertex target = getEntity(orientGraph, targetUUID, null, + targetClass); + + // TODO Check if in and out types are compatible with the relation + // type as defined in relation type + + logger.trace("Creating {} ({}) beetween {} -> {}", + Relation.class.getSimpleName(), relationType, + Utility.vertexToJsonString(source), + Utility.vertexToJsonString(target)); + + Edge edge = orientGraph.addEdge(null, source, target, relationType); + + if (jsonProperties != null && jsonProperties.compareTo("") != 0) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(jsonProperties); + + Iterator> iterator = jsonNode + .fields(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + try { + JsonNode value = entry.getValue(); + edge.setProperty(entry.getKey(), value.asText()); + } catch (Exception e) { + throw new ResourceRegistryException( + "Error while setting property" + + String.valueOf(entry), e); + } + } + } catch (Exception e) { + new ResourceRegistryException( + "Error while setting Relation Properties", e); + } + } + + HeaderUtility.addHeader(edge, null); + ContextUtility.addToActualContext(orientGraph, edge); + + ((OrientEdge) edge).save(); + orientGraph.commit(); + + return Utility.orientEdgeToJsonString((OrientEdge) edge); + } catch (ResourceNotFoundException rnfe) { + throw rnfe; + } catch (Exception e) { + throw new ResourceNotFoundException(e.getMessage()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + @Override + public String createFacet(String facetType, String jsonRepresentation) + throws ResourceRegistryException { + return createVertexEntity(facetType, Facet.class, jsonRepresentation); + } + + @Override + public String readFacet(String uuid) throws FacetNotFoundException, + ResourceRegistryException { + return readFacet(uuid, Facet.NAME); + } + + @Override + public String readFacet(String uuid, String facetType) + throws FacetNotFoundException, ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.READER); + + Vertex facet = getEntity(orientGraph, uuid, facetType, Facet.class); + + return Utility.orientVertexToJsonString((OrientVertex) facet); + } catch (FacetNotFoundException fnfe) { + throw fnfe; + } catch (Exception e) { + throw new ResourceRegistryException(e.getMessage()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + @Override + public String updateFacet(String uuid, String jsonRepresentation) + throws ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(jsonRepresentation); + + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + // TODO get facetType from json + Vertex facet = getEntity(orientGraph, uuid, Facet.NAME, Facet.class); + + Set oldKeys = facet.getPropertyKeys(); + + Iterator> iterator = jsonNode.fields(); + while (iterator.hasNext()) { + + Entry entry = iterator.next(); + String key = entry.getKey(); + + if (key.startsWith("_")) { + oldKeys.remove(key); + continue; + } + + if (key.compareTo(Facet.HEADER_PROPERTY) == 0) { + oldKeys.remove(key); + continue; + } + + JsonNode value = entry.getValue(); + facet.setProperty(key, value.asText()); + + oldKeys.remove(key); + + } + + for (String key : oldKeys) { + if (key.startsWith("_")) { + continue; + } + facet.removeProperty(key); + } + + ((OrientVertex) facet).save(); + orientGraph.commit(); + + return Utility.orientVertexToJsonString((OrientVertex) facet); + + } catch (FacetNotFoundException fnfe) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw fnfe; + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceRegistryException("Error Updating Facet", + e.getCause()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + @Override + public boolean deleteFacet(String uuid) throws FacetNotFoundException, + ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + Vertex facet = getEntity(orientGraph, uuid, Facet.NAME, Facet.class); + + facet.remove(); + orientGraph.commit(); + } catch (FacetNotFoundException fnfe) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw fnfe; + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceRegistryException(e); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + + return true; + } + + @Override + public String attachFacet(String resourceUUID, String facetUUID, + String consistOfType, String jsonProperties) + throws FacetNotFoundException, ResourceNotFoundException, + ResourceRegistryException { + return createEdgeRelation(resourceUUID, Resource.class, facetUUID, + Facet.class, consistOfType, jsonProperties); + } + + @Override + public boolean detachFacet(String consistOfUUID) + throws ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + Edge edge = getRelation(orientGraph, consistOfUUID, ConsistOf.NAME, + ConsistOf.class); + + edge.remove(); + orientGraph.commit(); + } catch (FacetNotFoundException fnfe) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw fnfe; + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceRegistryException(e); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + + return true; + + } + + @Override + public String attachResource(String sourceResourceUuid, + String targetResourceUuid, String relatedToType, + String jsonProperties) throws ResourceNotFoundException, + ResourceRegistryException { + return createEdgeRelation(sourceResourceUuid, Resource.class, + targetResourceUuid, Resource.class, relatedToType, + jsonProperties); + } + + @Override + public boolean detachResource(String relatedToUUID) + throws ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + Edge edge = getRelation(orientGraph, relatedToUUID, RelatedTo.NAME, + RelatedTo.class); + + edge.remove(); + orientGraph.commit(); + } catch (FacetNotFoundException fnfe) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw fnfe; + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceRegistryException(e); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + + return true; + } + + @Override + public String createResource(String resourceType, String jsonRepresentation) + throws ResourceRegistryException { + return createVertexEntity(resourceType, Resource.class, + jsonRepresentation); + } + + @Override + public String readResource(String uuid) throws ResourceNotFoundException { + return readResource(uuid, Resource.NAME); + } + + @Override + public String readResource(String uuid, String resourceType) + throws ResourceNotFoundException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.READER); + + Vertex resource = getEntity(orientGraph, uuid, resourceType, + Resource.class); + + // TODO get all attached facets + + return Utility.orientVertexToJsonString((OrientVertex) resource); + } catch (ResourceNotFoundException rnfe) { + throw rnfe; + } catch (Exception e) { + throw new ResourceNotFoundException(e.getMessage()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + @Override + public boolean deleteResource(String uuid) + throws ResourceNotFoundException, ResourceRegistryException { + OrientGraph orientGraph = null; + + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.WRITER); + + Vertex resource = getEntity(orientGraph, uuid, null, Resource.class); + + // TODO remove attached facets if not managed from hooks + resource.remove(); + + orientGraph.commit(); + } catch (ResourceNotFoundException fnfe) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw fnfe; + } catch (Exception e) { + if (orientGraph != null) { + orientGraph.rollback(); + } + throw new ResourceNotFoundException(e.getMessage()); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + + return true; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImpl.java new file mode 100644 index 0000000..864d628 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImpl.java @@ -0,0 +1,117 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +import org.gcube.informationsystem.resourceregistry.api.Query; +import org.gcube.informationsystem.resourceregistry.api.exceptions.InvalidQueryException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper; +import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.gcube.informationsystem.resourceregistry.resources.utils.ContextUtility; +import org.glassfish.jersey.internal.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.research.ws.wadl.HTTPMethods; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class QueryImpl implements Query { + + private static Logger logger = LoggerFactory.getLogger(QueryImpl.class); + + private static final String QUERY = "query/"; + private static final String SQL = "sql/"; + private static final String DEFAULT_LIMIT = "20/"; + + private static final URL BASE_QUERY_URL; + + static { + try { + URL url = new URL(DatabaseEnvironment.HTTP_URL_STRING); + URL urlQuery = new URL(url, QUERY); + URL urlDB = new URL(urlQuery, DatabaseEnvironment.DB + "/"); + BASE_QUERY_URL = new URL(urlDB, SQL); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private void checkStatus(HttpURLConnection connection) throws Exception { + int statusCode = connection.getResponseCode(); + switch (statusCode) { + case 200: + case 201: + return; + default: + throw new Exception(connection.getResponseMessage()); + } + } + + @Override + public String execute(String query, String fetchPlan) + throws InvalidQueryException { + + + String readerUsername = ContextUtility.getActualSecurityRoleOrUserName(SecurityContextMapper.PermissionMode.READER, SecurityContextMapper.SecurityType.USER); + + + try { + URL queryURL = new URL(BASE_QUERY_URL, URLEncoder.encode(query, + "UTF-8") + "/"); + + /* + if (limit != null && limit > 0) { + queryURL = new URL(queryURL, limit.toString() + "/"); + } else { + queryURL = new URL(queryURL, DEFAULT_LIMIT); + } + */ + queryURL = new URL(queryURL, DEFAULT_LIMIT); + + + if (fetchPlan != null && fetchPlan.compareTo("") != 0) { + queryURL = new URL(queryURL, fetchPlan + "/"); + } + + logger.debug("Connecting to {}", queryURL.toString()); + HttpURLConnection connection = (HttpURLConnection) queryURL + .openConnection(); + + String password = DatabaseEnvironment.DEFAULT_PASSWORDS.get(PermissionMode.READER); + String authString = String.format("%s:%s", readerUsername, password); + + byte[] authEncBytes = Base64.encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + connection.setRequestProperty("Authorization", "Basic " + + authStringEnc); + connection.setRequestMethod(HTTPMethods.GET.toString()); + connection.connect(); + + checkStatus(connection); + + InputStream inputStream = connection.getInputStream(); + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + return result.toString("UTF-8"); + + } catch (Exception e) { + throw new InvalidQueryException(e.getMessage(), e); + } + + } +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/SchemaManagementImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/SchemaManagementImpl.java new file mode 100644 index 0000000..8f0a432 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/impl/SchemaManagementImpl.java @@ -0,0 +1,599 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.model.entity.Resource; +import org.gcube.informationsystem.model.relation.ConsistOf; +import org.gcube.informationsystem.model.relation.RelatedTo; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.resourceregistry.api.SchemaManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.gcube.informationsystem.types.TypeBinder.Property; +import org.gcube.informationsystem.types.TypeBinder.TypeDefinition; +import org.jboss.weld.exceptions.UnsupportedOperationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; +import com.orientechnologies.orient.core.metadata.OMetadata; +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OClassImpl; +import com.orientechnologies.orient.core.metadata.schema.OProperty; +import com.orientechnologies.orient.core.metadata.schema.OSchema; +import com.orientechnologies.orient.core.metadata.schema.OType; +import com.orientechnologies.orient.core.record.impl.ODocument; +import com.tinkerpop.blueprints.impls.orient.OrientEdgeType; +import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; +import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx; +import com.tinkerpop.blueprints.impls.orient.OrientVertexType; +import com.tinkerpop.blueprints.impls.orient.OrientVertexType.OrientVertexProperty; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + * TODO Create an instance for each Registered Type in a management + * SecurityContext so that that management context can be used to see + * Entity and Relations as graph. + */ +public class SchemaManagementImpl implements SchemaManagement { + + private static Logger logger = LoggerFactory + .getLogger(SchemaManagementImpl.class); + + protected static OClass getEntityOClass(OrientGraphNoTx orientGraphNoTx, String entityType) throws SchemaException { + OMetadata oMetadata = orientGraphNoTx.getRawGraph().getMetadata(); + OSchema oSchema = oMetadata.getSchema(); + return oSchema.getClass(entityType); + + } + + protected OClass getTypeSchema(String type, String baseType) + throws SchemaNotFoundException { + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.READER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + logger.debug("Getting {} Type {} schema", + baseType != null ? baseType : "", type); + + orientGraphNoTx = orientGraphFactory.getNoTx(); + + OClass oClass = getEntityOClass(orientGraphNoTx, type); + + if (baseType != null) { + if (!oClass.isSubClassOf(baseType)) { + throw new SchemaException("The requested type is not a " + + baseType); + } + } + return oClass; + + } catch (SchemaNotFoundException snfe) { + throw snfe; + } catch (Exception e) { + throw new SchemaNotFoundException(e.getMessage()); + } + } + + protected static String serializeOClass(OClass oClass) { + ODocument oDocument = ((OClassImpl) oClass).toStream(); + String json = oDocument.toJSON(); + logger.trace("Requested type serialization is {}", json); + return json; + } + + protected List getSuperclassesAndCheckCompliancy( + OrientGraphNoTx orientGraphNoTx, TypeDefinition typeDefinition, + String baseType) throws SchemaException { + + Set superClasses = typeDefinition.getSuperclasses(); + if (baseType !=null){ + if(superClasses == null || superClasses.size() == 0){ + throw new RuntimeException( + String.format( + "No Superclass found in schema %s. The Type Definition must extend %s", + typeDefinition, baseType)); + } + } + + List oSuperclasses = new ArrayList<>(); + for (String superClass : superClasses) { + OClass oSuperClass = getEntityOClass(orientGraphNoTx, superClass); + if (baseType != null) { + if (typeDefinition.getName().compareTo(baseType) != 0) { + if (!oSuperClass.isSubClassOf(baseType)) { + throw new RuntimeException(superClass + + " is not a subsclass of " + baseType + + ". Each Superclass MUST be a subclass of " + + baseType); + } + } + } + oSuperclasses.add(oSuperClass); + } + + return oSuperclasses; + } + + protected String getTypeSchemaAsString(String type, String baseType) + throws SchemaNotFoundException { + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.READER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + orientGraphNoTx = orientGraphFactory.getNoTx(); + OClass oClass = getTypeSchema(type, baseType); + return serializeOClass(oClass); + } catch (Exception e) { + throw new SchemaNotFoundException(e); + } finally { + if (orientGraphNoTx != null) { + orientGraphNoTx.shutdown(); + } + } + } + + protected String registerVertexTypeSchema(String jsonSchema, + Class baseType) throws SchemaException { + + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.WRITER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + logger.trace("Trying to register {} {}", baseType, jsonSchema); + + ObjectMapper mapper = new ObjectMapper(); + TypeDefinition typeDefinition = mapper.readValue(jsonSchema, + TypeDefinition.class); + + orientGraphNoTx = orientGraphFactory.getNoTx(); + + OrientVertexType ovt = orientGraphNoTx + .createVertexType(typeDefinition.getName()); + ovt.setDescription(typeDefinition.getDescription()); + ovt.setAbstract(typeDefinition.isAbstractType()); + + List oSuperclasses = getSuperclassesAndCheckCompliancy( + orientGraphNoTx, typeDefinition, baseType.getSimpleName()); + + ovt.setSuperClasses(oSuperclasses); + + if (Resource.class.isAssignableFrom(baseType)) { + Set properties = typeDefinition.getProperties(); + if (properties != null && properties.size() > 0) { + throw new Exception( + "A Resource cannot contains any properties."); + } + } else { + for (Property property : typeDefinition.getProperties()) { + OrientVertexProperty ovp = ovt.createProperty( + property.getName(), + OType.getById(property.getType().byteValue())); + ovp.setDescription(property.getDescription()); + ovp.setMandatory(property.isMandatory()); + ovp.setNotNull(property.isNotnull()); + ovp.setReadonly(property.isReadonly()); + ovp.setRegexp(property.getRegexpr()); + if (property.getLinkedClass() != null) { + OClass linkedClass = getEntityOClass(orientGraphNoTx, property.getLinkedClass()); + if (linkedClass == null) { + logger.trace("class {} not found in schema", + property.getLinkedClass()); + throw new Exception("class " + + property.getLinkedClass() + + " not found in schema"); + } + + if (linkedClass.isEdgeType() + || linkedClass.isVertexType()) { + throw new Exception( + "An Embedded Field cannot be an Entity or a Relation"); + } + + ovp.setLinkedClass(linkedClass); + } else if (property.getLinkedType() != null) { + ovp.setLinkedType(OType.getById(property + .getLinkedType().byteValue())); + } + } + } + + orientGraphNoTx.commit(); + + OClass oClass = getTypeSchema(typeDefinition.getName(), null); + return serializeOClass(oClass); + + } catch (Exception e) { + throw new SchemaException(e); + } finally { + if (orientGraphNoTx != null) { + orientGraphNoTx.shutdown(); + } + } + } + + protected String registerEdgeTypeSchema(String jsonSchema, String baseType) + throws SchemaException { + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.WRITER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + logger.trace("Trying to register {} {}", baseType, jsonSchema); + + ObjectMapper mapper = new ObjectMapper(); + TypeDefinition typeDefinition = mapper.readValue(jsonSchema, + TypeDefinition.class); + + orientGraphNoTx = orientGraphFactory.getNoTx(); + + OrientEdgeType oet = orientGraphNoTx.createEdgeType(typeDefinition + .getName()); + oet.setDescription(typeDefinition.getDescription()); + oet.setAbstract(typeDefinition.isAbstractType()); + + List oSuperclasses = getSuperclassesAndCheckCompliancy( + orientGraphNoTx, typeDefinition, baseType); + oet.setSuperClasses(oSuperclasses); + + for (Property property : typeDefinition.getProperties()) { + OProperty op = oet.createProperty(property.getName(), + OType.getById(property.getType().byteValue())); + op.setDescription(property.getDescription()); + op.setMandatory(property.isMandatory()); + op.setNotNull(property.isNotnull()); + op.setReadonly(property.isReadonly()); + op.setRegexp(property.getRegexpr()); + if (property.getLinkedClass() != null) { + OClass linkedClass = getEntityOClass(orientGraphNoTx, + property.getLinkedClass()); + if (linkedClass == null) { + logger.trace("class {} not found in schema", + property.getLinkedClass()); + throw new Exception("class " + + property.getLinkedClass() + + " not found in schema"); + } + + if (linkedClass.isEdgeType() || linkedClass.isVertexType()) { + throw new Exception( + "An Embedded Field cannot be an Entity or a Relation"); + } + + op.setLinkedClass(linkedClass); + } + } + + orientGraphNoTx.commit(); + + OClass oClass = getTypeSchema(typeDefinition.getName(), null); + return serializeOClass(oClass); + } catch (Exception e) { + throw new SchemaException(e); + } finally { + if (orientGraphNoTx != null) { + orientGraphNoTx.shutdown(); + } + } + } + + public String registerDocumentSchema(String jsonSchema) + throws SchemaException { + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.WRITER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + logger.trace("Trying to register {}", jsonSchema); + + ObjectMapper mapper = new ObjectMapper(); + TypeDefinition typeDefinition = mapper.readValue(jsonSchema, + TypeDefinition.class); + + orientGraphNoTx = orientGraphFactory.getNoTx(); + + ODatabaseDocumentTx oDatabaseDocumentTx = orientGraphNoTx.getRawGraph(); + OMetadata oMetadata = oDatabaseDocumentTx.getMetadata(); + OSchema oSchema = oMetadata.getSchema(); + + OClass oClass = oSchema.createClass(typeDefinition.getName()); + oClass.setDescription(typeDefinition.getDescription()); + oClass.setAbstract(typeDefinition.isAbstractType()); + + List oSuperclasses = getSuperclassesAndCheckCompliancy( + orientGraphNoTx, typeDefinition, null); + oClass.setSuperClasses(oSuperclasses); + + oDatabaseDocumentTx.commit(); + + + for (Property property : typeDefinition.getProperties()) { + OProperty ovp = oClass.createProperty(property.getName(), + OType.getById(property.getType().byteValue())); + ovp.setDescription(property.getDescription()); + ovp.setMandatory(property.isMandatory()); + ovp.setNotNull(property.isNotnull()); + ovp.setReadonly(property.isReadonly()); + ovp.setRegexp(property.getRegexpr()); + if (property.getLinkedClass() != null) { + OClass linkedClass = getEntityOClass(orientGraphNoTx, + property.getLinkedClass()); + if (linkedClass == null) { + logger.trace("class {} not found in schema", + property.getLinkedClass()); + throw new Exception("class " + + property.getLinkedClass() + + " not found in schema"); + } + + if (linkedClass.isEdgeType() || linkedClass.isVertexType()) { + throw new Exception( + "An Embedded Field cannot be an Entity or a Relation"); + } + + ovp.setLinkedClass(linkedClass); + } + } + + orientGraphNoTx.commit(); + + return serializeOClass(oClass); + + } catch (Exception e) { + throw new SchemaException(e); + } finally { + if (orientGraphNoTx != null) { + orientGraphNoTx.shutdown(); + } + } + } + + /* + public void addDocumentProperties(TypeDefinition typeDefinition) throws SchemaException { + OrientGraphFactory orientGraphFactory = SecurityContextMapper + .getSecurityContextFactory(null, PermissionMode.WRITER); + + OrientGraphNoTx orientGraphNoTx = null; + try { + logger.trace("Adding properties to {}", typeDefinition); + + OClass oClass = getEntityOClass(orientGraphNoTx, typeDefinition.getName()); + + orientGraphNoTx = orientGraphFactory.getNoTx(); + + for (Property property : typeDefinition.getProperties()) { + OProperty ovp = oClass.createProperty(property.getName(), + OType.getById(property.getType().byteValue())); + ovp.setDescription(property.getDescription()); + ovp.setMandatory(property.isMandatory()); + ovp.setNotNull(property.isNotnull()); + ovp.setReadonly(property.isReadonly()); + ovp.setRegexp(property.getRegexpr()); + if (property.getLinkedClass() != null) { + OClass linkedClass = getEntityOClass(orientGraphNoTx, + property.getLinkedClass()); + if (linkedClass == null) { + logger.trace("class {} not found in schema", + property.getLinkedClass()); + throw new Exception("class " + + property.getLinkedClass() + + " not found in schema"); + } + + if (linkedClass.isEdgeType() || linkedClass.isVertexType()) { + throw new Exception( + "An Embedded Field cannot be an Entity or a Relation"); + } + + ovp.setLinkedClass(linkedClass); + } + } + } catch (Exception e) { + throw new SchemaException(e); + } finally { + if (orientGraphNoTx != null) { + orientGraphNoTx.shutdown(); + } + } + } + */ + + @Override + public String registerEntitySchema(String jsonSchema) + throws SchemaException { + return registerVertexTypeSchema(jsonSchema, Entity.class); + } + + @Override + public String getEntitySchema(String entityType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(entityType, Entity.NAME); + } + + @Override + public String updateEntitySchema(String entityType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteEntitySchema(String entityType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerFacetSchema(String jsonSchema) throws SchemaException { + return registerVertexTypeSchema(jsonSchema, Facet.class); + } + + @Override + public String getFacetSchema(String facetType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(facetType, Facet.NAME); + } + + @Override + public String updateFacetSchema(String facetType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteFacetSchema(String facetType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerResourceSchema(String jsonSchema) + throws SchemaException { + return registerVertexTypeSchema(jsonSchema, Resource.class); + } + + @Override + public String getResourceSchema(String resourceType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(resourceType, Resource.NAME); + } + + @Override + public String updateResourceSchema(String resourceType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteResourceSchema(String resourceType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerEmbeddedTypeSchema(String jsonSchema) + throws SchemaException { + + return registerDocumentSchema(jsonSchema); + /* + ObjectMapper mapper = new ObjectMapper(); + TypeDefinition typeDefinition; + try { + typeDefinition = mapper.readValue(jsonSchema, + TypeDefinition.class); + registerDocumentSchema(typeDefinition); + addDocumentProperties(typeDefinition); + + return jsonSchema; + } catch (SchemaException e) { + throw e; + } catch (Exception e) { + throw new SchemaException(e); + } + */ + } + + @Override + public String getEmbeddedTypeSchema(String embeddedType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(embeddedType, null); + } + + @Override + public String updateEmbeddedTypeSchema(String embeddedType, + String jsonSchema) throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteEmbeddedTypeSchema(String embeddedType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerRelationSchema(String jsonSchema) + throws SchemaException { + return registerEdgeTypeSchema(jsonSchema, Relation.NAME); + } + + @Override + public String getRelationSchema(String relationType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(relationType, Relation.NAME); + } + + @Override + public String updateRelationSchema(String relationType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteRelationSchema(String relationType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerConsistOfSchema(String jsonSchema) + throws SchemaException { + return registerEdgeTypeSchema(jsonSchema, ConsistOf.NAME); + } + + @Override + public String getConsistOfSchema(String consistOfType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(consistOfType, ConsistOf.NAME); + } + + @Override + public String updateConsistOfSchema(String consistOfType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteConsistOfSchema(String consistOfType) + throws SchemaNotFoundException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String registerRelatedToSchema(String jsonSchema) + throws SchemaException { + return registerEdgeTypeSchema(jsonSchema, RelatedTo.NAME); + } + + @Override + public String getRelatedToSchema(String relatedToType) + throws SchemaNotFoundException { + return getTypeSchemaAsString(relatedToType, RelatedTo.NAME); + } + + @Override + public String updateRelatedToSchema(String relatedToType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + + @Override + public String deleteRelatedToSchema(String relatedToType) + throws SchemaException { + throw new UnsupportedOperationException("Not Yet implemented"); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java new file mode 100644 index 0000000..ebf9c4b --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java @@ -0,0 +1,139 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.utils; + +import java.util.Iterator; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.informationsystem.model.orientdb.impl.embedded.Header; +import org.gcube.informationsystem.model.orientdb.impl.entity.Context; +import org.gcube.informationsystem.model.orientdb.impl.entity.Entity; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContext; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper; +import org.gcube.informationsystem.resourceregistry.dbinitialization.SecurityContextMapper.PermissionMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.orientechnologies.orient.core.metadata.security.OSecurity; +import com.orientechnologies.orient.core.record.impl.ODocument; +import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class ContextUtility { + + private static final Logger logger = LoggerFactory.getLogger(ContextUtility.class); + + public static void addToActualContext(OrientGraph orientGraph, Vertex vertex) + throws ContextException { + String contextID = ContextUtility.getActualContextUUID(); + SecurityContext.addToSecurityContext(orientGraph, vertex, contextID); + } + + public static void addToActualContext(OSecurity oSecurity, Vertex vertex) + throws ContextException { + String contextID = ContextUtility.getActualContextUUID(); + SecurityContext.addToSecurityContext(oSecurity, vertex, contextID); + } + + public static void addToActualContext(OrientGraph orientGraph, Edge edge) + throws ContextException { + String contextID = ContextUtility.getActualContextUUID(); + SecurityContext.addToSecurityContext(orientGraph, edge, contextID); + } + + public static void addToActualContext(OSecurity oSecurity, Edge edge) + throws ContextException { + String contextID = ContextUtility.getActualContextUUID(); + SecurityContext.addToSecurityContext(oSecurity, edge, contextID); + } + + protected static String getContextUUIDFromContextVertex(Vertex vertex) { + ODocument header = vertex.getProperty(Entity.HEADER_PROPERTY); + String contextID = header.field(Header.UUID_PROPERTY); + return contextID; + } + + public static String getActualContextUUID() throws ContextException { + try { + String scope = ScopeProvider.instance.get(); + OrientGraphFactory factory = SecurityContextMapper.getSecurityContextFactory(null, PermissionMode.READER); + Vertex context = ContextUtility.getContextVertexByFullName( + factory.getTx(), scope); + return getContextUUIDFromContextVertex(context); + } catch (Exception e) { + throw new ContextException( + "Unable to restrive Context UUID from current Context"); + } + } + + public static OrientGraph getActualSecurityContextGraph( + PermissionMode permissionMode) throws Exception { + try { + String contextID = getActualContextUUID(); + OrientGraphFactory factory = SecurityContextMapper + .getSecurityContextFactory(contextID, permissionMode); + return factory.getTx(); + } catch (Exception e) { + logger.error("Unable to retrieve context.", e); + throw e; + } + } + + public static Vertex getContextVertexByFullName(OrientGraph orientGraph, + String fullName) throws ContextNotFoundException { + + ScopeBean scopeBean = new ScopeBean(fullName); + String name = scopeBean.name(); + + // TODO Rewrite the previous query using Gremlin + // Please note that this query works because all the scope parts has a + // different name + String select = "SELECT FROM " + Context.class.getSimpleName() + + " WHERE " + Context.NAME_PROPERTY + " = \"" + name + "\""; + ; + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery( + select); + Iterable vertexes = orientGraph.command(osqlSynchQuery) + .execute(); + + if (vertexes == null || !vertexes.iterator().hasNext()) { + throw new ContextNotFoundException( + "Error retrieving context with name " + fullName); + } + + Iterator iterator = vertexes.iterator(); + Vertex context = iterator.next(); + + logger.trace("Context Representing Vertex : {}", + Utility.vertexToJsonString(context)); + + if (iterator.hasNext()) { + throw new ContextNotFoundException( + "Found more than one context with name " + name + + "but required the one with path" + fullName + + ". Please Reimplement the query"); + } + + return context; + } + + public static String getActualSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode permissionMode, + SecurityContextMapper.SecurityType securityType) { + String scope = ScopeProvider.instance.get(); + return SecurityContextMapper.getSecurityRoleOrUserName(permissionMode, + securityType, scope); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/HeaderUtility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/HeaderUtility.java new file mode 100644 index 0000000..aa39823 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/HeaderUtility.java @@ -0,0 +1,84 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.utils; + +import java.util.UUID; + +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.UserInfo; +import org.gcube.informationsystem.model.orientdb.impl.embedded.Header; +import org.gcube.informationsystem.model.orientdb.impl.entity.Entity; +import org.gcube.informationsystem.model.orientdb.impl.relation.Relation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class HeaderUtility { + + private static final Logger logger = LoggerFactory + .getLogger(HeaderUtility.class); + + public static Header createHeader(UUID uuid) { + Header header = new Header(); + + if (uuid == null) { + uuid = UUID.randomUUID(); + } + + header.setUUID(uuid); + + String creator = org.gcube.informationsystem.model.embedded.Header.UNKNOWN_USER; + try { + UserInfo userInfo = AuthorizationProvider.instance.get(); + String username = userInfo.getUserName(); + if (username != null && username.compareTo("") != 0) { + creator = username; + } else { + throw new Exception("Username null or empty"); + } + } catch (Exception e) { + logger.error("Unable to retrieve user"); + } + header.setCreator(creator); + + long timestamp = System.currentTimeMillis(); + header.setCreationTime(timestamp); + header.setLastUpdateTime(timestamp); + + return header; + } + + + public static Header addHeader(Vertex vertex, UUID uuid) { + Header header = createHeader(uuid); + vertex.setProperty(Entity.HEADER_PROPERTY, header); + return header; + } + + public static Header addHeader(Entity entity, UUID uuid) { + Header header = createHeader(uuid); + entity.setHeader(header); + return header; + } + + + public static Header addHeader(Edge edge, UUID uuid) { + Header header = createHeader(uuid); + edge.setProperty(Entity.HEADER_PROPERTY, header); + return header; + } + + public static Header addHeader(@SuppressWarnings("rawtypes") Relation relation, UUID uuid) { + Header header = createHeader(uuid); + relation.setHeader(header); + return header; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/Utility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/Utility.java new file mode 100644 index 0000000..09042da --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/Utility.java @@ -0,0 +1,173 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.utils; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.codehaus.jettison.json.JSONException; +import org.gcube.informationsystem.model.embedded.Header; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.orientechnologies.orient.core.record.ORecord; +import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.orient.OrientEdge; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientVertex; +import com.tinkerpop.blueprints.util.io.graphson.GraphSONMode; +import com.tinkerpop.blueprints.util.io.graphson.GraphSONUtility; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class Utility { + + private static final Logger logger = LoggerFactory.getLogger(Utility.class); + + public static String orientVertexToJsonString(OrientVertex orientVertex) { + ORecord oRecord = orientVertex.getRecord(); + return oRecord.toJSON(); + } + + public static String vertexToJsonString(Vertex vertex, boolean raw) + throws JSONException { + if (raw) { + return GraphSONUtility.jsonFromElement(vertex, + vertex.getPropertyKeys(), GraphSONMode.EXTENDED).toString(); + } else { + Set keys = new HashSet<>(vertex.getPropertyKeys()); + for (String key : vertex.getPropertyKeys()) { + if (key.startsWith("_")) { + keys.remove(key); + } + } + return GraphSONUtility.jsonFromElement(vertex, keys, + GraphSONMode.COMPACT).toString(); + } + } + + public static String vertexToJsonString(Vertex vertex) { + try { + return vertexToJsonString(vertex, true); + } catch (Exception e) { + return String.valueOf(vertex); + } + } + + public static String orientEdgeToJsonString(OrientEdge orientEdge) { + ORecord oRecord = orientEdge.getRecord(); + return oRecord.toJSON(); + } + + public static String edgeToJsonString(Edge edge, boolean raw) + throws JSONException { + if (raw) { + return GraphSONUtility.jsonFromElement(edge, + edge.getPropertyKeys(), GraphSONMode.EXTENDED).toString(); + } else { + Set keys = new HashSet<>(edge.getPropertyKeys()); + for (String key : edge.getPropertyKeys()) { + if (key.startsWith("_")) { + keys.remove(key); + } + } + return GraphSONUtility.jsonFromElement(edge, keys, + GraphSONMode.COMPACT).toString(); + } + } + + public static String edgeToJsonString(Edge edge) { + try { + return edgeToJsonString(edge, true); + } catch (Exception e) { + return String.valueOf(edge); + } + } + + public static Vertex getEntityByUUID(OrientGraph orientGraph, + String entityType, String uuid) throws ResourceRegistryException { + + if (entityType == null) { + entityType = Entity.NAME; + } + + // TODO Rewrite using Gremlin + String select = "SELECT FROM " + entityType + " WHERE " + + Entity.HEADER_PROPERTY + "." + Header.UUID_PROPERTY + " = \"" + + uuid + "\""; + + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery( + select); + + Iterable vertexes = orientGraph.command(osqlSynchQuery) + .execute(); + if (vertexes == null || !vertexes.iterator().hasNext()) { + String error = String.format("No %s with UUID %s was found", + entityType, uuid); + logger.info(error); + throw new EntityException(error); + } + + Iterator iterator = vertexes.iterator(); + Vertex entity = iterator.next(); + + logger.trace("{} with {} is : {}", entityType, uuid, + Utility.vertexToJsonString(entity)); + + if (iterator.hasNext()) { + throw new ResourceRegistryException("Found more than one " + + entityType + " with uuid " + uuid + + ". This is a fatal error please contact Admnistrator"); + } + + return entity; + } + + public static Edge getRelationByUUID(OrientGraph orientGraph, + String relationType, String uuid) throws ResourceRegistryException { + + if (relationType == null) { + relationType = Relation.class.getSimpleName(); + } + + // TODO Rewrite using Gremlin + String select = "SELECT FROM " + relationType + " WHERE " + + Relation.HEADER_PROPERTY + "." + Header.UUID_PROPERTY + + " = \"" + uuid + "\""; + + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery(select); + + Iterable edges = orientGraph.command(osqlSynchQuery).execute(); + if (edges == null || !edges.iterator().hasNext()) { + String error = String.format("No %s with UUID %s was found", + relationType, uuid); + logger.info(error); + throw new FacetNotFoundException(error); + } + + Iterator iterator = edges.iterator(); + Edge relation = iterator.next(); + + logger.trace("{} with {} is : {}", relationType, uuid, + Utility.edgeToJsonString(relation)); + + if (iterator.hasNext()) { + throw new ResourceRegistryException("Found more than one " + + relationType + " with uuid " + uuid + + ". This is a fatal error please contact Admnistrator"); + } + + return relation; + } +} \ No newline at end of file diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/ContextManagerFactory.java b/src/test/java/org/gcube/informationsystem/resourceregistry/ContextManagerFactory.java new file mode 100644 index 0000000..d2c119c --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/ContextManagerFactory.java @@ -0,0 +1,54 @@ +package org.gcube.informationsystem.resourceregistry; + +import org.gcube.informationsystem.resourceregistry.api.ContextManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextCreationException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.glassfish.hk2.api.Factory; + +public class ContextManagerFactory implements Factory { + + @Override + public void dispose(ContextManagement arg0) { + } + + @Override + public ContextManagement provide() { + return new ContextManagement() { + + @Override + public String delete(String uuid) throws ContextNotFoundException { + return "{fake resource}"; + } + + + @Override + public String create(String parentContextUUID, String name) + throws ContextCreationException { + return parentContextUUID+"newContext-"+name; + } + + @Override + public String rename(String contextUUID, String name) + throws ContextNotFoundException { + return contextUUID+"-newName:"+name; + } + + @Override + public String move(String newParentUUID, String contextToMoveUUID) + throws ContextNotFoundException { + return newParentUUID+"-"+contextToMoveUUID; + } + + + @Override + public String read(String contextUUID) + throws ContextNotFoundException, ContextException { + return contextUUID; + } + }; + + + } + +} \ No newline at end of file diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/EntityManagementFactory.java b/src/test/java/org/gcube/informationsystem/resourceregistry/EntityManagementFactory.java new file mode 100644 index 0000000..75a09da --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/EntityManagementFactory.java @@ -0,0 +1,108 @@ +package org.gcube.informationsystem.resourceregistry; + +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.ResourceNotFoundException; +import org.glassfish.hk2.api.Factory; + +public class EntityManagementFactory implements Factory { + + @Override + public void dispose(EntityManagement arg0) { + // TODO Auto-generated method stub + } + + @Override + public EntityManagement provide() { + return new EntityManagement() { + + @Override + public String updateFacet(String uuid, String jsonRepresentation) + throws FacetNotFoundException { + return null; + } + + @Override + public String readResource(String uuid) + throws ResourceNotFoundException { + return "resource"; + } + + @Override + public String readFacet(String uuid) throws FacetNotFoundException { + return "facet"; + } + + @Override + public boolean deleteResource(String uuid) + throws ResourceNotFoundException, ResourceRegistryException { + return false; + } + + @Override + public boolean deleteFacet(String uuid) + throws FacetNotFoundException, ResourceRegistryException { + return false; + } + + @Override + public String createResource(String resourceType, + String jsonRepresentation) throws ResourceRegistryException { + return null; + } + + @Override + public String createFacet(String facetType, + String jsonRepresentation) throws ResourceRegistryException { + return null; + } + + @Override + public String attachResource(String sourceResourceUuid, + String targetResourceUuid, String relatedToType, + String jsonProperties) throws ResourceNotFoundException, + ResourceRegistryException { + return null; + } + + @Override + public String attachFacet(String resourceUuid, String facetUuid, + String consistOfType, String jsonProperties) + throws FacetNotFoundException, ResourceNotFoundException, + ResourceRegistryException { + return null; + } + + @Override + public String readFacet(String uuid, String facetType) + throws FacetNotFoundException, ResourceRegistryException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String readResource(String uuid, String resourceType) + throws ResourceNotFoundException, ResourceRegistryException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean detachFacet(String consistOfUUID) + throws ResourceRegistryException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean detachResource(String relatedToUUID) + throws ResourceRegistryException { + // TODO Auto-generated method stub + return false; + } + + }; + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/EntityRegistrationFactory.java b/src/test/java/org/gcube/informationsystem/resourceregistry/EntityRegistrationFactory.java new file mode 100644 index 0000000..571dce7 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/EntityRegistrationFactory.java @@ -0,0 +1,227 @@ +package org.gcube.informationsystem.resourceregistry; + +import org.gcube.informationsystem.resourceregistry.api.SchemaManagement; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; +import org.glassfish.hk2.api.Factory; + +public class EntityRegistrationFactory implements Factory{ + + @Override + public void dispose(SchemaManagement arg0) { + // TODO Auto-generated method stub + + } + + @Override + public SchemaManagement provide() { + return new SchemaManagement() { + + @Override + public String registerEntitySchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEntitySchema(String entityType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateEntitySchema(String entityType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteEntitySchema(String entityType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerFacetSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getFacetSchema(String facetType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateFacetSchema(String facetType, String jsonSchema) + throws SchemaNotFoundException, SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteFacetSchema(String facetType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerResourceSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getResourceSchema(String resourceType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateResourceSchema(String resourceType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteResourceSchema(String resourceType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerEmbeddedTypeSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEmbeddedTypeSchema(String embeddedType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateEmbeddedTypeSchema(String embeddedType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteEmbeddedTypeSchema(String embeddedType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerRelationSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getRelationSchema(String relationType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateRelationSchema(String relationType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteRelationSchema(String relationType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerConsistOfSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getConsistOfSchema(String consistOfType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateConsistOfSchema(String consistOfType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteConsistOfSchema(String consistOfType) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String registerRelatedToSchema(String jsonSchema) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getRelatedToSchema(String relatedToType) + throws SchemaNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String updateRelatedToSchema(String relatedToType, + String jsonSchema) throws SchemaNotFoundException, + SchemaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String deleteRelatedToSchema(String relatedToType) + throws SchemaException { + // TODO Auto-generated method stub + return null; + } + + + + }; + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/QueryManagerFactory.java b/src/test/java/org/gcube/informationsystem/resourceregistry/QueryManagerFactory.java new file mode 100644 index 0000000..3d0fbab --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/QueryManagerFactory.java @@ -0,0 +1,28 @@ +package org.gcube.informationsystem.resourceregistry; + +import org.gcube.informationsystem.resourceregistry.api.Query; +import org.gcube.informationsystem.resourceregistry.api.exceptions.InvalidQueryException; +import org.glassfish.hk2.api.Factory; + +public class QueryManagerFactory implements Factory{ + + @Override + public void dispose(Query arg0) { + // TODO Auto-generated method stub + + } + + @Override + public Query provide() { + return new Query() { + + @Override + public String execute(String query, String fetchPlan) throws InvalidQueryException { + if (query.equals("error")) + throw new InvalidQueryException("error in query"); + return "result"; + } + }; + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/access/AccessTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/access/AccessTest.java new file mode 100644 index 0000000..e315a90 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/access/AccessTest.java @@ -0,0 +1,74 @@ +package org.gcube.informationsystem.resourceregistry.access; + +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +import org.gcube.informationsystem.resourceregistry.EntityManagementFactory; +import org.gcube.informationsystem.resourceregistry.EntityRegistrationFactory; +import org.gcube.informationsystem.resourceregistry.QueryManagerFactory; +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.api.Query; +import org.gcube.informationsystem.resourceregistry.api.SchemaManagement; +import org.gcube.informationsystem.resourceregistry.exceptions.ResourceRegistryExceptionMapper; +import org.gcube.informationsystem.resourceregistry.resources.Access; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Assert; +import org.junit.Test; + +public class AccessTest extends JerseyTest{ + + + @Override + protected Application configure() { + AbstractBinder binder = new AbstractBinder() { + @Override + protected void configure() { + bindFactory(EntityManagementFactory.class).to(EntityManagement.class); + bindFactory(QueryManagerFactory.class).to(Query.class); + bindFactory(EntityRegistrationFactory.class).to(SchemaManagement.class); + } + }; + ResourceConfig config = new ResourceConfig(Access.class, ResourceRegistryExceptionMapper.class); + config.register(binder); + return config; + } + + @Test + public void validQuery(){ + Response response = target("access").queryParam("query", "select * from test").request().get(Response.class); + Assert.assertEquals(200, response.getStatus()); + } + + @Test + public void invalidQuery(){ + Response response = target("access").queryParam("query", "error").request().get(Response.class); + Assert.assertEquals(400, response.getStatus()); + } + + @Test + public void getfacet(){ + Response response = target("access").path("facet").path("facetId").request().get(Response.class); + Assert.assertEquals(200, response.getStatus()); + } + + @Test + public void getResource(){ + Response response = target("access").path("resource").path("resourceId").request().get(Response.class); + Assert.assertEquals(200, response.getStatus()); + } + + @Test + public void getfacetSchema(){ + Response response = target("access").path("facet").path("schema").path("facetType").request().get(Response.class); + Assert.assertEquals(200, response.getStatus()); + } + + @Test + public void getResourceSchema(){ + Response response = target("access").path("resource").path("schema").path("resourceType").request().get(Response.class); + Assert.assertEquals(200, response.getStatus()); + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/context/ContextManagementTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ContextManagementTest.java new file mode 100644 index 0000000..bb5d0b3 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ContextManagementTest.java @@ -0,0 +1,57 @@ +package org.gcube.informationsystem.resourceregistry.context; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +import org.gcube.informationsystem.resourceregistry.ContextManagerFactory; +import org.gcube.informationsystem.resourceregistry.api.ContextManagement; +import org.gcube.informationsystem.resourceregistry.exceptions.ResourceRegistryExceptionMapper; +import org.gcube.informationsystem.resourceregistry.resources.ContextManager; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Assert; +import org.junit.Test; + +public class ContextManagementTest extends JerseyTest{ + + @Override + protected Application configure() { + AbstractBinder binder = new AbstractBinder() { + @Override + protected void configure() { + bindFactory(ContextManagerFactory.class) + .to(ContextManagement.class); + } + }; + ResourceConfig config = new ResourceConfig(ContextManager.class, ResourceRegistryExceptionMapper.class); + config.register(binder); + return config; + } + + + @Test + public void create(){ + Response response = target("context").path("parentContextId").request().put(Entity.text(new String("{fake context creation}")), Response.class); + Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + @Test + public void delete(){ + Response response = target("context").path("contextID").request().delete(Response.class); + Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + @Test + public void move(){ + Response response = target("context").path("Move").path("contextID").request().put(Entity.text(new String("{newContextParentId}")), Response.class); + Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + @Test + public void rename(){ + Response response = target("context").path("Rename").path("contextID").request().put(Entity.text(new String("{newName}")), Response.class); + Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ContextCreation.java b/src/test/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ContextCreation.java new file mode 100644 index 0000000..b6bd0d7 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/dbinitialization/ContextCreation.java @@ -0,0 +1,31 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.dbinitialization; + +import org.gcube.informationsystem.model.embedded.Embedded; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.facet.CPUFacet; +import org.gcube.informationsystem.model.relation.Host; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.model.resource.Configuration; +import org.junit.Test; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class ContextCreation { + + @Test + public void test() throws Exception{ + SchemaInitializator.addPackage(Embedded.class.getPackage()); + SchemaInitializator.addPackage(Entity.class.getPackage()); + SchemaInitializator.addPackage(Relation.class.getPackage()); + SchemaInitializator.addPackage(CPUFacet.class.getPackage()); + SchemaInitializator.addPackage(Host.class.getPackage()); + SchemaInitializator.addPackage(Configuration.class.getPackage()); + SchemaInitializator.createTypes(); + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityManagementTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityManagementTest.java new file mode 100644 index 0000000..7c9f79c --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityManagementTest.java @@ -0,0 +1,78 @@ +package org.gcube.informationsystem.resourceregistry.entitymanager; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +import org.gcube.informationsystem.resourceregistry.EntityManagementFactory; +import org.gcube.informationsystem.resourceregistry.api.EntityManagement; +import org.gcube.informationsystem.resourceregistry.exceptions.ResourceRegistryExceptionMapper; +import org.gcube.informationsystem.resourceregistry.resources.EntityManager; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Assert; +import org.junit.Test; +public class EntityManagementTest extends JerseyTest{ + + @Override + protected Application configure() { + AbstractBinder binder = new AbstractBinder() { + @Override + protected void configure() { + bindFactory(EntityManagementFactory.class).to(EntityManagement.class); + } + }; + ResourceConfig config = new ResourceConfig(EntityManager.class, ResourceRegistryExceptionMapper.class); + config.register(binder); + return config; + } + + @Test + public void createFacet(){ + Response response = target("entity").path("facet").path("facetType").request().put(Entity.text(new String("{fake facet creation}")), Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void createResource(){ + Response response = target("entity").path("resource").path("resourceType").request().put(Entity.text(new String("{fake resource creation}")), Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void deleteFacet(){ + Response response = target("entity").path("facet").path("facetId").request().delete(Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void deleteResource(){ + Response response = target("entity").path("resource").path("resourceId").request().delete(Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void attachFacet(){ + Response response = target("entity").path("resource").path("resourceId").path("facet").path("facetId").request().put(Entity.text(new String("{Relation Properties}")), Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void attachResource(){ + Response response = target("entity").path("resource/source").path("sourceResourceId").path("target").path("targetResourceId").request().put(Entity.text(new String("{Relation Properties}")), Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void detachFacet(){ + Response response = target("entity").path("resource").path("resourceId").path("facet").path("facetId").request().delete(Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } + + @Test + public void detachResource(){ + Response response = target("entity").path("resource/source").path("sourceResourceId").path("target").path("targetResourceId").request().delete(Response.class); + Assert.assertEquals(Response.Status.OK.getFamily(), response.getStatusInfo().getFamily()); + } +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityRegistrationTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityRegistrationTest.java new file mode 100644 index 0000000..d577e7c --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/entitymanager/EntityRegistrationTest.java @@ -0,0 +1,5 @@ +package org.gcube.informationsystem.resourceregistry.entitymanager; + +public class EntityRegistrationTest { + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImplTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImplTest.java new file mode 100644 index 0000000..fdd8af2 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/ContextManagementImplTest.java @@ -0,0 +1,342 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import org.gcube.informationsystem.model.facet.ContactFacet; +import org.gcube.informationsystem.model.relation.Run; +import org.gcube.informationsystem.model.resource.Service; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextCreationException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseIntializator; +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 ContextManagementImplTest { + + private static Logger logger = LoggerFactory.getLogger(ContextManagementImplTest.class); + + protected ContextManagementImpl contextManagementImpl; + + /* + private static final String VALID_CHARACTER = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + + private String randomString(int lenght) { + StringBuilder sb = new StringBuilder(lenght); + for (int i = 0; i < lenght; i++) { + sb.append(VALID_CHARACTER.charAt(SECURE_RANDOM + .nextInt(VALID_CHARACTER.length()))); + } + return sb.toString(); + } + */ + + public ContextManagementImplTest(){ + contextManagementImpl = new ContextManagementImpl(); + DatabaseIntializator.addPackage(Service.class.getPackage()); + DatabaseIntializator.addPackage(Run.class.getPackage()); + DatabaseIntializator.addPackage(ContactFacet.class.getPackage()); + } + + public static final String CTX_NAME_A = "A"; + public static final String CTX_NAME_B = "B"; + public static final String CTX_NAME_C = "C"; + + protected void invalidCreation(String parentUUID, String name){ + try { + contextManagementImpl.create(parentUUID, name); + throw new RuntimeException("The context " + name + " with parent " + parentUUID + " was already created and MUST throw " + ContextCreationException.class.getSimpleName() + ". This is a bug in your code."); + } catch (ContextCreationException e) { + logger.debug("As expected the context {} with parent {} was already created and a {} has been thrown", name, parentUUID, e.getClass().getSimpleName()); + } + } + + protected void invalidMoving(String parentUUID, String name){ + try { + contextManagementImpl.move(parentUUID, name); + throw new RuntimeException("The context " + name + " with parent " + parentUUID + " was already created and MUST throw " + ContextException.class.getSimpleName() + ". This is a bug in your code."); + } catch (ContextNotFoundException e) { + throw new RuntimeException(e); + } catch (ContextException e) { + logger.debug("As expected the context {} with parent {} was already created and a {} has been thrown", name, parentUUID, e.getClass().getSimpleName()); + } + } + + protected void invalidRename(String uuid, String newName){ + try { + contextManagementImpl.rename(uuid, newName); + throw new RuntimeException("The context with uuid " + uuid + " cannot be renamed to " + newName + " and MUST throw " + ContextException.class.getSimpleName() + ". This is a bug in your code."); + } catch (ContextNotFoundException e) { + throw new RuntimeException(e); + } catch (ContextException e) { + logger.debug("As expected the context with uuid {} cannot be renamed to {} and a {} has been thrown", uuid, newName, e.getClass().getSimpleName()); + } + } + + + protected void invalidDelete(String uuid){ + try { + contextManagementImpl.delete(uuid); + throw new RuntimeException("The context with uuid " + uuid + " cannot be deleted and MUST throw " + ContextException.class.getSimpleName() + ". This is a bug in your code."); + } catch (ContextNotFoundException e) { + throw new RuntimeException(e); + } catch (ContextException e) { + logger.debug("As expected the context with uuid {} cannot be deleted and a {} has been thrown", uuid, e.getClass().getSimpleName()); + } + } + + @Test + public void simpleTest() throws ContextNotFoundException, ContextException { + String A_1 = contextManagementImpl.create(null, CTX_NAME_A); + /* + * A(1) + */ + + String A_2 = contextManagementImpl.create(A_1, CTX_NAME_A); + /* + * A_1 + * A_2 + */ + String B_3 = contextManagementImpl.create(A_2, CTX_NAME_B); + /* + * A_1 + * A_2 + * B_3 + */ + + contextManagementImpl.move(A_1, B_3); + /* + * A_1 + * A_2 B_3 + */ + + contextManagementImpl.rename(B_3, CTX_NAME_C); + /* + * A_1 + * A_2 C_3 + */ + + contextManagementImpl.rename(B_3, CTX_NAME_B); + /* + * A_1 + * A_2 C_3 + */ + + contextManagementImpl.move(A_2, B_3); + /* + * A_1 + * A_2 + * B_3 + */ + + contextManagementImpl.delete(B_3); + /* + * A_1 + * A_2 + */ + contextManagementImpl.delete(A_2); + /* + * A_1 + */ + contextManagementImpl.delete(A_1); + /* + * + */ + logger.debug("The DB should be now clean"); + } + + + //@Test + public void devContextTest() throws ContextNotFoundException, ContextException { + String gcube = contextManagementImpl.create(null, "gcube"); + logger.trace("/gcube : {}", gcube); + String devsec = contextManagementImpl.create(gcube, "devsec"); + logger.trace("/gcube/devsec : {}", devsec); + String devVRE = contextManagementImpl.create(devsec, "devVRE"); + logger.trace("/gcube/devsec/devVRE : {}", devVRE); + String devNext = contextManagementImpl.create(gcube, "devNext"); + logger.trace("/gcube/devNext : {}", devNext); + String NextNext = contextManagementImpl.create(devNext, "NextNext"); + logger.trace("/gcube/devNext/NextNext : {}", NextNext); + + /* + contextManagementImpl.delete(NextNext); + contextManagementImpl.delete(devNext); + contextManagementImpl.delete(devVRE); + contextManagementImpl.delete(devsec); + contextManagementImpl.delete(gcube); + */ + + logger.debug("The DB should be now clean"); + } + + @Test + public void readTest() throws ContextNotFoundException, ContextException { + String A_1 = contextManagementImpl.create(null, "LLL"); + String read = contextManagementImpl.read(A_1); + logger.trace("A : {}", read); + contextManagementImpl.delete(A_1); + } + + @Test + public void completeTest() throws ContextNotFoundException, ContextException { + String A_1 = contextManagementImpl.create(null, CTX_NAME_A); + /* + * A(1) + */ + + String A_2 = contextManagementImpl.create(A_1, CTX_NAME_A); + /* + * A_1 + * A_2 + */ + + String B_3 = contextManagementImpl.create(A_2, CTX_NAME_B); + /* + * A_1 + * A_2 + * B_3 + */ + + + String B_4 = contextManagementImpl.create(A_1, CTX_NAME_B); + /* + * A_1 + * A_2 B_4 + * B_3 + */ + + String A_5 = contextManagementImpl.create(B_4, CTX_NAME_A); + /* + * A_1 + * A_2 B_4 + * B_3 A_5 + */ + + + invalidCreation(null, CTX_NAME_A); // Trying to recreate A_1. Fails + invalidCreation(A_1, CTX_NAME_A); // Trying to recreate A_2. Fails + invalidCreation(A_2, CTX_NAME_B); // Trying to recreate B_3. Fails + invalidCreation(A_1, CTX_NAME_B); // Trying to recreate B_4. Fails + invalidCreation(B_4, CTX_NAME_A); // Trying to recreate A_5. Fails + + + // Trying to move B_3 as child of A_1. It fails due to B_4. Fails + invalidMoving(A_1, B_3); + // Trying to move A_5 as child of A_1. It fails due to A_2. Fails + invalidMoving(A_1, A_5); + + + + // Moving B_3 as child of B_4. OK + contextManagementImpl.move(B_4, B_3); + /* + * A_1 + * A_2 B_4 + * B_3 A_5 + */ + + // Restoring the initial situation by moving B_3 as child of A_2 + contextManagementImpl.move(A_2, B_3); + /* + * A_1 + * A_2 B_4 + * B_3 A_5 + */ + + + // Trying to move B_3 as child of A_1. It fails due to B_4. Fails + invalidMoving(A_1, B_3); + + // Renaming B_3 as C_3 + String C_3 = contextManagementImpl.rename(B_3, CTX_NAME_C); + Assert.assertTrue(C_3.compareTo(B_3)==0); + /* + * A_1 + * A_2 B_4 + * C_3 A_5 + */ + + // Moving C_3 (was B_3) as child of A_1. Now it is possible + contextManagementImpl.move(A_1, B_3); + /* + * A_1 + * C_3 A_2 B_4 + * A_5 + */ + + + + // Trying to rename C_3 (was B_3) newly to B_3. Fails due to B_4 + invalidRename(C_3, CTX_NAME_B); + + + // Moving back C_3 (was B_3) as child of A_2. + contextManagementImpl.move(A_2, B_3); + String BC_3 = contextManagementImpl.rename(C_3, CTX_NAME_B); + Assert.assertTrue(BC_3.compareTo(B_3)==0); + Assert.assertTrue(BC_3.compareTo(C_3)==0); + /* + * A_1 + * A_2 B_4 + * B_3 A_5 + */ + + + invalidDelete(A_1); + invalidDelete(A_2); + invalidDelete(B_4); + contextManagementImpl.delete(A_5); + /* + * A_1 + * A_2 B_4 + * B_3 + */ + try { + contextManagementImpl.delete(A_5); + } catch(ContextNotFoundException e){ + logger.debug("The context with uuid {} was not found. (Was already deleted)", A_5); + } + + contextManagementImpl.delete(B_3); + /* + * A_1 + * A_2 B_4 + */ + invalidDelete(A_1); + contextManagementImpl.delete(B_4); + /* + * A_1 + * A_2 + */ + contextManagementImpl.delete(A_2); + /* + * A_1 + */ + + contextManagementImpl.delete(A_1); + + + logger.debug("The DB should be now clean"); + } + + + @Test + public void moveToRootTest() throws ContextNotFoundException, ContextException { + String A_1 = contextManagementImpl.create(null, CTX_NAME_A); + String A_2 = contextManagementImpl.create(A_1, CTX_NAME_B); + contextManagementImpl.move(null, A_2); + contextManagementImpl.delete(A_1); + contextManagementImpl.delete(A_2); + logger.debug("The DB should be now clean"); + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImplTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImplTest.java new file mode 100644 index 0000000..34daa01 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/EntityManagementImplTest.java @@ -0,0 +1,240 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import java.io.StringWriter; + +import org.codehaus.jettison.json.JSONObject; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.informationsystem.impl.facet.CPUFacetImpl; +import org.gcube.informationsystem.impl.utils.Entities; +import org.gcube.informationsystem.impl.utils.Utility; +import org.gcube.informationsystem.model.embedded.Header; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.facet.CPUFacet; +import org.gcube.informationsystem.model.relation.ConsistOf; +import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.model.resource.HostingNode; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.FacetNotFoundException; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class EntityManagementImplTest { + + private static Logger logger = LoggerFactory + .getLogger(EntityManagementImplTest.class); + + protected EntityManagementImpl entityManagementImpl; + + public EntityManagementImplTest() { + entityManagementImpl = new EntityManagementImpl(); + } + + @Test + public void testCreateReadDeleteFacet() throws Exception { + ScopeProvider.instance.set("/gcube/devsec"); + + CPUFacetImpl cpuFacetImpl = new CPUFacetImpl(); + cpuFacetImpl.setClockSpeed("1 GHz"); + cpuFacetImpl.setModel("Opteron"); + cpuFacetImpl.setVendor("AMD"); + StringWriter stringWriter = new StringWriter(); + Entities.marshal(cpuFacetImpl, stringWriter); + + String json = entityManagementImpl.createFacet( + CPUFacet.class.getSimpleName(), stringWriter.toString()); + logger.debug("Created : {}", json); + + String uuid = Utility.getUUIDFromJSONString(json); + + String readJson = entityManagementImpl.readFacet(uuid); + logger.debug("Read : {}", readJson); + + stringWriter = new StringWriter(); + Entities.marshal(cpuFacetImpl, stringWriter); + cpuFacetImpl.setVendor("Luca"); + + JsonNode jsonNode = Utility.getJSONNode(stringWriter.toString()); + ((ObjectNode) jsonNode).remove("clockSpeed"); + ((ObjectNode) jsonNode).put("My", "Test"); + + stringWriter = new StringWriter(); + Entities.marshal(jsonNode, stringWriter); + + readJson = entityManagementImpl.updateFacet(uuid, + stringWriter.toString()); + logger.debug("Updated : {}", readJson); + + readJson = entityManagementImpl.readFacet(uuid); + logger.debug("Read Updated : {}", readJson); + + boolean deleted = entityManagementImpl.deleteFacet(uuid); + if (!deleted) { + throw new Exception("Facet Not Deleted"); + } + + } + + @Test + public void testDifferentScopes() throws Exception { + ScopeProvider.instance.set("/gcube/devsec"); + + CPUFacetImpl cpuFacetImpl = new CPUFacetImpl(); + cpuFacetImpl.setClockSpeed("1 GHz"); + cpuFacetImpl.setModel("Opteron"); + cpuFacetImpl.setVendor("AMD"); + StringWriter stringWriter = new StringWriter(); + Entities.marshal(cpuFacetImpl, stringWriter); + + String json = entityManagementImpl.createFacet( + CPUFacet.class.getSimpleName(), stringWriter.toString()); + logger.debug("Created : {}", json); + + JSONObject jsonObject = new JSONObject(json); + JSONObject header = jsonObject.getJSONObject(Entity.HEADER_PROPERTY); + String uuid = header.getString(Header.UUID_PROPERTY); + + String readJson = entityManagementImpl.readFacet(uuid); + logger.debug("Read : {}", readJson); + + /*----------*/ + + logger.debug("Setting /gcube/devNext scope"); + ScopeProvider.instance.set("/gcube/devNext"); + try { + readJson = entityManagementImpl.readFacet(uuid); + logger.debug("You should not be able to read Feact with UUID {}", + uuid); + throw new Exception( + "You should not be able to read Feact with UUID " + uuid); + } catch (FacetNotFoundException e) { + logger.debug("Good the facet created in /gcube/devsec is not visible in /gcube/devNext"); + } + + jsonObject = new JSONObject(stringWriter.toString()); + jsonObject.remove("clockSpeed"); + jsonObject.put("My", "Test"); + + try { + readJson = entityManagementImpl.updateFacet(uuid, + jsonObject.toString()); + logger.debug("You should not be able to update Facet with UUID {}", + uuid); + throw new Exception( + "You should not be able to read Facet with UUID " + uuid); + } catch (FacetNotFoundException e) { + logger.debug("Good the Facet created in /gcube/devsec cannot be updated in /gcube/devNext"); + } + + try { + entityManagementImpl.deleteFacet(uuid); + logger.debug("You should not be able to delete Facet with UUID {}", + uuid); + throw new Exception( + "You should not be able to delete Facet with UUID " + uuid); + } catch (FacetNotFoundException e) { + logger.debug("Good the Facet created in /gcube/devsec cannot be deleted in /gcube/devNext"); + } + + /*----------*/ + + logger.debug("Setting back /gcube/devsec scope"); + ScopeProvider.instance.set("/gcube/devsec"); + + readJson = entityManagementImpl + .updateFacet(uuid, jsonObject.toString()); + logger.debug("Updated : {}", readJson); + + readJson = entityManagementImpl.readFacet(uuid); + logger.debug("Read Updated : {}", readJson); + + boolean deleted = entityManagementImpl.deleteFacet(uuid); + if (!deleted) { + throw new Exception("Facet Not Deleted"); + } + + } + + /* + * @Test public void testCreateFacet() throws Exception{ + * ScopeProvider.instance.set("/gcube/devsec"); + * + * CPUFacetImpl cpuFacetImpl = new CPUFacetImpl(); + * cpuFacetImpl.setClockSpeed("1 GHz"); + * cpuFacetImpl.setModelName("Opteron"); cpuFacetImpl.setVendor("AMD"); + * StringWriter stringWriter = new StringWriter(); + * Entities.marshal(cpuFacetImpl, stringWriter); + * + * String json = + * entityManagementImpl.createFacet(CPUFacet.class.getSimpleName(), + * stringWriter.toString()); logger.debug("Created : {}", json); } + */ + + /* + * @Test public void testReadFacet() throws Exception{ + * ScopeProvider.instance.set("/gcube/devsec"); String readJson = + * entityManagementImpl.readFacet(""); logger.debug("Read : {}", readJson); + * } + */ + + /* + * @Test public void testDeleteFacet() throws Exception{ + * ScopeProvider.instance.set("/gcube/devsec"); boolean deleted = + * entityManagementImpl.deleteFacet(""); if(!deleted){ throw new + * Exception("Facet Not Deleted"); } } + */ + + @Test + public void testCreateResourceAndFacet() throws Exception { + ScopeProvider.instance.set("/gcube/devsec"); + + String json = entityManagementImpl.createResource( + HostingNode.class.getSimpleName(), "{}"); + String resourceUUID = Utility.getUUIDFromJSONString(json); + + CPUFacetImpl cpuFacetImpl = new CPUFacetImpl(); + cpuFacetImpl.setClockSpeed("1 GHz"); + cpuFacetImpl.setModel("Opteron"); + cpuFacetImpl.setVendor("AMD"); + StringWriter stringWriter = new StringWriter(); + Entities.marshal(cpuFacetImpl, stringWriter); + + json = entityManagementImpl.createFacet(CPUFacet.class.getSimpleName(), + stringWriter.toString()); + logger.debug("Created : {}", json); + String facetUUID = Utility.getUUIDFromJSONString(json); + + json = entityManagementImpl.attachFacet(resourceUUID, facetUUID, + ConsistOf.class.getSimpleName(), null); + logger.debug("Facet attached : {}", json); + + String consistOfUUID = Utility.getUUIDFromJSONString(json); + + boolean detached = entityManagementImpl.detachFacet(consistOfUUID); + + if (detached) { + logger.trace("{} {} with uuid {} removed successfully", + ConsistOf.NAME, Relation.NAME, consistOfUUID); + } else { + String error = String.format("Unable to remove %s %s with uuid %s", + ConsistOf.NAME, Relation.NAME, consistOfUUID); + logger.error(error); + throw new Exception(error); + } + + entityManagementImpl.deleteResource(resourceUUID); + + entityManagementImpl.deleteFacet(facetUUID); + + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImplTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImplTest.java new file mode 100644 index 0000000..cc067bb --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/resources/impl/QueryImplTest.java @@ -0,0 +1,26 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.resources.impl; + +import org.gcube.informationsystem.resourceregistry.api.exceptions.InvalidQueryException; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class QueryImplTest { + + private static Logger logger = LoggerFactory.getLogger(QueryImplTest.class); + + @Test + public void testQuery() throws InvalidQueryException{ + QueryImpl queryImpl = new QueryImpl(); + String ret = queryImpl.execute("select * from CPUFacet", null); + logger.debug(ret); + } + +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..4f36cc8 --- /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