diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..fae1a2b
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..ea75af5
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ resource-registry-context-client
+
+
+
+
+
+ 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..714351a
--- /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.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8
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/pom.xml b/pom.xml
new file mode 100644
index 0000000..958f0b2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,97 @@
+
+ 4.0.0
+
+ org.gcube.tools
+ maven-parent
+ 1.0.0
+
+
+ org.gcube.information-system
+ resource-registry-context-client
+ 1.0.0-SNAPSHOT
+ Resource Registry Context Client
+ Contains Non Idempotent API to manage Contexts in Resource Registry
+
+
+ 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
+ gcube-bom
+ LATEST
+ pom
+ import
+
+
+ org.gcube.information-system
+ information-system-bom
+ LATEST
+ pom
+ import
+
+
+
+
+
+
+ org.gcube.common
+ authorization-client
+
+
+ org.gcube.resources.discovery
+ ic-client
+
+
+ org.gcube.information-system
+ resource-registry-api
+ [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)
+
+
+ org.gcube.information-system
+ information-system-model
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ 1.0.13
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ make-servicearchive
+ package
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClient.java b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClient.java
new file mode 100644
index 0000000..7a488e3
--- /dev/null
+++ b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClient.java
@@ -0,0 +1,48 @@
+package org.gcube.informationsystem.resourceregistry.client;
+
+import java.util.UUID;
+
+import org.gcube.informationsystem.model.entity.Context;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextAlreadyPresentException;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException;
+
+/**
+ * @author Luca Frosini (ISTI - CNR)
+ */
+public interface ResourceRegistryContextClient {
+
+ public Context create(Context context)
+ throws ContextAlreadyPresentException, ResourceRegistryException;
+
+ public String create(String context)
+ throws ContextAlreadyPresentException, ResourceRegistryException;
+
+
+ public Context read(Context context)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+ public Context read(UUID uuid)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+ public String read(String uuid)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+
+ public Context update(Context context)
+ throws ContextAlreadyPresentException, ResourceRegistryException;
+
+ public String update(String context)
+ throws ContextAlreadyPresentException, ResourceRegistryException;
+
+
+ public boolean delete(Context context)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+ public boolean delete(UUID uuid)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+ public boolean delete(String uuid)
+ throws ContextNotFoundException, ResourceRegistryException;
+
+}
diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientFactory.java b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientFactory.java
new file mode 100644
index 0000000..d925ec2
--- /dev/null
+++ b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientFactory.java
@@ -0,0 +1,127 @@
+package org.gcube.informationsystem.resourceregistry.client;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
+import org.gcube.common.resources.gcore.GCoreEndpoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.informationsystem.resourceregistry.api.Constants;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.gcube.resources.discovery.icclient.ICFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Luca Frosini (ISTI - CNR)
+ */
+public class ResourceRegistryContextClientFactory {
+
+ private static final Logger logger = LoggerFactory.getLogger(ResourceRegistryContextClientFactory.class);
+
+ protected static Map clients;
+
+ static {
+ clients = new HashMap<>();
+ }
+
+ private static String FORCED_URL = null;
+
+ protected static void forceToURL(String url){
+ FORCED_URL = url;
+ }
+
+ private static String classFormat = "$resource/Profile/ServiceClass/text() eq '%1s'";
+ private static String nameFormat = "$resource/Profile/ServiceName/text() eq '%1s'";
+ private static String statusFormat = "$resource/Profile/DeploymentData/Status/text() eq 'ready'";
+ private static String containsFormat = "$entry/@EntryName eq '%1s'";
+
+
+ private static String serviceEndpointCategoryFormat = "$resource/Profile/Category/text() eq '%1s'";
+ private static String serviceEndpointNameFormat = "$resource/Profile/Name/text() eq '%1s'";
+ private static String serviceEndpointstatusFormat = "$resource/Profile/RunTime/Status/text() eq 'READY'";
+
+
+
+ private static SimpleQuery queryForService(){
+ return ICFactory.queryFor(GCoreEndpoint.class)
+ .addCondition(String.format(classFormat, Constants.SERVICE_CLASS))
+ .addCondition(String.format(nameFormat, Constants.SERVICE_NAME))
+ .addCondition(String.format(statusFormat))
+ .addVariable("$entry","$resource/Profile/AccessPoint/RunningInstanceInterfaces/Endpoint")
+ .addCondition(String.format(containsFormat, Constants.SERVICE_ENTRY_NAME))
+ .setResult("$entry/text()");
+ }
+
+ private static SimpleQuery queryForProxy(){
+ return ICFactory.queryFor(ServiceEndpoint.class)
+ .addCondition(String.format(serviceEndpointCategoryFormat, Constants.SERVICE_CLASS))
+ .addCondition(String.format(serviceEndpointNameFormat, Constants.SERVICE_NAME))
+ .addCondition(String.format(serviceEndpointstatusFormat))
+ .addVariable("$entry","$resource/Profile/AccessPoint/Interface/Endpoint")
+ .addCondition(String.format(containsFormat, Constants.SERVICE_ENTRY_NAME))
+ .setResult("$entry/text()");
+ }
+
+
+ protected static List getAddresses(){
+ List addresses = new ArrayList<>();
+
+ try {
+ SimpleQuery proxyQuery = queryForProxy();
+ addresses = ICFactory.client().submit(proxyQuery);
+ if(addresses==null || addresses.isEmpty()){
+ throw new Exception("No ResourceRegistry Proxy Found");
+ }
+ } catch (Exception e) {
+ logger.debug("{}. Looking for RunningInstance.", e.getMessage());
+ SimpleQuery serviceQuery = queryForService();
+ addresses = ICFactory.client().submit(serviceQuery);
+ }
+
+ return addresses;
+ }
+
+
+ public static ResourceRegistryContextClient create(){
+ if(FORCED_URL!=null){
+ return new ResourceRegistryContextClientImpl(FORCED_URL);
+ }
+
+ String key = null;
+ if (SecurityTokenProvider.instance.get() == null) {
+ if (ScopeProvider.instance.get() == null) {
+ throw new RuntimeException(
+ "Null Token and Scope. Please set your token first.");
+ }
+ key = ScopeProvider.instance.get();
+ } else {
+ key = SecurityTokenProvider.instance.get();
+ }
+
+ ResourceRegistryContextClient client = clients.get(key);
+
+ if(client==null){
+
+ List addresses = getAddresses();
+
+ if(addresses==null || addresses.isEmpty()){
+ String error = String.format("No %s:%s found in the current context", Constants.SERVICE_CLASS, Constants.SERVICE_NAME);
+ throw new RuntimeException(error);
+ }
+
+ Random random = new Random();
+ int index = random.nextInt(addresses.size());
+
+ client = new ResourceRegistryContextClientImpl(addresses.get(index));
+
+ }
+
+ return client;
+ }
+
+}
diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientImpl.java
new file mode 100644
index 0000000..25c8785
--- /dev/null
+++ b/src/main/java/org/gcube/informationsystem/resourceregistry/client/ResourceRegistryContextClientImpl.java
@@ -0,0 +1,200 @@
+package org.gcube.informationsystem.resourceregistry.client;
+
+import java.io.StringWriter;
+import java.net.MalformedURLException;
+import java.util.UUID;
+
+import org.gcube.informationsystem.impl.utils.ISMapper;
+import org.gcube.informationsystem.model.entity.Context;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextAlreadyPresentException;
+import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException;
+import org.gcube.informationsystem.resourceregistry.api.rest.ContextPath;
+import org.gcube.informationsystem.resourceregistry.api.rest.httputils.HTTPCall;
+import org.gcube.informationsystem.resourceregistry.api.rest.httputils.HTTPCall.HTTPMETHOD;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Luca Frosini (ISTI - CNR)
+ */
+public class ResourceRegistryContextClientImpl implements ResourceRegistryContextClient {
+
+ private static final Logger logger = LoggerFactory.getLogger(ResourceRegistryContextClientImpl.class);
+
+ public static final String PATH_SEPARATOR = "/";
+
+ protected final String address;
+ protected HTTPCall httpCall;
+
+ public ResourceRegistryContextClientImpl(String address) {
+ this.address = address;
+
+ }
+
+ private HTTPCall getHTTPCall() throws MalformedURLException {
+ if (httpCall == null) {
+ httpCall = new HTTPCall(address, ResourceRegistryContextClient.class.getSimpleName());
+ }
+ return httpCall;
+ }
+
+
+ @Override
+ public Context create(Context context) throws ContextAlreadyPresentException, ResourceRegistryException {
+ try {
+ String contextString = ISMapper.marshal(context);
+ String res = create(contextString);
+ return ISMapper.unmarshal(Context.class, res);
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String create(String context) throws ContextAlreadyPresentException, ResourceRegistryException {
+ try {
+ logger.trace("Going to create: {}", context);
+ StringWriter stringWriter = new StringWriter();
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(ContextPath.CONTEXT_PATH_PART);
+
+ HTTPCall httpCall = getHTTPCall();
+ String c = httpCall.call(String.class, stringWriter.toString(), HTTPMETHOD.PUT, context);
+
+ logger.trace("{} successfully created", c);
+ return c;
+
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ @Override
+ public Context read(Context context) throws ContextNotFoundException, ResourceRegistryException {
+ return read(context.getHeader().getUUID());
+ }
+
+ @Override
+ public Context read(UUID uuid) throws ContextNotFoundException, ResourceRegistryException {
+ try {
+ String res = read(uuid.toString());
+ return ISMapper.unmarshal(Context.class, res);
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String read(String uuid) throws ContextNotFoundException, ResourceRegistryException {
+ try {
+ logger.trace("Going to read {} with UUID {}", Context.NAME);
+ StringWriter stringWriter = new StringWriter();
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(ContextPath.CONTEXT_PATH_PART);
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(uuid);
+
+ HTTPCall httpCall = getHTTPCall();
+ String c = httpCall.call(String.class, stringWriter.toString(), HTTPMETHOD.GET);
+
+ logger.debug("Got {} is {}", Context.NAME, c);
+ return c;
+
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Context update(Context context) throws ContextAlreadyPresentException, ResourceRegistryException {
+ try {
+ String contextString = ISMapper.marshal(context);
+ String res = update(contextString);
+ return ISMapper.unmarshal(Context.class, res);
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Updating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Updating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String update(String context) throws ContextAlreadyPresentException, ResourceRegistryException {
+ try {
+ logger.trace("Going to update: {}", context);
+ StringWriter stringWriter = new StringWriter();
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(ContextPath.CONTEXT_PATH_PART);
+
+ HTTPCall httpCall = getHTTPCall();
+ String c = httpCall.call(String.class, stringWriter.toString(), HTTPMETHOD.POST, context);
+
+ logger.trace("{} successfully updated", c);
+ return c;
+
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean delete(Context context) throws ContextNotFoundException, ResourceRegistryException {
+ return delete(context.getHeader().getUUID());
+ }
+
+ @Override
+ public boolean delete(UUID uuid) throws ContextNotFoundException, ResourceRegistryException {
+ return delete(uuid.toString());
+ }
+
+ @Override
+ public boolean delete(String uuid) throws ContextNotFoundException, ResourceRegistryException {
+ try {
+ logger.trace("Going to read {} with UUID {}", Context.NAME);
+ StringWriter stringWriter = new StringWriter();
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(ContextPath.CONTEXT_PATH_PART);
+ stringWriter.append(PATH_SEPARATOR);
+ stringWriter.append(uuid);
+
+ HTTPCall httpCall = getHTTPCall();
+ boolean deleted = httpCall.call(Boolean.class, stringWriter.toString(), HTTPMETHOD.DELETE);
+
+ logger.info("{} with UUID {} {}", Context.NAME, uuid,
+ deleted ? " successfully deleted" : "was NOT deleted");
+ return deleted;
+ } catch (ResourceRegistryException e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw e;
+ } catch (Exception e) {
+ // logger.trace("Error Creating {}", facet, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+
+}
diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..f90657e
--- /dev/null
+++ b/src/test/resources/logback-test.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file