From d05db9259739f61e95ff7b553b69581789551cb7 Mon Sep 17 00:00:00 2001 From: Fabio Sinibaldi Date: Thu, 22 Sep 2022 11:15:08 +0200 Subject: [PATCH] Ticket #23894 : client to expose relationship management methods --- .../client/DefaultDocumentsClient.java | 100 +++++++++++++++++- .../clients/ProfiledDocumentsTest.java | 40 +++++++ .../model/rest/CreateRelationshipRequest.java | 17 +++ .../model/rest/DeleteRelationshipRequest.java | 11 ++ .../common/rest/InterfaceConstants.java | 4 +- .../geoportal/common/rest/Projects.java | 15 ++- .../service/rest/ProfiledDocuments.java | 7 +- 7 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java create mode 100644 geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java diff --git a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/DefaultDocumentsClient.java b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/DefaultDocumentsClient.java index 6d3b9ad..070f9b1 100644 --- a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/DefaultDocumentsClient.java +++ b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/DefaultDocumentsClient.java @@ -9,9 +9,8 @@ import org.gcube.application.geoportal.common.faults.InvalidRequestException; import org.gcube.application.geoportal.common.model.document.Project; import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.document.access.Access; -import org.gcube.application.geoportal.common.model.rest.QueryRequest; -import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; -import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.*; import org.gcube.application.geoportal.common.rest.InterfaceConstants; import org.gcube.application.geoportal.common.rest.Projects; import org.gcube.common.clients.Call; @@ -23,6 +22,7 @@ import javax.ws.rs.core.MediaType; import java.io.IOException; import java.rmi.RemoteException; import java.util.Iterator; +import java.util.List; @RequiredArgsConstructor @Slf4j @@ -280,7 +280,7 @@ public class DefaultDocumentsClient implements Projects { @Override public T updateDocument(String id, Document updatedDocument) throws RemoteException { try { - log.debug("Updateing {} [useCaseDescriptor {} , class {}] with ", + log.debug("Updating {} [useCaseDescriptor {} , class {}] with ", id, profileID,getManagedClass(),updatedDocument); Call call = endpoint -> { return ResponseCommons.check(endpoint.path(profileID).path(id). @@ -299,5 +299,95 @@ public class DefaultDocumentsClient implements Projects { } } - + @Override + public Project setRelation(CreateRelationshipRequest request) throws RemoteException { + try { + log.debug("Setting relationship {}:{} --{}--> {}:{}", + profileID, request.getProjectId(), request.getRelationshipId(), + request.getTargetUCD(),request.getTargetId()); + Call call = endpoint -> { + return ResponseCommons.check(endpoint.path(profileID). + path(InterfaceConstants.Methods.RELATIONSHIP). + path(request.getRelationshipId()). + queryParam(InterfaceConstants.Parameters.TARGET_ID,request.getTargetId()). + queryParam(InterfaceConstants.Parameters.TARGET_UCD,request.getTargetUCD()). + request(MediaType.APPLICATION_JSON). + put(Entity.entity(null, MediaType.APPLICATION_JSON)),getManagedClass()); + }; + T toReturn=delegate.make(call); + log.info("Set relationship {}:{} --{}--> {}:{}", + profileID, request.getProjectId(), request.getRelationshipId(), + request.getTargetUCD(),request.getTargetId()); + return toReturn; + }catch(RemoteException e){ + log.error("Unexpected error ",e); + throw e; + }catch(Exception e){ + log.error("Unexpected error ",e); + throw new RemoteException("Unexpected Error", e); + } + } + + @Override + public Project deleteRelation(DeleteRelationshipRequest request) throws RemoteException { + try { + log.debug("Deleting relationship {}:{} --{}--> {}:{}", + profileID, request.getProjectId(), request.getRelationshipId(), + request.getTargetUCD(),request.getTargetId()); + Call call = endpoint -> { + return ResponseCommons.check(endpoint.path(profileID). + path(InterfaceConstants.Methods.RELATIONSHIP). + path(request.getRelationshipId()). + queryParam(InterfaceConstants.Parameters.TARGET_ID,request.getTargetId()). + queryParam(InterfaceConstants.Parameters.TARGET_UCD,request.getTargetUCD()). + request(MediaType.APPLICATION_JSON). + delete(),getManagedClass()); + }; + T toReturn=delegate.make(call); + log.info("Deleted relationship {}:{} --{}--> {}:{}", + profileID, request.getProjectId(), request.getRelationshipId(), + request.getTargetUCD(),request.getTargetId()); + return toReturn; + }catch(RemoteException e){ + log.error("Unexpected error ",e); + throw e; + }catch(Exception e){ + log.error("Unexpected error ",e); + throw new RemoteException("Unexpected Error", e); + } + } + + @Override + public Iterator getRelationshipChain(String id, String relationId) throws RemoteException { + return getRelationshipChain(id,relationId,null); + } + + @Override + public Iterator getRelationshipChain(String id, String relationId, Boolean deep) throws RemoteException { + try { + log.debug("Get relationship chain ID {} for {} [useCaseDescriptor {} , class {}]", + relationId, id, profileID,getManagedClass()); + Call> call = endpoint -> { + + WebTarget target = endpoint.path(profileID). + path(InterfaceConstants.Methods.RELATIONSHIP). + path(id). + path(relationId); + + if(deep!=null) target = target.queryParam(InterfaceConstants.Parameters.DEEP,deep); + + String jsonChain = ResponseCommons.check(target.request(MediaType.APPLICATION_JSON). + get(),String.class); + + return Serialization.readCollection(jsonChain,RelationshipNavigationObject.class); + }; + return delegate.make(call); + }catch(RemoteException e){ + log.error("Unexpected error ",e); + throw e; + }catch(Exception e){ + log.error("Unexpected error ",e); + throw new RemoteException("Unexpected Error", e); + } + } } diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java index 26e4de8..de1f633 100644 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java @@ -7,6 +7,9 @@ import org.gcube.application.geoportal.client.DefaultDocumentsClient; import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.common.model.document.Project; import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest; +import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.rest.Projects; import org.gcube.application.geoportal.common.utils.tests.GCubeTest; @@ -15,6 +18,7 @@ import sun.net.www.content.text.Generic; import java.rmi.RemoteException; import java.time.LocalDateTime; +import java.util.Iterator; import java.util.concurrent.atomic.AtomicLong; import static junit.framework.TestCase.assertTrue; @@ -86,5 +90,41 @@ public class ProfiledDocumentsTest> exte }); } + @Test + public void testRelationships() throws Exception{ + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + Project source = client.createNew(new Document().append("field","value")); + Project target = client.createNew(new Document().append("field2","value")); + + String relId="associate"; + + + Project linkedSource = client.setRelation( + new CreateRelationshipRequest(source.getId(),relId, + target.getId(), null)); + + assumeTrue(linkedSource.getRelationships()!=null); + assumeTrue(!linkedSource.getRelationships().isEmpty()); + assumeTrue(linkedSource.getRelationships().get(0).getRelationshipName().equals(relId)); + assumeTrue(linkedSource.getRelationships().get(0).getTargetID().equals(target.getId())); + assumeTrue(linkedSource.getRelationships().get(0).getTargetUCD().equals(target.getProfileID())); + + Iterator it = client.getRelationshipChain(source.getId(),relId,true); + System.out.println("Scanning rel .."); + it.forEachRemaining(r -> { + System.out.println(r.getTarget().getId()); + System.out.println("Children size : "+r.getChildren().size()); + }); + + + Project unLinkedSource = client.deleteRelation( + new DeleteRelationshipRequest(source.getId(),relId, + target.getId(),null)); + + + assumeTrue(unLinkedSource.getRelationships()==null || unLinkedSource.getRelationships().isEmpty()); + + } } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java new file mode 100644 index 0000000..96d5303 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java @@ -0,0 +1,17 @@ +package org.gcube.application.geoportal.common.model.rest; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CreateRelationshipRequest { + + private String projectId; + private String relationshipId; + private String targetId; + private String targetUCD; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java new file mode 100644 index 0000000..96377d8 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java @@ -0,0 +1,11 @@ +package org.gcube.application.geoportal.common.model.rest; + +public class DeleteRelationshipRequest extends CreateRelationshipRequest{ + + public DeleteRelationshipRequest(String projectId, String relationshipId, String targetId, String targetUCD) { + super(projectId, relationshipId, targetId, targetUCD); + } + + public DeleteRelationshipRequest() { + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java index fe0983b..0ffa144 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java @@ -43,8 +43,8 @@ public class InterfaceConstants { public static final String RELATIONSHIP_ID="relationship_id"; public static final String DEEP="deep"; - public static final String TARGET_UCD="target_id"; - public static final String TARGET_ID="target_ucd"; + public static final String TARGET_UCD="target_ucd"; + public static final String TARGET_ID="target_id"; } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java index c09faf5..c195ef1 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java @@ -5,12 +5,12 @@ import org.gcube.application.geoportal.common.faults.InvalidRequestException; import org.gcube.application.geoportal.common.model.document.Project; import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.document.access.Access; -import org.gcube.application.geoportal.common.model.rest.QueryRequest; -import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; -import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.*; import java.rmi.RemoteException; import java.util.Iterator; +import java.util.List; public interface Projects

{ @@ -43,4 +43,13 @@ public interface Projects

{ public P forceUnlock(String id) throws RemoteException; public P setAccessPolicy(String id, Access toSet) throws RemoteException; + + // Relationships + public Project setRelation(CreateRelationshipRequest request)throws RemoteException; + + public Project deleteRelation(DeleteRelationshipRequest request)throws RemoteException; + + public Iterator getRelationshipChain(String id, String relationId, Boolean deep) throws RemoteException; + + public Iterator getRelationshipChain(String id, String relationId) throws RemoteException; } diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java index fc91570..d4ca7c3 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java @@ -288,7 +288,12 @@ public class ProfiledDocuments { protected Project run() throws Exception, WebApplicationException { log.info("Set relation from Project ({} : {}) [{}]-> ({} : {})", manager.getUseCaseDescriptor().getId(), id,relationshipId,targetUCD,targetId); - return manager.setRelation(id,relationshipId,targetUCD,targetId); + String toUseTargetUCD=targetUCD; + if(toUseTargetUCD==null || toUseTargetUCD.isEmpty()) { + log.debug("Target UCD is null, forcing same UCD () as source ",manager.getUseCaseDescriptor().getId()); + toUseTargetUCD = manager.getUseCaseDescriptor().getId(); + } + return manager.setRelation(id,relationshipId,toUseTargetUCD,targetId); } }.execute().getResult(); }