resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SharingManager.java

218 lines
9.0 KiB
Java
Raw Normal View History

package org.gcube.informationsystem.resourceregistry.rest;
2021-01-25 17:38:19 +01:00
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
2021-02-16 17:17:40 +01:00
import javax.ws.rs.DefaultValue;
2021-01-24 23:33:06 +01:00
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
2021-07-01 12:13:23 +02:00
import javax.ws.rs.Produces;
2021-01-24 23:33:06 +01:00
import javax.ws.rs.QueryParam;
2021-01-25 17:38:19 +01:00
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
import org.gcube.common.authorization.library.provider.CalledMethodProvider;
2021-01-25 17:38:19 +01:00
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
2021-10-25 11:40:47 +02:00
import org.gcube.informationsystem.contexts.reference.entities.Context;
2021-01-25 17:38:19 +01:00
import org.gcube.informationsystem.model.reference.properties.Header;
2021-07-01 12:13:23 +02:00
import org.gcube.informationsystem.resourceregistry.ResourceInitializer;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException;
2021-10-25 11:00:54 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource.ResourceNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException;
import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath;
import org.gcube.informationsystem.resourceregistry.api.rest.SharingPath;
2021-01-24 23:33:06 +01:00
import org.gcube.informationsystem.resourceregistry.api.rest.SharingPath.SharingOperation;
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
2021-02-05 17:50:16 +01:00
import org.gcube.informationsystem.resourceregistry.instances.model.ERManagement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2021-01-20 17:08:59 +01:00
/**
* @author Luca Frosini (ISTI - CNR)
*/
@Path(SharingPath.SHARING_PATH_PART)
public class SharingManager {
2020-11-24 15:39:09 +01:00
private static Logger logger = LoggerFactory.getLogger(SharingManager.class);
2020-11-24 15:39:09 +01:00
public SharingManager() {
ContextUtility.getHierarchicalMode().set(false);
ContextUtility.getIncludeInstanceContexts().set(false);
}
2021-01-25 17:38:19 +01:00
protected String serializeAffectedInstaces(ObjectMapper objectMapper, Map<UUID,JsonNode> affectedInstances) throws ResourceRegistryException {
ArrayNode arrayNode = objectMapper.createArrayNode();
for(JsonNode jsonNode : affectedInstances.values()) {
arrayNode.add(jsonNode);
}
try {
return objectMapper.writeValueAsString(arrayNode);
} catch (JsonProcessingException e) {
throw new ResourceRegistryException(e);
}
}
2021-01-24 23:33:06 +01:00
/**
* Add/Remove to/from the context identified by CONTEXT_UUID path parameter the list of instances contained in the body of the request.
* The the body is the following
*
* [
* {"@class" : "HostingNode", header : { "uuid" : "16032d09-3823-444e-a1ff-a67de4f350a8"}},
* {"@class" : "Hosts", header : { "uuid" : "97ab8a6b-6b1b-4868-b8fc-ba48d0439ba9"}},
* {"@class" : "EService", header : { "uuid" : "d3b1a29b-aa70-4a5a-be83-361a4209dd3e"}}
* ]
*
*
* Each instance is managed without considering the propagation constraint of relations.
*
2021-07-01 12:13:23 +02:00
* POST /sharing/contexts/{CONTEXT_UUID}?operation=PUT(ADD|REMOVE)&[dryRun=true]
2021-01-24 23:33:06 +01:00
*
* e.g
2021-02-16 17:17:40 +01:00
* POST /resource-registry/contexts/67062c11-9c3a-4906-870d-7df6a43408b0?operation=ADD&dryRun=true
* POST /resource-registry/contexts/67062c11-9c3a-4906-870d-7df6a43408b0?operation=REMOVE
2021-01-24 23:33:06 +01:00
*
* where
* 67062c11-9c3a-4906-870d-7df6a43408b0/ is the Context UUID
*
2021-01-25 17:38:19 +01:00
* The body contains the list of instances to add/remove to/from the context identified by CONTEXT_UUID
2021-01-24 23:33:06 +01:00
*
2020-11-24 15:39:09 +01:00
*/
// @POST
2021-07-01 12:13:23 +02:00
// @Path("/{" + SharingPath.CONTEXTS_PATH_PART + "/{" + AccessPath.CONTEXT_UUID_PATH_PARAM + "}")
public String addRemoveNoPropagationConstraint(
2021-01-24 23:33:06 +01:00
@PathParam(AccessPath.CONTEXT_UUID_PATH_PARAM) String contextId,
@QueryParam(SharingPath.OPERATION_QUERY_PARAMETER) SharingOperation operation,
2021-02-16 17:17:40 +01:00
@QueryParam(SharingPath.DRY_RUN_QUERY_PARAMETER) @DefaultValue("false") Boolean dryRun,
2021-01-24 23:33:06 +01:00
String body)
2021-02-16 17:17:40 +01:00
throws SchemaViolationException, ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
2020-11-24 15:39:09 +01:00
2021-01-25 17:38:19 +01:00
try {
StringBuffer calledMethod = new StringBuffer();
if(dryRun==null) {
dryRun = false;
}
if(dryRun) {
calledMethod.append("dryRun");
}
if(operation == SharingOperation.ADD) {
logger.info("Requested {} {} to {} with UUID {}", dryRun? "a dry run for adding": "to add", body, Context.NAME, contextId);
calledMethod.append("AddToContext");
}else {
logger.info("Requested {} {} from {} with UUID {}", dryRun? "a dry run for removing": "to remove", body, Context.NAME, contextId);
calledMethod.append("RemoveFromContext");
}
calledMethod.append("NoPropagationConstraint");
CalledMethodProvider.instance.set(calledMethod.toString());
ObjectMapper objectMapper = new ObjectMapper();
ArrayNode arrayNode = (ArrayNode) objectMapper.readTree(body);
Map<UUID,JsonNode> expectedInstances = new HashMap<>();
for(JsonNode node : arrayNode) {
@SuppressWarnings("unused")
2021-01-25 17:38:19 +01:00
String type = node.get(Element.CLASS_PROPERTY).asText();
String instanceId = node.get(IdentifiableElement.HEADER_PROPERTY).get(Header.UUID_PROPERTY).asText();
UUID uuid = UUID.fromString(instanceId);
expectedInstances.put(uuid, node);
2021-01-25 17:38:19 +01:00
}
@SuppressWarnings("unused")
UUID contextUUID = UUID.fromString(contextId);
Map<UUID,JsonNode> affectedInstances = null;
if(operation == SharingOperation.ADD) {
// affectedInstances = ERManagementUtility.addToContextNoPropagationConstraint(expectedInstances, contextUUID, dryRun);
}else {
// affectedInstances = ERManagementUtility.removeFromContextNoPropagationConstraint(expectedInstances, contextUUID, dryRun);
}
2021-01-25 17:38:19 +01:00
return serializeAffectedInstaces(objectMapper, affectedInstances);
}catch (ResourceRegistryException e) {
throw e;
}catch (Exception e) {
throw new ResourceRegistryException(e);
2021-01-24 23:33:06 +01:00
}
}
/**
2021-01-25 17:38:19 +01:00
* Add/Remove an instance from context. The operation can have a cascade effect due to propagation constraint.
2021-01-24 23:33:06 +01:00
*
2021-01-25 17:38:19 +01:00
* Return the list of instances affected by an add/remove to/from context the target instance identified by UUID path parameter
2021-01-24 23:33:06 +01:00
*
2021-02-16 17:17:40 +01:00
* POST /sharing/contexts/{CONTEXT_UUID}/{TYPE_NAME}/{UUID}?operation=(ADD|REMOVE)&dryRun=true]
2021-01-24 23:33:06 +01:00
*
* e.g
2021-01-25 17:38:19 +01:00
* POST /resource-registry/sharing/contexts/67062c11-9c3a-4906-870d-7df6a43408b0/HostingNode/16032d09-3823-444e-a1ff-a67de4f350a8?operation=ADD&dryRun=true
* POST /resource-registry/sharing/contexts/67062c11-9c3a-4906-870d-7df6a43408b0/HostingNode/16032d09-3823-444e-a1ff-a67de4f350a8?operation=REMOVE&dryRun=true
2021-01-24 23:33:06 +01:00
*
* where
* 67062c11-9c3a-4906-870d-7df6a43408b0 is the Context UUID and
* 16032d09-3823-444e-a1ff-a67de4f350a8 is the HostingNode UUID
*
*/
2021-01-25 17:38:19 +01:00
@POST
2021-07-01 12:13:23 +02:00
@Path("/" + SharingPath.CONTEXTS_PATH_PART + "/{" + AccessPath.CONTEXT_UUID_PATH_PARAM + "}/"
+ "{" + AccessPath.TYPE_PATH_PARAM + "}" + "/{" + AccessPath.UUID_PATH_PARAM + "}")
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
2021-01-25 17:38:19 +01:00
public String addRemove(
2021-01-24 23:33:06 +01:00
@PathParam(AccessPath.CONTEXT_UUID_PATH_PARAM) String contextId,
@PathParam(AccessPath.TYPE_PATH_PARAM) String type,
2020-11-24 15:39:09 +01:00
@PathParam(AccessPath.UUID_PATH_PARAM) String instanceId,
2021-01-25 17:38:19 +01:00
@QueryParam(SharingPath.OPERATION_QUERY_PARAMETER) SharingOperation operation,
2021-02-16 17:17:40 +01:00
@QueryParam(SharingPath.DRY_RUN_QUERY_PARAMETER) @DefaultValue("false") Boolean dryRun)
throws SchemaViolationException, ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
2021-01-25 17:38:19 +01:00
StringBuffer calledMethod = new StringBuffer();
if(dryRun==null) {
dryRun = false;
}
if(dryRun) {
calledMethod.append("dryRun");
}
2021-01-24 23:33:06 +01:00
if(operation == SharingOperation.ADD) {
2021-01-25 17:38:19 +01:00
logger.info("Requested {} {} with UUID {} to {} with UUID {}", dryRun? "a dry run for adding": "to add", type, instanceId, Context.NAME, contextId);
calledMethod.append("AddToContext");
2021-01-24 23:33:06 +01:00
}else {
2021-01-25 17:38:19 +01:00
logger.info("Requested {} {} with UUID {} from {} with UUID {}", dryRun? "a dry run for removing": "to remove", type, instanceId, Context.NAME, contextId);
calledMethod.append("RemoveFromContext");
2021-01-24 23:33:06 +01:00
}
2021-01-25 17:38:19 +01:00
CalledMethodProvider.instance.set(calledMethod.toString());
2020-11-24 15:39:09 +01:00
2021-02-22 16:36:19 +01:00
ElementManagement<?,?> elementManagement = ElementManagementUtility.getERManagement(type);
2021-01-24 23:33:06 +01:00
elementManagement.setUUID(UUID.fromString(instanceId));
elementManagement.setDryRun(dryRun);
2021-01-25 17:38:19 +01:00
UUID contextUUID = UUID.fromString(contextId);
2021-03-05 14:41:02 +01:00
2021-01-24 23:33:06 +01:00
if(operation == SharingOperation.ADD) {
2021-03-05 14:41:02 +01:00
((ERManagement) elementManagement).addToContext(contextUUID);
2021-01-24 23:33:06 +01:00
}else {
2021-03-05 14:41:02 +01:00
((ERManagement) elementManagement).removeFromContext(contextUUID);
2021-01-24 23:33:06 +01:00
}
2021-01-25 17:38:19 +01:00
try {
2021-03-05 14:41:02 +01:00
ObjectMapper objectMapper = new ObjectMapper();
return serializeAffectedInstaces(objectMapper, elementManagement.getAffectedInstances());
2021-01-25 17:38:19 +01:00
} catch (Exception e) {
throw new ResourceRegistryException(e);
}
}
2020-11-24 15:39:09 +01:00
}