diff --git a/deploys/distributed/.gitignore b/deploys/distributed/.gitignore deleted file mode 100644 index e0e2d93930..0000000000 --- a/deploys/distributed/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ldap/* \ No newline at end of file diff --git a/deploys/distributed/central/docker-compose-dev.yaml b/deploys/distributed/central/docker-compose-dev.yaml index ccf3ba1cb9..8373d75038 100644 --- a/deploys/distributed/central/docker-compose-dev.yaml +++ b/deploys/distributed/central/docker-compose-dev.yaml @@ -1,6 +1,6 @@ services: zoo: - image: docker.io/zookeeper:3.9.2 + image: docker.io/zookeeper:3.9-jre-17 restart: unless-stopped ports: - "2182:2181" @@ -57,10 +57,11 @@ services: - LDAP_ADMIN_PASSWORD=roda - LDAP_EXTRA_SCHEMAS=cosine,inetorgperson,nis,pbkdf2 volumes: - - ./ldap/ldif/pbkdf2.ldif:/opt/bitnami/openldap/etc/schema/pbkdf2.ldif + - ldap_data:/opt/bitnami/openldap/etc/schema/pbkdf2.ldif volumes: zookeeper_data: zookeeper_datalog: solr_data: clam_data: siegfried_data: + ldap_data: \ No newline at end of file diff --git a/deploys/distributed/local/docker-compose-dev.yaml b/deploys/distributed/local/docker-compose-dev.yaml index 08871b2731..4a6ed5b5e1 100644 --- a/deploys/distributed/local/docker-compose-dev.yaml +++ b/deploys/distributed/local/docker-compose-dev.yaml @@ -1,6 +1,6 @@ services: zoo: - image: docker.io/zookeeper:3.9.2 + image: docker.io/zookeeper:3.9-jre-17 restart: unless-stopped ports: - "2181:2181" @@ -17,6 +17,7 @@ services: environment: ZK_HOST: zoo:2181 SOLR_HOST: localhost + SOLR_OPTS: "-Dsolr.environment=dev,label=DEV+ENV" depends_on: - zoo command: @@ -56,10 +57,11 @@ services: - LDAP_ADMIN_PASSWORD=roda - LDAP_EXTRA_SCHEMAS=cosine,inetorgperson,nis,pbkdf2 volumes: - - ./ldap/ldif/pbkdf2.ldif:/opt/bitnami/openldap/etc/schema/pbkdf2.ldif + - ldap_data:/opt/bitnami/openldap/etc/schema/pbkdf2.ldif volumes: zookeeper_data: zookeeper_datalog: solr_data: clam_data: siegfried_data: + ldap_data: diff --git a/deploys/standalone/docker-compose-dev.yaml b/deploys/standalone/docker-compose-dev.yaml index 8f9b9c4b36..8f706ceb99 100644 --- a/deploys/standalone/docker-compose-dev.yaml +++ b/deploys/standalone/docker-compose-dev.yaml @@ -10,7 +10,7 @@ services: - zookeeper_data:/data - zookeeper_datalog:/datalog solr: - image: docker.io/solr:9 + image: docker.io/solr:9.6.1 restart: unless-stopped ports: - "8983:8983" diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java index 84f70825e9..5d9a8d38e2 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java @@ -700,7 +700,10 @@ public String toString() { public static final String CONTROLLER_DISPOSAL_CONFIRMATION_ID_PARAM = "disposalConfirmationId"; public static final String CONTROLLER_DISTRIBUTED_INSTANCE_PARAM = RODA_OBJECT_DISTRIBUTED_INSTANCE; + public static final String CONTROLLER_DISTRIBUTED_INSTANCE_ID_PARAM = "distributedInstanceId"; + public static final String CONTROLLER_DISTRIBUTED_INSTANCE_STATUS_PARAM = "activate"; public static final String CONTROLLER_LOCAL_INSTANCE_PARAM = RODA_OBJECT_LOCAL_INSTANCE; + public static final String CONTROLLER_LOCAL_INSTANCE_ID_PARAM = "localInstanceId"; public static final String CONTROLLER_ACCESS_KEY_PARAM = RODA_OBJECT_ACCESS_KEY; public static final String CONTROLLER_ID_OBJECT_PARAM = "transferred_resource_uuid, transferred_resource_path, sip, transferred_resource_original_name"; diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AcquireLockTimeoutException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AcquireLockTimeoutException.java index 6de2c6a63a..927ca0e21d 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AcquireLockTimeoutException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AcquireLockTimeoutException.java @@ -7,7 +7,10 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class AcquireLockTimeoutException extends LockingException { + @Serial private static final long serialVersionUID = -3183093939393405726L; public AcquireLockTimeoutException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyExistsException.java index 892e83bdb0..dc2104ac86 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyExistsException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Luis Faria * */ public class AlreadyExistsException extends RODAException { + @Serial private static final long serialVersionUID = -6744205569453461540L; public AlreadyExistsException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyHasInstanceIdentifier.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyHasInstanceIdentifier.java index 6808e937b9..13c7d7686c 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyHasInstanceIdentifier.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/AlreadyHasInstanceIdentifier.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class AlreadyHasInstanceIdentifier extends RODAException { + @Serial private static final long serialVersionUID = -6744205569453461540L; public AlreadyHasInstanceIdentifier() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldAlreadyExistsException.java index a27d1d54e2..aed0626aa8 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldAlreadyExistsException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalHoldAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = -9204333449702855127L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldNotValidException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldNotValidException.java index c581f9b09c..7eceaf1e25 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldNotValidException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalHoldNotValidException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalHoldNotValidException extends GenericException { + @Serial private static final long serialVersionUID = 2413699496731974126L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleAlreadyExistsException.java index b7a5612198..783486afd6 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleAlreadyExistsException.java @@ -7,10 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalRuleAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = -4589782633937474385L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleNotValidException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleNotValidException.java index 0330f78781..7c62ee8ad2 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleNotValidException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalRuleNotValidException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalRuleNotValidException extends GenericException { + @Serial private static final long serialVersionUID = 2413699496731974126L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleAlreadyExistsException.java index a3b4822994..5ef9c7401d 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleAlreadyExistsException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalScheduleAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = -4589782633937474385L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleNotValidException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleNotValidException.java index 9d43637985..daa054abd5 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleNotValidException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/DisposalScheduleNotValidException.java @@ -7,10 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Tiago Fraga */ public class DisposalScheduleNotValidException extends GenericException { + @Serial private static final long serialVersionUID = 809098516488134186L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailAlreadyExistsException.java index c54121c1a9..fc2b5b7b43 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailAlreadyExistsException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that the specified email was is already used. * * @author Rui Castro */ public class EmailAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = 3392813159441368655L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailUnverifiedException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailUnverifiedException.java index 6eebcd2cdc..e99fc18838 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailUnverifiedException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/EmailUnverifiedException.java @@ -7,6 +7,8 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that was not possible to authenticate {@link User} because * it's email address is not verified. @@ -14,6 +16,7 @@ * @author Rui Castro */ public class EmailUnverifiedException extends AuthenticationDeniedException { + @Serial private static final long serialVersionUID = 4619089972230221210L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/GroupAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/GroupAlreadyExistsException.java index 8d73e58cc0..6d2a4fdac3 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/GroupAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/GroupAlreadyExistsException.java @@ -9,6 +9,8 @@ import org.roda.core.data.v2.user.Group; +import java.io.Serial; + /** * Thrown to indicate that a {@link Group} with the same name already exists * when a new one is trying to be created. @@ -17,6 +19,7 @@ */ public class GroupAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = 6493339963861919270L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IllegalOperationException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IllegalOperationException.java index fc7438f704..7e039794e2 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IllegalOperationException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IllegalOperationException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that the execution of some operation is not permited. * * @author Rui Castro */ public class IllegalOperationException extends RODAServiceException { + @Serial private static final long serialVersionUID = -8118340939329992654L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InactiveUserException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InactiveUserException.java index 687bcdb5fa..2bdbc87505 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InactiveUserException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InactiveUserException.java @@ -9,6 +9,8 @@ import org.roda.core.data.v2.user.User; +import java.io.Serial; + /** * Thrown to indicate that was not possible to authenticate {@link User} because * it is not active. @@ -16,6 +18,7 @@ * @author Rui Castro */ public class InactiveUserException extends AuthenticationDeniedException { + @Serial private static final long serialVersionUID = -1893919532523481577L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InstanceIdNotUpdated.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InstanceIdNotUpdated.java index 32bf7c7aee..cb959d910a 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InstanceIdNotUpdated.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InstanceIdNotUpdated.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Luis Faria * */ public class InstanceIdNotUpdated extends RODAException { + @Serial private static final long serialVersionUID = -1656013708463576500L; public InstanceIdNotUpdated() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidParameterException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidParameterException.java index 9861d8e593..a2ed84db4f 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidParameterException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidParameterException.java @@ -9,12 +9,15 @@ import org.roda.core.data.v2.jobs.PluginParameter; +import java.io.Serial; + /** * Thrown to indicate that a {@link PluginParameter} is wrong. * * @author Rui Castro */ public class InvalidParameterException extends RODAException { + @Serial private static final long serialVersionUID = 4040123614898012034L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidTokenException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidTokenException.java index f5d2179e0f..e9bbb53a39 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidTokenException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/InvalidTokenException.java @@ -7,14 +7,17 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** - * Thrown to indicate the the email confirmation token or password change token + * Thrown to indicate the email confirmation token or password change token * is invalid. A token can be invalid because is not the expected token or * because it already expired. * * @author Rui Castro */ public class InvalidTokenException extends RODAException { + @Serial private static final long serialVersionUID = -182450030953675819L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IsStillUpdatingException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IsStillUpdatingException.java index e051f24d3a..9a23d9bfe3 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IsStillUpdatingException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/IsStillUpdatingException.java @@ -7,8 +7,11 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class IsStillUpdatingException extends RODAException { + @Serial private static final long serialVersionUID = 7420264596411093449L; public IsStillUpdatingException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobAlreadyStartedException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobAlreadyStartedException.java index 4c81d3cc81..5493e75e28 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobAlreadyStartedException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobAlreadyStartedException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Hélder Silva * */ public class JobAlreadyStartedException extends JobException { + @Serial private static final long serialVersionUID = -6744205569453461540L; public JobAlreadyStartedException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobException.java index dd864b0077..0444037660 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobException.java @@ -7,7 +7,10 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class JobException extends RODAException { + @Serial private static final long serialVersionUID = 1893131595923947285L; public JobException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobInErrorException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobInErrorException.java index 1461691cb4..aa77f3ca45 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobInErrorException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobInErrorException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Hélder Silva * */ public class JobInErrorException extends JobException { + @Serial private static final long serialVersionUID = 668519344542236907L; public JobInErrorException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobIsStoppingException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobIsStoppingException.java index 425dc02ec6..a5a2c178d5 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobIsStoppingException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobIsStoppingException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Hélder Silva * */ public class JobIsStoppingException extends JobException { + @Serial private static final long serialVersionUID = 668519344542236907L; public JobIsStoppingException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobStateNotPendingException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobStateNotPendingException.java index 52f5b1d40d..0e39d4e3f3 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobStateNotPendingException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/JobStateNotPendingException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Shahzod Yusupov */ public class JobStateNotPendingException extends RODAException { + @Serial private static final long serialVersionUID = -829610996201922888L; public JobStateNotPendingException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LockingException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LockingException.java index c903eb3d57..403c42b0fd 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LockingException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LockingException.java @@ -7,7 +7,10 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class LockingException extends RODAException { + @Serial private static final long serialVersionUID = 8700288419110883827L; public LockingException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LogEntryJsonParseException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LogEntryJsonParseException.java index a5f8505494..cf3e10520f 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LogEntryJsonParseException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LogEntryJsonParseException.java @@ -7,8 +7,11 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class LogEntryJsonParseException extends RODAException { + @Serial private static final long serialVersionUID = -8336065269567551582L; private String filename; diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LoggerException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LoggerException.java index bc2a63c0fb..c192146265 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LoggerException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/LoggerException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that some error occurred in the Logger. * * @author Rui Castro */ public class LoggerException extends RODAException { + @Serial private static final long serialVersionUID = 9061875666831921195L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MarketException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MarketException.java index 19da916095..b57f8f9ee8 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MarketException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MarketException.java @@ -7,10 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Gabriel Barros */ public class MarketException extends RODAException { + @Serial private static final long serialVersionUID = 5663037203596674543L; public MarketException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MultipleGenericException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MultipleGenericException.java index 2b4b36df28..cf51b62866 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MultipleGenericException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/MultipleGenericException.java @@ -7,6 +7,7 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; import java.util.ArrayList; import java.util.List; @@ -15,6 +16,7 @@ * */ public class MultipleGenericException extends GenericException { + @Serial private static final long serialVersionUID = 3865896551745064851L; private transient List causes = new ArrayList<>(); @@ -41,9 +43,7 @@ public static MultipleGenericException build(List> li List causes = new ArrayList<>(); for (ReturnWithExceptions item : list) { - for (Exception e : item.getExceptions()) { - causes.add(e); - } + causes.addAll(item.getExceptions()); } return new MultipleGenericException(causes); diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotFoundException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotFoundException.java index 921826950c..a4af8d5001 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotFoundException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotFoundException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Luis Faria * */ public class NotFoundException extends RODAException { + @Serial private static final long serialVersionUID = -1656013708463576500L; public NotFoundException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotImplementedException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotImplementedException.java index 660c8fa871..c2bd445988 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotImplementedException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotImplementedException.java @@ -7,10 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Hélder Silva */ public class NotImplementedException extends RODAException { + @Serial private static final long serialVersionUID = -6744205569453461540L; public NotImplementedException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotLockableAtTheTimeException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotLockableAtTheTimeException.java index 749a6e9a1a..8c6aca50f7 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotLockableAtTheTimeException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotLockableAtTheTimeException.java @@ -7,7 +7,10 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class NotLockableAtTheTimeException extends LockingException { + @Serial private static final long serialVersionUID = 7257377928175910597L; public NotLockableAtTheTimeException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotSupportedException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotSupportedException.java index e7207b8d07..b5598633ce 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotSupportedException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotSupportedException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Luis Faria * */ public class NotSupportedException extends RODAException { + @Serial private static final long serialVersionUID = -1656013708463576500L; public NotSupportedException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotificationException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotificationException.java index 0a5555cfc2..f5f53413b5 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotificationException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/NotificationException.java @@ -7,8 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class NotificationException extends RODAException { + @Serial + private static final long serialVersionUID = -1007761117626340269L; + public NotificationException() { super(); } diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/ObserverException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/ObserverException.java index b99bf11474..24a52f1dc3 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/ObserverException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/ObserverException.java @@ -7,7 +7,10 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + public class ObserverException extends RODAException { + @Serial private static final long serialVersionUID = -1006839588088229886L; public ObserverException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAException.java index 7988a1bab6..e052c9cb26 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAException.java @@ -7,11 +7,14 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Luis Faria * */ public class RODAException extends Exception { + @Serial private static final long serialVersionUID = -1656013708463576500L; public RODAException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAServiceException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAServiceException.java index f624f47e56..d992538c30 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAServiceException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RODAServiceException.java @@ -7,6 +7,8 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown when something wrong happens inside a RODA service and the request * could not be complete. @@ -14,6 +16,7 @@ * @author Rui Castro */ public class RODAServiceException extends RODAException { + @Serial private static final long serialVersionUID = 4068129466745626125L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RequestNotValidException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RequestNotValidException.java index bb5a91e07a..a4f29303ef 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RequestNotValidException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RequestNotValidException.java @@ -7,12 +7,15 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * * @author Luis Faria * */ public class RequestNotValidException extends RODAException { + @Serial private static final long serialVersionUID = -2066738446256937178L; public RequestNotValidException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RetentionPeriodCalculationException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RetentionPeriodCalculationException.java index 63ca65bb17..2d634dc766 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RetentionPeriodCalculationException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RetentionPeriodCalculationException.java @@ -7,10 +7,13 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * @author Miguel Guimarães */ public class RetentionPeriodCalculationException extends RODAException { + @Serial private static final long serialVersionUID = -834809453076076692L; public RetentionPeriodCalculationException() { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RoleAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RoleAlreadyExistsException.java index 3c633687d3..d39c45f54e 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RoleAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/RoleAlreadyExistsException.java @@ -7,6 +7,8 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that a role with the same name already exists when a new * one is trying to be created. @@ -15,6 +17,7 @@ */ public class RoleAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = -6214944667650454428L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/UserAlreadyExistsException.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/UserAlreadyExistsException.java index 67f1684838..59583ec7a4 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/UserAlreadyExistsException.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/exceptions/UserAlreadyExistsException.java @@ -7,6 +7,8 @@ */ package org.roda.core.data.exceptions; +import java.io.Serial; + /** * Thrown to indicate that an User with the same name already exists when a new * one is trying to be created. @@ -15,6 +17,7 @@ */ public class UserAlreadyExistsException extends AlreadyExistsException { + @Serial private static final long serialVersionUID = 6493339963861919270L; /** diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/RODAInstance.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/RODAInstance.java index 1f140e2ed6..3382909522 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/RODAInstance.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/RODAInstance.java @@ -7,6 +7,7 @@ */ package org.roda.core.data.v2.synchronization; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; @@ -21,10 +22,10 @@ */ public abstract class RODAInstance implements Serializable, IsModelObject { private static final int VERSION = 1; + @Serial private static final long serialVersionUID = -3816835903133713036L; private String id; - private String name; private Date lastSynchronizationDate; diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateDistributedInstanceRequest.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateDistributedInstanceRequest.java similarity index 94% rename from roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateDistributedInstanceRequest.java rename to roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateDistributedInstanceRequest.java index 8aead1e839..59021cbc6b 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateDistributedInstanceRequest.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateDistributedInstanceRequest.java @@ -1,4 +1,4 @@ -package org.roda.core.data.v2.generics; +package org.roda.core.data.v2.synchronization.central; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateLocalInstanceRequest.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateLocalInstanceRequest.java similarity index 88% rename from roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateLocalInstanceRequest.java rename to roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateLocalInstanceRequest.java index c32447020f..6aee9637c7 100644 --- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/generics/CreateLocalInstanceRequest.java +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/CreateLocalInstanceRequest.java @@ -1,6 +1,4 @@ -package org.roda.core.data.v2.generics; - -import com.fasterxml.jackson.annotation.JsonInclude; +package org.roda.core.data.v2.synchronization.central; import java.io.Serial; import java.io.Serializable; @@ -8,7 +6,7 @@ /** * @author António Lindo */ -@JsonInclude(JsonInclude.Include.ALWAYS) + public class CreateLocalInstanceRequest implements Serializable { @Serial private static final long serialVersionUID = -2706255856347304025L; @@ -18,7 +16,7 @@ public class CreateLocalInstanceRequest implements Serializable { private String centralInstanceURL; public CreateLocalInstanceRequest() { - + // empty constructor } public CreateLocalInstanceRequest(String id, String accessKey, String centralInstanceURL) { diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/UpdateDistributedInstanceRequest.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/UpdateDistributedInstanceRequest.java new file mode 100644 index 0000000000..851248f538 --- /dev/null +++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/v2/synchronization/central/UpdateDistributedInstanceRequest.java @@ -0,0 +1,50 @@ +package org.roda.core.data.v2.synchronization.central; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author Miguel Guimarães + */ +public class UpdateDistributedInstanceRequest implements Serializable { + @Serial + private static final long serialVersionUID = 5597476107465354723L; + + private String id; + private String name; + private String description; + + public UpdateDistributedInstanceRequest() { + // empty constructor + } + + public UpdateDistributedInstanceRequest(String id, String name, String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/RESTClientUtility.java b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/RESTClientUtility.java index 9775741836..b22524cdad 100644 --- a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/RESTClientUtility.java +++ b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/RESTClientUtility.java @@ -78,6 +78,34 @@ public static T sendPostRequest(T element, Class ele } } + public static T sendPostRequestWithoutBody(Class elementClass, String url, String resource, + AccessToken accessToken) throws GenericException { + CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + HttpPost httpPost = new HttpPost(url + resource); + httpPost.addHeader("Authorization", "Bearer " + accessToken.getToken()); + httpPost.addHeader("content-type", "application/json"); + httpPost.addHeader("Accept", "application/json"); + + try { + HttpResponse response; + response = httpClient.execute(httpPost); + HttpEntity responseEntity = response.getEntity(); + int responseStatusCode = response.getStatusLine().getStatusCode(); + + if (responseStatusCode == 201) { + if (elementClass != null) { + return JsonUtils.getObjectFromJson(responseEntity.getContent(), elementClass); + } else { + return null; + } + } else { + throw new GenericException("POST request response status code: " + responseStatusCode); + } + } catch (IOException e) { + throw new GenericException("Error sending POST request", e); + } + } + public static T sendPostRequest(Object element, Class elementClass, String url, String resource, AccessToken accessToken) throws GenericException { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); diff --git a/roda-core/roda-core/src/main/java/org/roda/core/RodaBootstrap.java b/roda-core/roda-core/src/main/java/org/roda/core/RodaBootstrap.java index 57e23d3923..8b6ef87be9 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/RodaBootstrap.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/RodaBootstrap.java @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; /** - * This class is responsible for bootstrapping the RODA application tha needs to + * This class is responsible for bootstrapping the RODA application that needs to * be done before starting the spring boot application. It initializes the * configuration manager, directory initializer, and plugin manager. It also * sets the context class loader for the current thread. diff --git a/roda-core/roda-core/src/main/java/org/roda/core/common/SyncUtils.java b/roda-core/roda-core/src/main/java/org/roda/core/common/SyncUtils.java index bfd081ed1f..60aa6866ee 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/common/SyncUtils.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/common/SyncUtils.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -24,8 +23,7 @@ import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.StringEntity; +import org.apache.http.client.methods.HttpPatch; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; @@ -68,6 +66,10 @@ public class SyncUtils { private static final Logger LOGGER = LoggerFactory.getLogger(SyncUtils.class); + private SyncUtils() { + // private constructor + } + /** * Central Bundle methods */ @@ -141,7 +143,7 @@ private static boolean createCentralPackage(StoragePath containerPath, public static Path getBundleWorkingDirectory(String instanceId) throws IOException { Path tempDirectory = Files.createTempDirectory(RodaCoreFactory.getWorkingDirectory(), RodaConstants.CORE_SYNCHRONIZATION_FOLDER + instanceId); - LOGGER.debug("Creating " + tempDirectory); + LOGGER.debug("Creating temporary directory {}", tempDirectory); return tempDirectory; } @@ -183,7 +185,7 @@ public static Path compress(Path workingDir, String filename) throws NotFoundException, GenericException, IOException { Path outcomePath = RodaCoreFactory.getSynchronizationDirectoryPath() .resolve(RodaConstants.CORE_SYNCHRONIZATION_OUTCOME_FOLDER).resolve(filename); - LOGGER.debug("Compress files to " + outcomePath); + LOGGER.debug("Compress files to {}", outcomePath); if (FSUtils.exists(outcomePath)) { FSUtils.deletePath(outcomePath); @@ -193,7 +195,7 @@ public static Path compress(Path workingDir, String filename) } public static void extract(Path workingDir, Path incomingPath) throws IOException { - LOGGER.debug("Extracting files to " + workingDir); + LOGGER.debug("Extracting files to {}", workingDir); ZipUtility.extractFilesFromZIP(incomingPath.toFile(), workingDir.toFile(), true); } @@ -244,8 +246,8 @@ public String getMediaType() { public static DistributedInstance requestInstanceStatus(LocalInstance localInstance) throws GenericException { try { AccessToken accessToken = TokenManager.getInstance().getAccessToken(localInstance); - String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + "status" - + RodaConstants.API_SEP + localInstance.getId(); + String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + RodaConstants.API_SEP + + localInstance.getId(); CloseableHttpClient httpClient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(localInstance.getCentralInstanceURL() + resource); @@ -270,7 +272,7 @@ public static DistributedInstance requestInstanceStatus(LocalInstance localInsta public static Path requestRemoteActions(LocalInstance localInstance) throws GenericException { try { AccessToken accessToken = TokenManager.getInstance().getAccessToken(localInstance); - String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + "remote_actions" + String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + "remote/actions" + RodaConstants.API_SEP + localInstance.getId(); CloseableHttpClient httpClient = HttpClientBuilder.create().build(); @@ -361,24 +363,26 @@ public static StreamResponse createLastSyncFileStreamResponse(Path path) { * if some i/o error occurs. */ public static JsonParser createJsonParser(Path path) throws IOException { - final JsonFactory jfactory = new JsonFactory(); - return jfactory.createParser(path.toFile()); + final JsonFactory factory = new JsonFactory(); + return factory.createParser(path.toFile()); } - public static void updateDistributedInstance(LocalInstance localInstance, DistributedInstance distributedInstance) - throws GenericException { + public static void updateDistributedInstanceSyncStatus(LocalInstance localInstance, + DistributedInstance distributedInstance) throws GenericException { try { AccessToken accessToken = TokenManager.getInstance().getAccessToken(localInstance); - String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + "distributed"; + String resource = RodaConstants.API_SEP + "api/v2/distributed-instances/" + distributedInstance.getId() + + "/status?activate=false"; CloseableHttpClient httpClient = HttpClientBuilder.create().build(); - HttpPut httpPut = new HttpPut(localInstance.getCentralInstanceURL() + resource); - httpPut.setEntity(new StringEntity(JsonUtils.getJsonFromObject(distributedInstance))); - httpPut.addHeader("Authorization", "Bearer " + accessToken.getToken()); - httpPut.addHeader("content-type", "application/json"); - httpPut.addHeader("Accept", "application/json"); + HttpPatch httpPatch = new HttpPatch(localInstance.getCentralInstanceURL() + resource); + // httpPatch.setEntity(new + // StringEntity(JsonUtils.getJsonFromObject(distributedInstance))); + httpPatch.addHeader("Authorization", "Bearer " + accessToken.getToken()); + httpPatch.addHeader("content-type", "application/json"); + httpPatch.addHeader("Accept", "application/json"); - HttpResponse response = httpClient.execute(httpPut); + HttpResponse response = httpClient.execute(httpPatch); if (response.getStatusLine().getStatusCode() != RodaConstants.HTTP_RESPONSE_CODE_SUCCESS) { throw new GenericException( @@ -417,5 +421,4 @@ public static Long getUpdatesFromDistributedInstance(LocalInstance localInstance throw new GenericException("Unable to retrieve instance status: " + e.getMessage()); } } - } diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java index 4341d1a8fb..dd22394ea5 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java @@ -4381,6 +4381,7 @@ public DistributedInstance updateDistributedInstance(DistributedInstance distrib String distributedInstanceAsJson = JsonUtils.getJsonFromObject(distributedInstance); StoragePath distributedInstancePath = ModelUtils.getDistributedInstanceStoragePath(distributedInstance.getId()); + if (distributedInstancePath != null) { storage.updateBinaryContent(distributedInstancePath, new StringContentPayload(distributedInstanceAsJson), false, false); diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/utils/LdapUtility.java b/roda-core/roda-core/src/main/java/org/roda/core/model/utils/LdapUtility.java index c698ba53ac..54d87c06f9 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/model/utils/LdapUtility.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/model/utils/LdapUtility.java @@ -233,8 +233,8 @@ public void initialize(RodaConstants.NodeType nodeType) throws Exception { ldapTemplate.setContextSource(contextSource); } - bootstrap(); - createRoles(configuration); + bootstrap(configuration); + } /** @@ -244,7 +244,7 @@ public void initialize(RodaConstants.NodeType nodeType) throws Exception { * @throws Exception * if there were some problems while initializing the system */ - private void bootstrap() throws Exception { + private void bootstrap(Configuration configuration) throws Exception { if (!dnExists(LdapUtils.emptyLdapName())) { // Add root DN addRootEntry(); @@ -259,6 +259,8 @@ private void bootstrap() throws Exception { addOrganizationUnitIfNotExists(ldapGroupsDN); applyLdif(); + + createRoles(configuration); } } diff --git a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/instance/RegisterPlugin.java b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/instance/RegisterPlugin.java index 31508c8f40..d749be07c6 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/instance/RegisterPlugin.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/instance/RegisterPlugin.java @@ -147,9 +147,9 @@ private void subscribeLocalInstance(ModelService model, Job cachedJob, Report pl try { LocalInstance localInstance = RodaCoreFactory.getLocalInstance(); AccessToken accessToken = TokenManager.getInstance().getAccessToken(localInstance); - String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE - + RodaConstants.API_PATH_PARAM_DISTRIBUTED_INSTANCE_REGISTER; - RESTClientUtility.sendPostRequest(localInstance, null, localInstance.getCentralInstanceURL(), resource, + String resource = RodaConstants.API_SEP + RodaConstants.API_REST_V2_DISTRIBUTED_INSTANCE + RodaConstants.API_SEP + + localInstance.getId() + RodaConstants.API_SEP + RodaConstants.API_PATH_PARAM_DISTRIBUTED_INSTANCE_REGISTER; + RESTClientUtility.sendPostRequestWithoutBody(null, localInstance.getCentralInstanceURL(), resource, accessToken); localInstance.setIsSubscribed(true); localInstance.setStatus(SynchronizingStatus.ACTIVE); diff --git a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/AipPackagePlugin.java b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/AipPackagePlugin.java index 0510302096..45db1409df 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/AipPackagePlugin.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/AipPackagePlugin.java @@ -25,6 +25,7 @@ import org.roda.core.data.exceptions.RequestNotValidException; import org.roda.core.data.utils.JsonUtils; import org.roda.core.data.v2.Void; +import org.roda.core.data.v2.index.filter.AllFilterParameter; import org.roda.core.data.v2.index.filter.DateIntervalFilterParameter; import org.roda.core.data.v2.index.filter.Filter; import org.roda.core.data.v2.index.filter.FilterParameter; @@ -120,6 +121,8 @@ private IterableIndexResult listIndexedAip(IndexService index) if (fromDate != null) { filter.add( new DateIntervalFilterParameter(RodaConstants.AIP_UPDATED_ON, RodaConstants.AIP_UPDATED_ON, fromDate, toDate)); + } else { + filter.add(new AllFilterParameter()); } return index.findAll(IndexedAIP.class, filter, Collections.singletonList(RodaConstants.INDEX_UUID)); } diff --git a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/RodaEntityPackagesPlugin.java b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/RodaEntityPackagesPlugin.java index c75054803e..e1abbe0a95 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/RodaEntityPackagesPlugin.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/packages/RodaEntityPackagesPlugin.java @@ -166,12 +166,11 @@ protected void processEntity(IndexService index, ModelService model, Report repo createPackage(index, model, indexResult); } - state = PluginState.SUCCESS; outcomeText = "Package created with " + totalCount + " item(s) of entity " + getEntity(); jobPluginInfo.incrementObjectsProcessedWithSuccess(); } catch (GenericException | AuthorizationDeniedException | RequestNotValidException | NotFoundException | AlreadyExistsException e) { - LOGGER.error("Error on create package for entity " + getEntity(), e); + LOGGER.error("Error on create package for entity {}", getEntity(), e); state = PluginState.FAILURE; jobPluginInfo.incrementObjectsProcessedWithFailure(); outcomeText = "Error on create package for entity " + getEntity(); diff --git a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/proccess/RequestSyncBundlePlugin.java b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/proccess/RequestSyncBundlePlugin.java index 4c271669d6..32ed91972e 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/proccess/RequestSyncBundlePlugin.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/synchronization/proccess/RequestSyncBundlePlugin.java @@ -163,7 +163,7 @@ private void requestRemoteActions(ModelService model, IndexService index, Storag JobPluginInfo jobPluginInfo, Job cachedJob) { Report reportItem = PluginHelper.initPluginReportItem(this, cachedJob.getId(), Job.class); PluginHelper.updatePartialJobReport(this, model, reportItem, false, cachedJob); - PluginState pluginState = PluginState.SKIPPED; + PluginState pluginState; String outcomeDetailsText = "There are no updates from the central instance"; try { diff --git a/roda-core/roda-core/src/main/resources/config/roda-roles.properties b/roda-core/roda-core/src/main/resources/config/roda-roles.properties index dbec45a15b..900294a807 100644 --- a/roda-core/roda-core/src/main/resources/config/roda-roles.properties +++ b/roda-core/roda-core/src/main/resources/config/roda-roles.properties @@ -185,19 +185,21 @@ core.roles.org.roda.wui.api.v2.controller.RepresentationController.getRepresenta core.roles.org.roda.wui.api.v2.controller.RepresentationController.getRepresentationTypeOptions = representation.update core.roles.org.roda.wui.api.v2.controller.RepresentationController.retrieveIndexedRepresentationViaRequest = representation.read +# Distributed instances roles core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.getDistributedInstances = distributed_instances.read core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.getDistributedInstance = distributed_instances.read core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.deleteDistributedInstance = distributed_instances.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.createDistributedInstance = distributed_instances.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.updateDistributedInstance = distributed_instances.manage - +core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.updateDistributedInstanceSyncStatus = distributed_instances.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.testLocalInstanceConfiguration = local_instance_configuration.read core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.createLocalInstance = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.subscribeLocalInstance = local_instance_configuration.manage +core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.unsubscribeLocalInstance = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.deleteLocalInstanceConfiguration = local_instance_configuration.manage -core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.removeLocalConfiguration = localInstanceConfiguration.manage +core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.removeLocalConfiguration = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.status = local_instance_configuration.manage -core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.deleteLocalConfiguration = localInstanceConfiguration.manage +core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.deleteLocalConfiguration = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.synchronize = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.updateLocalInstanceConfiguration = local_instance_configuration.manage core.roles.org.roda.wui.api.v2.controller.DistributedInstancesController.getLocalInstance = local_instance_configuration.read diff --git a/roda-ui/roda-wui/pom.xml b/roda-ui/roda-wui/pom.xml index 0bc7e9891f..ef8575e736 100644 --- a/roda-ui/roda-wui/pom.xml +++ b/roda-ui/roda-wui/pom.xml @@ -109,6 +109,10 @@ ${project.build.directory}/${project.build.finalName} + ldap://localhost + 1389 + server + http://localhost:5138 localhost:2181 @@ -163,6 +167,10 @@ ${project.build.directory}/${project.build.finalName} + ldap://localhost + 1388 + server + http://localhost:5139 localhost:2182 diff --git a/roda-ui/roda-wui/src/main/java/config/i18n/client/ClientMessages.java b/roda-ui/roda-wui/src/main/java/config/i18n/client/ClientMessages.java index 739f118efd..d276a6fa85 100644 --- a/roda-ui/roda-wui/src/main/java/config/i18n/client/ClientMessages.java +++ b/roda-ui/roda-wui/src/main/java/config/i18n/client/ClientMessages.java @@ -2375,6 +2375,10 @@ SafeHtml representationInformationAssociatedWithDescription(String field, String String removeLocalConfigurationMessage(); + String successfullyUnsubscribedTitle(); + + String successfullyUnsubscribedMessage(); + String removeInstanceIdFromRepository(); String removeInstanceIdFromRepositoryMessage(); diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/controllers/RODAInstance.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/controllers/RODAInstance.java index 423214b475..15b834109d 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/controllers/RODAInstance.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/controllers/RODAInstance.java @@ -235,7 +235,7 @@ public static void deleteLocalInstanceConfiguration(User user) throws Authorizat DistributedInstance distributedInstance = SyncUtils.requestInstanceStatus(RodaCoreFactory.getLocalInstance()); distributedInstance.setStatus(SynchronizingStatus.INACTIVE); - SyncUtils.updateDistributedInstance(RodaCoreFactory.getLocalInstance(), distributedInstance); + SyncUtils.updateDistributedInstanceSyncStatus(RodaCoreFactory.getLocalInstance(), distributedInstance); } catch (GenericException e) { // Do nothing distributed instance was removed } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DistributedInstancesController.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DistributedInstancesController.java index 68034ad3c7..6df2fcd102 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DistributedInstancesController.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DistributedInstancesController.java @@ -8,29 +8,18 @@ import java.util.List; import java.util.Objects; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.ws.rs.core.Response; - -import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.roda.core.RodaCoreFactory; import org.roda.core.common.SyncUtils; import org.roda.core.common.TokenManager; import org.roda.core.data.common.RodaConstants; import org.roda.core.data.exceptions.AlreadyExistsException; +import org.roda.core.data.exceptions.AuthenticationDeniedException; import org.roda.core.data.exceptions.AuthorizationDeniedException; import org.roda.core.data.exceptions.GenericException; +import org.roda.core.data.exceptions.IllegalOperationException; import org.roda.core.data.exceptions.NotFoundException; -import org.roda.core.data.exceptions.RODAException; import org.roda.core.data.exceptions.RequestNotValidException; -import org.roda.core.data.v2.EntityResponse; import org.roda.core.data.v2.StreamResponse; -import org.roda.core.data.v2.generics.CreateDistributedInstanceRequest; -import org.roda.core.data.v2.generics.CreateLocalInstanceRequest; import org.roda.core.data.v2.index.filter.DateIntervalFilterParameter; import org.roda.core.data.v2.index.filter.Filter; import org.roda.core.data.v2.index.filter.SimpleFilterParameter; @@ -39,19 +28,19 @@ import org.roda.core.data.v2.ri.RepresentationInformation; import org.roda.core.data.v2.risks.IndexedRisk; import org.roda.core.data.v2.synchronization.SynchronizingStatus; +import org.roda.core.data.v2.synchronization.central.CreateDistributedInstanceRequest; +import org.roda.core.data.v2.synchronization.central.CreateLocalInstanceRequest; import org.roda.core.data.v2.synchronization.central.DistributedInstance; import org.roda.core.data.v2.synchronization.central.DistributedInstances; +import org.roda.core.data.v2.synchronization.central.UpdateDistributedInstanceRequest; import org.roda.core.data.v2.synchronization.local.LocalInstance; -import org.roda.core.data.v2.user.User; import org.roda.core.index.IndexService; import org.roda.core.model.ModelService; -import org.roda.core.storage.utils.RODAInstanceUtils; -import org.roda.wui.api.v1.utils.ApiUtils; -import org.roda.wui.api.v1.utils.ObjectResponse; import org.roda.wui.api.v2.exceptions.RESTException; import org.roda.wui.api.v2.exceptions.model.ErrorResponseMessage; import org.roda.wui.api.v2.services.DistributedInstanceService; import org.roda.wui.api.v2.services.MembersService; +import org.roda.wui.api.v2.utils.ApiUtils; import org.roda.wui.client.services.DistributedInstancesRestService; import org.roda.wui.common.ControllerAssistant; import org.roda.wui.common.model.RequestContext; @@ -61,15 +50,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -77,17 +70,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; -import jakarta.ws.rs.core.Response; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Objects; /** * @author António Lindo @@ -116,13 +98,17 @@ public DistributedInstances getDistributedInstances() { try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); + return RodaCoreFactory.getModelService().listDistributedInstances(); - } catch (RODAException | IOException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | RequestNotValidException | IOException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state); + controllerAssistant.registerAction(requestContext, state); } } @@ -135,13 +121,18 @@ public DistributedInstance getDistributedInstance(String id) { try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); + return RodaCoreFactory.getModelService().retrieveDistributedInstance(id); - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state); + controllerAssistant.registerAction(requestContext, id, state, + RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_ID_PARAM, id); } } @@ -156,13 +147,15 @@ public LocalInstance getLocalInstance() { controllerAssistant.checkRoles(requestContext.getUser()); LocalInstance localInstance = RodaCoreFactory.getLocalInstance(); return Objects.requireNonNullElseGet(localInstance, LocalInstance::new); - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + controllerAssistant.registerAction(requestContext, state); } } @@ -175,17 +168,20 @@ public Void deleteDistributedInstance(String id) { try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - final DistributedInstance distributedInstance = RodaCoreFactory.getModelService().retrieveDistributedInstance(id); - final String username = RodaConstants.DISTRIBUTED_INSTANCE_USER_PREFIX + distributedInstance.getName(); - RodaCoreFactory.getModelService().deleteDistributedInstance(id); - membersService.deleteUser(username); + + // delegate + distributedInstanceService.deleteDistributedInstance(membersService, id); return null; - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state); + controllerAssistant.registerAction(requestContext, id, state, + RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_ID_PARAM, id); } } @@ -195,51 +191,56 @@ public DistributedInstance createDistributedInstance( final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); LogEntryState state = LogEntryState.SUCCESS; - DistributedInstance distributedInstance = new DistributedInstance(); + try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - distributedInstance.setName(createDistributedInstanceRequest.getName()); - distributedInstance.setDescription(createDistributedInstanceRequest.getDescription()); - DistributedInstance createdInstance = distributedInstanceService.createDistributedInstance(distributedInstance, - requestContext.getUser()); + + DistributedInstance createdInstance = distributedInstanceService + .createDistributedInstance(createDistributedInstanceRequest, requestContext.getUser()); createdInstance .setToken(RodaCoreFactory.getModelService().retrieveAccessKey(createdInstance.getAccessKeyId()).getKey()); return createdInstance; - } catch (RODAException e) { + } catch (AlreadyExistsException | NotFoundException | RequestNotValidException | GenericException + | IllegalOperationException e) { state = LogEntryState.FAILURE; throw new RESTException(e); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); } finally { - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_PARAM, distributedInstance); + controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_PARAM, + createDistributedInstanceRequest); } } @Override - public DistributedInstance registerDistributedInstance(@RequestBody LocalInstance localInstance) { + public DistributedInstance updateDistributedInstance( + @RequestBody UpdateDistributedInstanceRequest distributedInstance) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - - LogEntryState state = LogEntryState.SUCCESS; try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - DistributedInstance distributedInstance = RodaCoreFactory.getModelService() - .retrieveDistributedInstance(localInstance.getId()); - distributedInstance.setStatus(SynchronizingStatus.ACTIVE); - return RodaCoreFactory.getModelService().updateDistributedInstance(distributedInstance, requestContext.getUser().getId()); - } catch (RODAException e) { + + // delegate + return distributedInstanceService.updateDistributionInstance(distributedInstance, requestContext.getUser()); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { - controllerAssistant.registerAction(requestContext.getUser(), state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + // register action + controllerAssistant.registerAction(requestContext, state); } } @Override - public DistributedInstance updateDistributedInstance(@RequestBody DistributedInstance distributedInstance) { + public DistributedInstance updateDistributedInstanceSyncStatus(String id, boolean activate) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); LogEntryState state = LogEntryState.SUCCESS; @@ -247,14 +248,19 @@ public DistributedInstance updateDistributedInstance(@RequestBody DistributedIns try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - return RodaCoreFactory.getModelService().updateDistributedInstance(distributedInstance, - requestContext.getUser().getId()); - } catch (RODAException e) { + + return distributedInstanceService.updateDistributionInstanceStatus(id, activate, requestContext.getUser()); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state); + controllerAssistant.registerAction(requestContext, id, state, + RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_ID_PARAM, id, + RodaConstants.CONTROLLER_DISTRIBUTED_INSTANCE_STATUS_PARAM, activate); } } @@ -271,12 +277,14 @@ public List testLocalInstanceConfiguration(@RequestBody LocalInstance lo TokenManager.getInstance().getAccessToken(localInstance); TokenManager.getInstance().removeToken(); - } catch (RODAException | IllegalArgumentException e) { + } catch (AuthenticationDeniedException | AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + responseList.add(e.toString()); + } catch (GenericException e) { state = LogEntryState.FAILURE; responseList.add(e.toString()); } finally { - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); } return responseList; @@ -286,25 +294,24 @@ public List testLocalInstanceConfiguration(@RequestBody LocalInstance lo public LocalInstance createLocalInstance(@RequestBody CreateLocalInstanceRequest createLocalInstanceRequest) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - LogEntryState state = LogEntryState.SUCCESS; - LocalInstance localInstance = new LocalInstance(); + try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - localInstance.setCentralInstanceURL(createLocalInstanceRequest.getCentralInstanceURL()); - localInstance.setAccessKey(createLocalInstanceRequest.getAccessKey()); - localInstance.setId(createLocalInstanceRequest.getId()); - RodaCoreFactory.createOrUpdateLocalInstance(localInstance); - localInstance.setAccessKey(null); - return localInstance; - } catch (RODAException e) { + + // delegate + return distributedInstanceService.createLocalInstance(createLocalInstanceRequest); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, - localInstance); + controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, + createLocalInstanceRequest); } } @@ -317,73 +324,73 @@ public LocalInstance subscribeLocalInstance(@RequestBody LocalInstance localInst try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - // Apply Identifiers - localInstance.setStatus(SynchronizingStatus.APPLYINGIDENTIFIER); - RodaCoreFactory.createOrUpdateLocalInstance(localInstance); - distributedInstanceService.applyInstanceIdToRodaObject(localInstance, requestContext.getUser(), true); - RODAInstanceUtils.createDistributedGroup(requestContext.getUser()); - localInstance.setAccessKey(null); - return localInstance; - } catch (RODAException e) { + + // delegate + return distributedInstanceService.subscribe(localInstance, requestContext.getUser()); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, + localInstance); } } @Override - public Void deleteLocalInstanceConfiguration() { + public Void unsubscribeLocalInstance() { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - LogEntryState state = LogEntryState.SUCCESS; try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - try { - // Deleting from distributed - DistributedInstance distributedInstance = SyncUtils.requestInstanceStatus(RodaCoreFactory.getLocalInstance()); - distributedInstance.setStatus(SynchronizingStatus.INACTIVE); - SyncUtils.updateDistributedInstance(RodaCoreFactory.getLocalInstance(), distributedInstance); - } catch (GenericException e) { - // Do nothing distributed instance was removed - } + DistributedInstance distributedInstance = SyncUtils.requestInstanceStatus(RodaCoreFactory.getLocalInstance()); + distributedInstance.setStatus(SynchronizingStatus.INACTIVE); + SyncUtils.updateDistributedInstanceSyncStatus(RodaCoreFactory.getLocalInstance(), distributedInstance); + // Deleting from remote TokenManager.getInstance().removeToken(); RodaCoreFactory.createOrUpdateLocalInstance(null); + return null; - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + controllerAssistant.registerAction(requestContext, state); } } @Override - public Void deleteLocalConfiguration(@RequestBody LocalInstance localInstance) { + public Void deleteLocalConfiguration() { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; - List responseList = new ArrayList(); RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - LogEntryState state = LogEntryState.SUCCESS; + try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - distributedInstanceService.applyInstanceIdToRodaObject(localInstance, requestContext.getUser(), false); + + // delegate + distributedInstanceService.applyInstanceIdToRodaObject(null, requestContext.getUser(), false); return null; - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + controllerAssistant.registerAction(requestContext, state); } } @@ -397,105 +404,68 @@ public Job synchronize(@RequestBody LocalInstance localInstance) { try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); + if (!SynchronizingStatus.ACTIVE.equals(localInstance.getStatus())) { state = LogEntryState.FAILURE; throw new GenericException("The instance isn't in Active state."); } else { return distributedInstanceService.synchronize(requestContext.getUser(), localInstance); } - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); + RodaConstants.CONTROLLER_LOCAL_INSTANCE_ID_PARAM, localInstance.getId()); } } - @RequestMapping(path = "/remove/bundle/{name}/{dir}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "Delete distributed instance", description = "Deletes a distributed instance", responses = { - @ApiResponse(responseCode = "204", description = "No Content"), + @PostMapping(path = "/{id}/register", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Register distributed instance", description = "Registers a distributed instance", responses = { + @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Void deleteSyncBundle( - @Parameter(description = "The sync bundle name") @PathVariable(name = "name") String name, - @Parameter(description = "The sync bundle directory") @PathVariable(name = "dir") String directory) { - String message = null; - - if (RodaConstants.CORE_SYNCHRONIZATION_INCOMING_FOLDER.equals(directory)) { - Path syncBundlePath = SyncUtils.getSyncIncomingBundlePath(name); - try { - Boolean deleteFromIncome = Files.deleteIfExists(syncBundlePath); - if (deleteFromIncome == true) { - message = "Deleted bundle from income folder with success"; - } else { - message = "Could not find bundle in income folder"; - } - } catch (IOException e) { - LOGGER.error("Can not delete bundle from income folder because " + e.getMessage()); - } - } else { - Path syncBundlePath = SyncUtils.getSyncOutcomeBundlePath(name); - try { - Boolean deleteFromOutcome = Files.deleteIfExists(syncBundlePath); - if (deleteFromOutcome == true) { - message = "Deleted bundle from outcome folder with success"; - } else { - message = "Could not find bundle in outcome folder"; - } - } catch (IOException e) { - LOGGER.error("Can not delete bundle from outcome folder because " + e.getMessage()); - } - } - LOGGER.info(message); - return null; - } - - - @Override - public DistributedInstance status(String id) { + public DistributedInstance registerDistributedInstance( + @Parameter(description = "The instance identifier") @PathVariable(name = "id") String id) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - LogEntryState state = LogEntryState.SUCCESS; + try { - // check permissions + // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); - return RodaCoreFactory.getModelService().retrieveDistributedInstance(id); - } catch (RODAException e) { + + DistributedInstance distributedInstance = RodaCoreFactory.getModelService().retrieveDistributedInstance(id); + distributedInstance.setStatus(SynchronizingStatus.ACTIVE); + return RodaCoreFactory.getModelService().updateDistributedInstance(distributedInstance, + requestContext.getUser().getId()); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { - // register action - controllerAssistant.registerAction(requestContext.getUser(), state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, - id); + controllerAssistant.registerAction(requestContext.getUser(), state, + RodaConstants.CONTROLLER_LOCAL_INSTANCE_ID_PARAM, id); } - } - @Override - public LocalInstance updateLocalInstanceConfiguration(@RequestBody LocalInstance localInstance) { + @GetMapping(path = "/updates/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get central instance updates", description = "Get central instance updates", responses = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = Long.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + private Long getCentralInstanceUpdates( + @Parameter(description = "The instance id") @PathVariable(name = "id") String id) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); LogEntryState state = LogEntryState.SUCCESS; - try { - // check user permissions - controllerAssistant.checkRoles(requestContext.getUser()); - RodaCoreFactory.createOrUpdateLocalInstance(localInstance); - return RodaCoreFactory.getLocalInstance(); - } catch (RODAException e) { - state = LogEntryState.FAILURE; - throw new RESTException(e); - } finally { - // register action - controllerAssistant.registerAction(requestContext.getUser(), state, - RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM); - } - } - - @Override - public Long getCentralInstanceUpdates(String id) { try { Long total = 0L; ModelService model = RodaCoreFactory.getModelService(); @@ -525,63 +495,127 @@ public Long getCentralInstanceUpdates(String id) { total += index.count(RepresentationInformation.class, riskFilter); return total; - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { + state = LogEntryState.FAILURE; throw new RESTException(e); } - } - @RequestMapping(path = "/remote_actions/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get instance status", description = "Gets instance status", responses = { - @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = Response.class))), + @DeleteMapping(path = "/remove/bundle/{name}/{dir}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Delete distributed instance", description = "Deletes a distributed instance", responses = { + @ApiResponse(responseCode = "204", description = "No Content"), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Response remoteActions(@Parameter(description = "The instance id") @PathVariable(name = "id") String id) { - // get user + void deleteSyncBundle(@Parameter(description = "The sync bundle name") @PathVariable(name = "name") String name, + @Parameter(description = "The sync bundle directory") @PathVariable(name = "dir") String directory) { + final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); - User user = requestContext.getUser(); + LogEntryState state = LogEntryState.SUCCESS; + try { - EntityResponse response = retrieveRemoteActions(user, id); - if (response instanceof StreamResponse) { - return ApiUtils.okResponse((StreamResponse) response); - } else { - return Response.noContent().build(); - } - } catch (RODAException e) { + // check user permissions + controllerAssistant.checkRoles(requestContext.getUser()); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; throw new RESTException(e); } + + String message = null; + + if (RodaConstants.CORE_SYNCHRONIZATION_INCOMING_FOLDER.equals(directory)) { + Path syncBundlePath = SyncUtils.getSyncIncomingBundlePath(name); + try { + boolean deleteFromIncome = Files.deleteIfExists(syncBundlePath); + if (deleteFromIncome) { + message = "Deleted bundle from income folder with success"; + } else { + message = "Could not find bundle in income folder"; + } + } catch (IOException e) { + LOGGER.error("Can not delete bundle from income folder because {}", e.getMessage()); + } + } else { + Path syncBundlePath = SyncUtils.getSyncOutcomeBundlePath(name); + try { + boolean deleteFromOutcome = Files.deleteIfExists(syncBundlePath); + if (deleteFromOutcome) { + message = "Deleted bundle from outcome folder with success"; + } else { + message = "Could not find bundle in outcome folder"; + } + } catch (IOException e) { + LOGGER.error("Can not delete bundle from outcome folder because {}", e.getMessage()); + } + } + LOGGER.info(message); } - public EntityResponse retrieveRemoteActions(User user, String instanceIdentifier) - throws GenericException, RequestNotValidException, AuthorizationDeniedException, AlreadyExistsException { + @Override + public LocalInstance updateLocalInstanceConfiguration(@RequestBody LocalInstance localInstance) { final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; + RequestContext requestContext = RequestUtils.parseHTTPRequest(request); + LogEntryState state = LogEntryState.SUCCESS; - // check permissions - controllerAssistant.checkRoles(user); + try { + // check user permissions + controllerAssistant.checkRoles(requestContext.getUser()); + RodaCoreFactory.createOrUpdateLocalInstance(localInstance); + return RodaCoreFactory.getLocalInstance(); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException e) { + state = LogEntryState.FAILURE; + throw new RESTException(e); + } finally { + // register action + controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, + localInstance); + } + } + @GetMapping(path = "/remote/actions/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + @Operation(summary = "Get instance status", description = "Gets instance status", responses = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = ResponseEntity.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "409", description = "Conflict", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + public ResponseEntity remoteActions( + @Parameter(description = "The instance id") @PathVariable(name = "id") String id) { + final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; + RequestContext requestContext = RequestUtils.parseHTTPRequest(request); LogEntryState state = LogEntryState.SUCCESS; try { - // delegate - try { - return distributedInstanceService.createCentralSyncBundle(instanceIdentifier); - } catch (NotFoundException e) { - return new ObjectResponse<>(null, null); - } - } catch (RODAException e) { + // check permissions + controllerAssistant.checkRoles(requestContext.getUser()); + + StreamResponse response = distributedInstanceService.createCentralSyncBundle(id); + + return ApiUtils.okResponse(response); + } catch (AlreadyExistsException | GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); } finally { // register action - controllerAssistant.registerAction(user, state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, - instanceIdentifier); + controllerAssistant.registerAction(requestContext.getUser(), state, RodaConstants.CONTROLLER_LOCAL_INSTANCE_PARAM, + id); } } - @RequestMapping(path = "/sync/status/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get synchronization status" ,description = "Gets synchronization status", responses = { - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = Response.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Response synchronizationStatus( + @GetMapping(path = "/sync/status/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get synchronization status", description = "Gets synchronization status", responses = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = ResponseEntity.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + ResponseEntity synchronizationStatus( @Parameter(description = "The instance id") @PathVariable(name = "id") String id, @Parameter(description = "The entity class") @RequestParam(name = RodaConstants.API_QUERY_KEY_CLASS) String entityClass, @Parameter(description = "The type") @RequestParam(name = RodaConstants.API_QUERY_KEY_TYPE) String type) { @@ -593,10 +627,11 @@ Response synchronizationStatus( try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); + // delegate - return ApiUtils.okResponse((StreamResponse) distributedInstanceService.retrieveLastSyncFileByClass(id, entityClass, type)); - } catch (RODAException e) { - state = LogEntryState.FAILURE; + return ApiUtils.okResponse(distributedInstanceService.retrieveLastSyncFileByClass(id, entityClass, type)); + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; throw new RESTException(e); } finally { // register action @@ -605,23 +640,28 @@ Response synchronizationStatus( } } - @RequestMapping(path = "/sync/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(path = "/sync/{id}", produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Import sync bundle", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = MultipartFile.class))), description = "Imports sync bundle", responses = { @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = Job.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Job importSyncBundle( + public Job importSyncBundle( @Parameter(content = @Content(mediaType = "multipart/form-data", schema = @Schema(implementation = MultipartFile.class)), description = "Multipart file") @RequestPart(value = "file") MultipartFile resource, @Parameter(description = "The instance id") @PathVariable(name = "id") String id) { - final ControllerAssistant controllerAssistant = new ControllerAssistant() { - }; + final ControllerAssistant controllerAssistant = new ControllerAssistant() {}; RequestContext requestContext = RequestUtils.parseHTTPRequest(request); LogEntryState state = LogEntryState.SUCCESS; try { // check user permissions controllerAssistant.checkRoles(requestContext.getUser()); + return distributedInstanceService.importSyncBundle(requestContext.getUser(), id, resource); - } catch (RODAException e) { + } catch (AuthorizationDeniedException e) { + state = LogEntryState.UNAUTHORIZED; + throw new RESTException(e); + } catch (GenericException | NotFoundException | RequestNotValidException e) { state = LogEntryState.FAILURE; throw new RESTException(e); } finally { diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DistributedInstanceService.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DistributedInstanceService.java index a0bbcf69ee..9c941cfa5c 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DistributedInstanceService.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DistributedInstanceService.java @@ -1,5 +1,11 @@ package org.roda.wui.api.v2.services; +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; import org.roda.core.RodaCoreFactory; import org.roda.core.common.SyncUtils; import org.roda.core.common.synchronization.BundleManifestCreator; @@ -10,27 +16,26 @@ import org.roda.core.data.exceptions.IllegalOperationException; import org.roda.core.data.exceptions.NotFoundException; import org.roda.core.data.exceptions.RequestNotValidException; -import org.roda.core.data.v2.EntityResponse; +import org.roda.core.data.v2.StreamResponse; import org.roda.core.data.v2.index.select.SelectedItemsNone; import org.roda.core.data.v2.jobs.Job; import org.roda.core.data.v2.synchronization.SynchronizingStatus; +import org.roda.core.data.v2.synchronization.central.CreateDistributedInstanceRequest; +import org.roda.core.data.v2.synchronization.central.CreateLocalInstanceRequest; import org.roda.core.data.v2.synchronization.central.DistributedInstance; +import org.roda.core.data.v2.synchronization.central.UpdateDistributedInstanceRequest; import org.roda.core.data.v2.synchronization.local.LocalInstance; import org.roda.core.data.v2.user.User; import org.roda.core.plugins.base.synchronization.instance.LocalInstanceRegisterPlugin; import org.roda.core.plugins.base.synchronization.proccess.ImportSyncBundlePlugin; import org.roda.core.plugins.base.synchronization.proccess.SynchronizeInstancePlugin; +import org.roda.core.storage.utils.RODAInstanceUtils; import org.roda.wui.api.controllers.BrowserHelper; import org.roda.wui.api.v2.utils.CommonServicesUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; - /** * @author António Lindo */ @@ -40,19 +45,43 @@ public class DistributedInstanceService { @Autowired private JobService jobsService; - public DistributedInstance createDistributedInstance(DistributedInstance distributedInstance, User user) + public void deleteDistributedInstance(MembersService membersService, String id) + throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { + final DistributedInstance distributedInstance = RodaCoreFactory.getModelService().retrieveDistributedInstance(id); + final String username = RodaConstants.DISTRIBUTED_INSTANCE_USER_PREFIX + distributedInstance.getName(); + RodaCoreFactory.getModelService().deleteDistributedInstance(id); + membersService.deleteUser(username); + } + + public DistributedInstance createDistributedInstance( + CreateDistributedInstanceRequest createDistributedInstanceRequest, User user) throws GenericException, AuthorizationDeniedException, AlreadyExistsException, NotFoundException, RequestNotValidException, IllegalOperationException { + DistributedInstance distributedInstance = new DistributedInstance(); + + distributedInstance.setName(createDistributedInstanceRequest.getName()); + distributedInstance.setDescription(createDistributedInstanceRequest.getDescription()); + return RodaCoreFactory.getModelService().createDistributedInstance(distributedInstance, user.getName()); } - public void applyInstanceIdToRodaObject(LocalInstance localInstance, User user, boolean doRegister) + public LocalInstance subscribe(LocalInstance localInstance, User user) + throws GenericException, AuthorizationDeniedException, RequestNotValidException, NotFoundException { + localInstance.setStatus(SynchronizingStatus.APPLYINGIDENTIFIER); + RodaCoreFactory.createOrUpdateLocalInstance(localInstance); + applyInstanceIdToRodaObject(localInstance.getId(), user, true); + RODAInstanceUtils.createDistributedGroup(user); + localInstance.setAccessKey(null); + return localInstance; + } + + public void applyInstanceIdToRodaObject(String id, User user, boolean doRegister) throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { Map pluginParameters = new HashMap<>(); if (doRegister) { pluginParameters.put(RodaConstants.PLUGIN_PARAMS_DO_REGISTER_PLUGIN, "true"); } - pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INSTANCE_IDENTIFIER, localInstance.getId()); + pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INSTANCE_IDENTIFIER, id); CommonServicesUtils.createAndExecuteInternalJob("Local Instance Register", SelectedItemsNone.create(), LocalInstanceRegisterPlugin.class, user, pluginParameters, "Could not register the localInstance"); @@ -66,7 +95,7 @@ public Job synchronize(User user, LocalInstance localInstance) SynchronizeInstancePlugin.class, user, new HashMap<>(), "Could not execute bundle job"); } - public EntityResponse createCentralSyncBundle(String instanceIdentifier) throws AuthorizationDeniedException, + public StreamResponse createCentralSyncBundle(String instanceIdentifier) throws AuthorizationDeniedException, AlreadyExistsException, RequestNotValidException, GenericException, NotFoundException { try { @@ -85,8 +114,8 @@ public EntityResponse createCentralSyncBundle(String instanceIdentifier) throws } } - public EntityResponse retrieveLastSyncFileByClass(final String instanceIdentifier, final String entityClass, - final String type) throws GenericException, NotFoundException { + public StreamResponse retrieveLastSyncFileByClass(final String instanceIdentifier, final String entityClass, + final String type) { final StringBuilder fileNameBuilder = new StringBuilder(); fileNameBuilder.append(type).append("_").append(instanceIdentifier).append("_").append(entityClass) .append(".jsonl"); @@ -113,4 +142,44 @@ public Job importSyncBundle(User user, String instanceIdentifier, MultipartFile throw new GenericException("Failed during sync package import", e); } } + + public DistributedInstance updateDistributionInstance(UpdateDistributedInstanceRequest request, User user) + throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { + DistributedInstance distributedInstance = RodaCoreFactory.getModelService() + .retrieveDistributedInstance(request.getId()); + + distributedInstance.setDescription(request.getDescription()); + + if (StringUtils.isNotBlank(request.getName())) { + distributedInstance.setName(request.getName()); + } else { + throw new RequestNotValidException("Name cannot be empty"); + } + + return RodaCoreFactory.getModelService().updateDistributedInstance(distributedInstance, user.getId()); + } + + public DistributedInstance updateDistributionInstanceStatus(String id, boolean activate, User user) + throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { + DistributedInstance distributedInstance = RodaCoreFactory.getModelService().retrieveDistributedInstance(id); + if (activate) { + distributedInstance.setStatus(SynchronizingStatus.ACTIVE); + } else { + distributedInstance.setStatus(SynchronizingStatus.INACTIVE); + } + return RodaCoreFactory.getModelService().updateDistributedInstance(distributedInstance, user.getId()); + } + + public LocalInstance createLocalInstance(CreateLocalInstanceRequest createLocalInstanceRequest) + throws GenericException { + LocalInstance localInstance = new LocalInstance(); + localInstance.setCentralInstanceURL(createLocalInstanceRequest.getCentralInstanceURL()); + localInstance.setAccessKey(createLocalInstanceRequest.getAccessKey()); + localInstance.setId(createLocalInstanceRequest.getId()); + + RodaCoreFactory.createOrUpdateLocalInstance(localInstance); + localInstance.setAccessKey(null); + + return localInstance; + } } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserService.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserService.java index b6dc7bad4d..398ed9d364 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserService.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserService.java @@ -7,24 +7,7 @@ */ package org.roda.wui.client.browse; -import java.io.IOException; -import java.util.List; - import org.roda.core.data.common.RodaConstants; -import org.roda.core.data.exceptions.AlreadyExistsException; -import org.roda.core.data.exceptions.AuthenticationDeniedException; -import org.roda.core.data.exceptions.AuthorizationDeniedException; -import org.roda.core.data.exceptions.GenericException; -import org.roda.core.data.exceptions.IllegalOperationException; -import org.roda.core.data.exceptions.NotFoundException; -import org.roda.core.data.exceptions.RequestNotValidException; -import org.roda.core.data.v2.accessKey.AccessKey; -import org.roda.core.data.v2.accessKey.AccessKeys; -import org.roda.core.data.v2.jobs.Job; -import org.roda.core.data.v2.synchronization.central.DistributedInstance; -import org.roda.core.data.v2.synchronization.central.DistributedInstances; -import org.roda.core.data.v2.synchronization.local.LocalInstance; -import org.roda.wui.client.browse.bundle.BrowseAIPBundle; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.RemoteService; @@ -40,46 +23,6 @@ public interface BrowserService extends RemoteService { */ static final String SERVICE_URI = "browserservice"; - BrowseAIPBundle retrieveBrowseAIPBundle(String aipId, String localeString, List aipFieldsToReturn) - throws AuthorizationDeniedException, GenericException, NotFoundException, RequestNotValidException; - - DistributedInstance createDistributedInstance(DistributedInstance distributedInstance) - throws AuthorizationDeniedException, AlreadyExistsException, NotFoundException, GenericException, - RequestNotValidException, IOException, IllegalOperationException; - - DistributedInstances listDistributedInstances() - throws AuthorizationDeniedException, IOException, GenericException, RequestNotValidException; - - DistributedInstance retrieveDistributedInstance(String distributedInstancesId) - throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException; - - void deleteDistributedInstance(String distributedInstancesId) - throws NotFoundException, GenericException, AuthorizationDeniedException, RequestNotValidException; - - DistributedInstance updateDistributedInstance(DistributedInstance distributedInstance) - throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException; - - void createLocalInstance(LocalInstance localInstance) throws AuthorizationDeniedException, GenericException; - - LocalInstance retrieveLocalInstance() throws AuthorizationDeniedException, GenericException; - - void deleteLocalInstanceConfiguration() throws AuthorizationDeniedException, GenericException; - - void updateLocalInstanceConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException; - - List testLocalInstanceConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException, AuthenticationDeniedException; - - LocalInstance subscribeLocalInstance(LocalInstance localInstance) throws AuthorizationDeniedException, - GenericException, AuthenticationDeniedException, RequestNotValidException, NotFoundException; - - Job synchronizeBundle(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException, NotFoundException, RequestNotValidException; - - void removeLocalConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException; - String getCrontabValue(String locale); /** diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserServiceAsync.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserServiceAsync.java index 8a4b4677f0..43b28aab7c 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserServiceAsync.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowserServiceAsync.java @@ -28,34 +28,5 @@ */ public interface BrowserServiceAsync { - void retrieveBrowseAIPBundle(String aipId, String localeString, List aipFieldsToReturn, - AsyncCallback callback); - - void createDistributedInstance(DistributedInstance distributedInstance, AsyncCallback async); - - void listDistributedInstances(AsyncCallback async); - - void retrieveDistributedInstance(String distributedInstanceId, AsyncCallback async); - - void updateDistributedInstance(DistributedInstance distributedInstance, AsyncCallback async); - - void deleteDistributedInstance(String distributedInstanceId, AsyncCallback async); - - void createLocalInstance(LocalInstance localInstance, AsyncCallback async); - - void retrieveLocalInstance(AsyncCallback async); - - void deleteLocalInstanceConfiguration(AsyncCallback async); - - void updateLocalInstanceConfiguration(LocalInstance localInstance, AsyncCallback async); - - void testLocalInstanceConfiguration(LocalInstance localInstance, AsyncCallback> async); - - void subscribeLocalInstance(LocalInstance localInstance, AsyncCallback async); - - void synchronizeBundle(LocalInstance localInstance, AsyncCallback async); - - void removeLocalConfiguration(LocalInstance localInstance, AsyncCallback async); - void getCrontabValue(String localeName, AsyncCallback async); } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/ingest/process/ShowJob.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/ingest/process/ShowJob.java index 1897f4ec72..53e3d16918 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/ingest/process/ShowJob.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/ingest/process/ShowJob.java @@ -41,8 +41,6 @@ import org.roda.core.data.v2.jobs.PluginParameter; import org.roda.core.data.v2.jobs.PluginParameter.PluginParameterType; import org.roda.core.data.v2.jobs.PluginType; -import org.roda.core.data.v2.synchronization.central.DistributedInstance; -import org.roda.core.data.v2.synchronization.local.LocalInstance; import org.roda.wui.client.browse.BrowserService; import org.roda.wui.client.common.NoAsyncCallback; import org.roda.wui.client.common.UserLogin; @@ -64,6 +62,7 @@ import org.roda.wui.client.management.distributed.ShowDistributedInstance; import org.roda.wui.client.process.Process; import org.roda.wui.client.services.ConfigurationRestService; +import org.roda.wui.client.services.DistributedInstancesRestService; import org.roda.wui.client.services.Services; import org.roda.wui.common.client.HistoryResolver; import org.roda.wui.common.client.tools.ConfigurationManager; @@ -274,22 +273,17 @@ public ShowJob(Job job, Map pluginsInfo, List() { - @Override - public void onFailure(Throwable caught) { - BrowserService.Util.getInstance().retrieveLocalInstance(new NoAsyncCallback() { - @Override - public void onSuccess(LocalInstance localInstance) { + Services services = new Services("Retrieve distributed instance", "retrieve"); + services.distributedInstanceResource(s -> s.getDistributedInstance(job.getInstanceId())) + .whenComplete((distributedInstance, throwable) -> { + if (throwable != null) { + services.distributedInstanceResource(DistributedInstancesRestService::getLocalInstance) + .whenComplete((localInstance, throwable1) -> { Label instanceNameLabel = new Label(localInstance.getName()); instanceNameLabel.addStyleName("value"); instancePanel.add(instanceNameLabel); - } - }); - } - - @Override - public void onSuccess(DistributedInstance distributedInstance) { + }); + } else { Anchor anchor = new Anchor(); anchor.setHref(HistoryUtils.createHistoryHashLink(ShowDistributedInstance.RESOLVER, job.getInstanceId())); anchor.setText(distributedInstance.getName()); diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateDistributedInstance.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateDistributedInstance.java index 8ce9761a00..58cdeae726 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateDistributedInstance.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateDistributedInstance.java @@ -18,7 +18,7 @@ import com.google.gwt.user.client.ui.Widget; import config.i18n.client.ClientMessages; import org.roda.core.data.v2.accessKey.AccessKey; -import org.roda.core.data.v2.generics.CreateDistributedInstanceRequest; +import org.roda.core.data.v2.synchronization.central.CreateDistributedInstanceRequest; import org.roda.core.data.v2.synchronization.central.DistributedInstance; import org.roda.wui.client.common.NoAsyncCallback; import org.roda.wui.client.common.UserLogin; diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateLocalInstanceConfiguration.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateLocalInstanceConfiguration.java index e3120fc11c..78d9334b30 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateLocalInstanceConfiguration.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/CreateLocalInstanceConfiguration.java @@ -16,11 +16,8 @@ import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; -import org.roda.core.data.v2.generics.CreateLocalInstanceRequest; -import org.roda.core.data.v2.synchronization.central.DistributedInstance; +import org.roda.core.data.v2.synchronization.central.CreateLocalInstanceRequest; import org.roda.core.data.v2.synchronization.local.LocalInstance; -import org.roda.wui.client.browse.BrowserService; -import org.roda.wui.client.common.NoAsyncCallback; import org.roda.wui.client.common.UserLogin; import org.roda.wui.client.common.utils.JavascriptUtils; import org.roda.wui.client.services.Services; diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/EditDistributedInstance.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/EditDistributedInstance.java index 24baff3d97..3ac1eb4546 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/EditDistributedInstance.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/EditDistributedInstance.java @@ -7,6 +7,19 @@ */ package org.roda.wui.client.management.distributed; +import java.util.List; + +import org.roda.core.data.v2.synchronization.central.DistributedInstance; +import org.roda.core.data.v2.synchronization.central.UpdateDistributedInstanceRequest; +import org.roda.wui.client.common.NoAsyncCallback; +import org.roda.wui.client.common.UserLogin; +import org.roda.wui.client.common.dialogs.Dialogs; +import org.roda.wui.client.common.utils.JavascriptUtils; +import org.roda.wui.client.services.Services; +import org.roda.wui.common.client.HistoryResolver; +import org.roda.wui.common.client.tools.HistoryUtils; +import org.roda.wui.common.client.tools.ListUtils; + import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -17,19 +30,8 @@ import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; -import config.i18n.client.ClientMessages; -import org.roda.core.data.v2.synchronization.SynchronizingStatus; -import org.roda.core.data.v2.synchronization.central.DistributedInstance; -import org.roda.wui.client.common.NoAsyncCallback; -import org.roda.wui.client.common.UserLogin; -import org.roda.wui.client.common.dialogs.Dialogs; -import org.roda.wui.client.common.utils.JavascriptUtils; -import org.roda.wui.client.services.Services; -import org.roda.wui.common.client.HistoryResolver; -import org.roda.wui.common.client.tools.HistoryUtils; -import org.roda.wui.common.client.tools.ListUtils; -import java.util.List; +import config.i18n.client.ClientMessages; /** * @author Gabriel Barros @@ -99,9 +101,9 @@ private void initStatusButton(DistributedInstance distributedInstance) { buttonChangeStatus.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { - distributedInstance.setStatus(SynchronizingStatus.INACTIVE); - Services services = new Services("Update distributed instance", "update"); - services.distributedInstanceResource(s -> s.updateDistributedInstance(distributedInstance)) + Services services = new Services("Update distributed instance status", "update"); + services + .distributedInstanceResource(s -> s.updateDistributedInstanceSyncStatus(distributedInstance.getId(), false)) .whenComplete((updatedDistributedInstance, error) -> { if (updatedDistributedInstance != null) { HistoryUtils.newHistory(DistributedInstancesManagement.RESOLVER); @@ -116,9 +118,9 @@ public void onClick(ClickEvent clickEvent) { buttonChangeStatus.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { - distributedInstance.setStatus(SynchronizingStatus.ACTIVE); - Services services = new Services("Update distributed instance", "update"); - services.distributedInstanceResource(s -> s.updateDistributedInstance(distributedInstance)) + Services services = new Services("Update distributed instance status", "update"); + services + .distributedInstanceResource(s -> s.updateDistributedInstanceSyncStatus(distributedInstance.getId(), true)) .whenComplete((updatedDistributedInstance, error) -> { if (updatedDistributedInstance != null) { HistoryUtils.newHistory(DistributedInstancesManagement.RESOLVER); @@ -142,11 +144,12 @@ protected void onLoad() { void buttonApplyHandler(ClickEvent e) { if (distributedInstanceDataPanel.isValid()) { DistributedInstance distributedInstanceUpdated = distributedInstanceDataPanel.getDistributedInstance(); - distributedInstance.setName(distributedInstanceUpdated.getName()); - distributedInstance.setDescription(distributedInstanceUpdated.getDescription()); + UpdateDistributedInstanceRequest request = new UpdateDistributedInstanceRequest( + distributedInstanceUpdated.getId(), distributedInstanceUpdated.getName(), + distributedInstanceUpdated.getDescription()); // distributedInstance.setNameIdentifier(distributedInstanceUpdated.getNameIdentifier()); Services services = new Services("Update distributed instance", "update"); - services.distributedInstanceResource(s -> s.updateDistributedInstance(this.distributedInstance)) + services.distributedInstanceResource(s -> s.updateDistributedInstance(request)) .whenComplete((updatedDistributedInstance, error) -> { if (updatedDistributedInstance != null) { HistoryUtils.newHistory(DistributedInstancesManagement.RESOLVER); diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/LocalInstanceConfigurationDataPanel.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/LocalInstanceConfigurationDataPanel.java index 73accfe511..ada4e9e0d9 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/LocalInstanceConfigurationDataPanel.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/LocalInstanceConfigurationDataPanel.java @@ -218,7 +218,7 @@ public LocalInstance getValue() { @UiHandler("buttonTest") void buttonTestHandler(ClickEvent e) { if (isValid()) { - Services services = new Services("Get distributed instance", "get"); + Services services = new Services("Test local instance configuration", "test"); services.distributedInstanceResource(s -> s.testLocalInstanceConfiguration(getLocalInstance())) .whenComplete((result, error) -> { if (result != null) { diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/ShowLocalInstanceConfiguration.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/ShowLocalInstanceConfiguration.java index 0715c4b367..d6b5b26e01 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/ShowLocalInstanceConfiguration.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/distributed/ShowLocalInstanceConfiguration.java @@ -7,20 +7,11 @@ */ package org.roda.wui.client.management.distributed; -import com.google.gwt.core.client.GWT; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.Button; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.Widget; -import config.i18n.client.ClientMessages; +import java.util.List; + import org.roda.core.data.v2.synchronization.SynchronizingStatus; import org.roda.core.data.v2.synchronization.local.LocalInstance; -import org.roda.wui.client.browse.BrowserService; +import org.roda.wui.client.browse.BrowseTop; import org.roda.wui.client.common.NoAsyncCallback; import org.roda.wui.client.common.UserLogin; import org.roda.wui.client.common.dialogs.Dialogs; @@ -28,13 +19,25 @@ import org.roda.wui.client.common.utils.HtmlSnippetUtils; import org.roda.wui.client.ingest.process.ShowJob; import org.roda.wui.client.process.InternalProcess; +import org.roda.wui.client.services.DistributedInstancesRestService; import org.roda.wui.client.services.Services; import org.roda.wui.common.client.HistoryResolver; import org.roda.wui.common.client.tools.HistoryUtils; import org.roda.wui.common.client.tools.ListUtils; import org.roda.wui.common.client.widgets.Toast; -import java.util.List; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Widget; + +import config.i18n.client.ClientMessages; /** * @author Gabriel Barros @@ -45,16 +48,15 @@ public class ShowLocalInstanceConfiguration extends Composite { @Override public void resolve(List historyTokens, AsyncCallback callback) { Services services = new Services("Get local instance", "get"); - services.distributedInstanceResource(s -> s.getLocalInstance()) - .whenComplete((localInstance, error) -> { - if (!localInstance.equals(new LocalInstance())) { - ShowLocalInstanceConfiguration showLocalInstanceConfiguration = new ShowLocalInstanceConfiguration( - localInstance); - callback.onSuccess(showLocalInstanceConfiguration); - } else { - HistoryUtils.newHistory(CreateLocalInstanceConfiguration.RESOLVER); - } - }); + services.distributedInstanceResource(s -> s.getLocalInstance()).whenComplete((localInstance, error) -> { + if (!localInstance.equals(new LocalInstance())) { + ShowLocalInstanceConfiguration showLocalInstanceConfiguration = new ShowLocalInstanceConfiguration( + localInstance); + callback.onSuccess(showLocalInstanceConfiguration); + } else { + HistoryUtils.newHistory(CreateLocalInstanceConfiguration.RESOLVER); + } + }); } @Override @@ -133,7 +135,6 @@ void buttonSubscribeHandler(ClickEvent e) { @Override public void onSuccess(Boolean result) { if (result) { - GWT.log("TEST:::"); Services services = new Services("Subscribe local instance", "subscribe"); services.distributedInstanceResource(s -> s.subscribeLocalInstance(localInstance)) .whenComplete((subscribedLocalInstance, error) -> { @@ -162,13 +163,12 @@ public void onSuccess(final Void nothing) { @UiHandler("buttonSynchronize") void buttonSynchronizeHandler(ClickEvent e) { Services services = new Services("Synchronize", "synchronize"); - services.distributedInstanceResource(s -> s.synchronize(localInstance)) - .whenComplete((job, error) -> { - if (job != null) { - Toast.showInfo("Create Job", "Success"); - HistoryUtils.newHistory(ShowJob.RESOLVER, job.getId()); - } - }); + services.distributedInstanceResource(s -> s.synchronize(localInstance)).whenComplete((job, error) -> { + if (job != null) { + Toast.showInfo("Create Job", "Success"); + HistoryUtils.newHistory(ShowJob.RESOLVER, job.getId()); + } + }); } @UiHandler("buttonUnsubscribe") @@ -190,13 +190,14 @@ public void onSuccess(Boolean result) { super.onSuccess(result); if (result) { Services services = new Services("Delete local instance configuration", "delete"); - services.distributedInstanceResource(s -> s.deleteLocalInstanceConfiguration()) + services.distributedInstanceResource(DistributedInstancesRestService::unsubscribeLocalInstance) .whenComplete((res, error) -> { if (error == null) { super.onSuccess(true); - Dialogs.showConfirmDialog(messages.removeInstanceIdFromRepository(), - messages.removeInstanceIdFromRepositoryMessage(), messages.dialogNo(), messages.dialogYes(), - confirmRemoveInstanceIdentifier()); + Toast.showInfo(messages.successfullyUnsubscribedTitle(), messages.successfullyUnsubscribedMessage()); + HistoryUtils.newHistory(BrowseTop.RESOLVER); + } else { + AsyncCallbackUtils.defaultFailureTreatment(error); } }); } @@ -211,7 +212,7 @@ public void onSuccess(Boolean result) { super.onSuccess(result); if (result) { Services services = new Services("Delete local configuration", "delete"); - services.distributedInstanceResource(s -> s.deleteLocalConfiguration(new LocalInstance())) + services.distributedInstanceResource(DistributedInstancesRestService::deleteLocalConfiguration) .whenComplete((res, error) -> { if (error == null) { Dialogs.showJobRedirectDialog(messages.jobCreatedMessage(), new AsyncCallback() { diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/services/DistributedInstancesRestService.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/services/DistributedInstancesRestService.java index 2dbc4329a3..ba56545b3b 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/services/DistributedInstancesRestService.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/services/DistributedInstancesRestService.java @@ -1,20 +1,14 @@ package org.roda.wui.client.services; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; + import org.fusesource.restygwt.client.DirectRestService; -import org.glassfish.jersey.media.multipart.FormDataMultiPart; -import org.roda.core.data.common.RodaConstants; -import org.roda.core.data.v2.generics.CreateDistributedInstanceRequest; -import org.roda.core.data.v2.generics.CreateLocalInstanceRequest; import org.roda.core.data.v2.jobs.Job; +import org.roda.core.data.v2.synchronization.central.CreateDistributedInstanceRequest; +import org.roda.core.data.v2.synchronization.central.CreateLocalInstanceRequest; import org.roda.core.data.v2.synchronization.central.DistributedInstance; import org.roda.core.data.v2.synchronization.central.DistributedInstances; +import org.roda.core.data.v2.synchronization.central.UpdateDistributedInstanceRequest; import org.roda.core.data.v2.synchronization.local.LocalInstance; import org.roda.wui.api.v2.exceptions.model.ErrorResponseMessage; import org.springframework.http.HttpStatus; @@ -22,9 +16,16 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; -import java.util.List; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; /** * @author António Lindo @@ -36,12 +37,15 @@ public interface DistributedInstancesRestService extends DirectRestService { @RequestMapping(path = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Get distributed instances", description = "Gets distributed instances list", responses = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DistributedInstances.class))), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) DistributedInstances getDistributedInstances(); @RequestMapping(path = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Get distributed instance", description = "Gets a particular distributed instance", responses = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) DistributedInstance getDistributedInstance( @Parameter(description = "The distributed instance id") @PathVariable(name = "id") String id); @@ -49,6 +53,8 @@ DistributedInstance getDistributedInstance( @RequestMapping(path = "/local", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Get local instance", description = "Gets a particular local instance", responses = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LocalInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) LocalInstance getLocalInstance(); @@ -56,6 +62,8 @@ DistributedInstance getDistributedInstance( @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(summary = "Delete distributed instance", description = "Deletes a distributed instance", responses = { @ApiResponse(responseCode = "204", description = "No Content"), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) Void deleteDistributedInstance( @Parameter(description = "The distributed instance id") @PathVariable(name = "id") String id); @@ -64,21 +72,34 @@ Void deleteDistributedInstance( @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "Create distributed instance", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CreateDistributedInstanceRequest.class))), description = "Creates a new distributed instance", responses = { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "409", description = "Conflict", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) DistributedInstance createDistributedInstance( @Parameter(name = "distributed-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) CreateDistributedInstanceRequest distributedInstance); - @RequestMapping(path = "/distributed", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Update distributed instance", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = DistributedInstance.class))), description = "Updates a new distributed instance", responses = { + @RequestMapping(path = "", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Update distributed instance", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = UpdateDistributedInstanceRequest.class))), description = "Updates a new distributed instance", responses = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) DistributedInstance updateDistributedInstance( - @Parameter(name = "distributed-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) DistributedInstance distributedInstance); + @Parameter(name = "distributed-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) UpdateDistributedInstanceRequest updateDistributedInstanceRequest); + + @RequestMapping(path = "{id}/status", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Change the distributed instance status", description = "If activate is set to true the distributed instance status will change to active, otherwise will change its status to inactive", responses = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + DistributedInstance updateDistributedInstanceSyncStatus( + @Parameter(description = "Distributed instance identifier") @PathVariable(name = "id") String id, + @Parameter(name = "activate", required = true, content = @Content(schema = @Schema(implementation = Boolean.class))) @RequestParam(name = "activate") boolean activate); @RequestMapping(path = "/test-configuration", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Test local instance configuration", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))), description = "Tests local instance configuration", responses = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = List.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = List.class)))}) List testLocalInstanceConfiguration( @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); @@ -86,65 +107,48 @@ List testLocalInstanceConfiguration( @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "Create local instance", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CreateLocalInstanceRequest.class))), description = "Creates a new local instance", responses = { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = LocalInstance.class))), - @ApiResponse(responseCode = "409", description = "Conflict", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) LocalInstance createLocalInstance( @Parameter(name = "create-local-instance-request", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) CreateLocalInstanceRequest createLocalInstanceRequest); @RequestMapping(path = "/local/subscribe", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Subscribe local instance", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))), description = "Subscribes local instance", responses = { @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = LocalInstance.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) LocalInstance subscribeLocalInstance( @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); - @RequestMapping(path = "/local/instance-configuration", method = RequestMethod.DELETE) + @RequestMapping(path = "/local/unsubscribe", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "Delete local instance configuration", description = "Deletes local instance configuration", responses = { - @ApiResponse(responseCode = "204", description = "No content"), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Void deleteLocalInstanceConfiguration(); + @Operation(summary = "Unsubscribe a local instance", description = "Unsubscribes a local instance and deletes its configuration", responses = { + @ApiResponse(responseCode = "204", description = "Unsubscribed"), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + Void unsubscribeLocalInstance(); - @RequestMapping(path = "/local/configuration", method = RequestMethod.DELETE) + @RequestMapping(path = "/local", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "Delete local configuration", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))) ,description = "Deletes local configuration", responses = { + @Operation(summary = "Delete local configuration", responses = { @ApiResponse(responseCode = "204", description = "No content"), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Void deleteLocalConfiguration( - @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + Void deleteLocalConfiguration(); @RequestMapping(path = "/synchronize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Synchronize instances", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))) ,description = "Synchronizes instances", responses = { + @Operation(summary = "Synchronize instances", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))), description = "Synchronizes instances", responses = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = Job.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) Job synchronize( @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); - @RequestMapping(path = "/status/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get instance status", description = "Gets instance status", responses = { - @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - DistributedInstance status( - @Parameter(description = "The instance id") @PathVariable(name = "id") String id); - - @RequestMapping(path = "/register", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "Register distributed instance", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))), description = "Registers a distributed instance", responses = { - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = DistributedInstance.class))), - @ApiResponse(responseCode = "409", description = "Conflict", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - DistributedInstance registerDistributedInstance( - @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); - - @RequestMapping(path = "/updates/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get central instance updates", description = "Get central instance updates", responses = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = Long.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) - Long getCentralInstanceUpdates( - @Parameter(description = "The instance id") @PathVariable(name = "id") String id); - @RequestMapping(path = "/local", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Update local instance configuration", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))) ,description = "Updates local instance configuration", responses = { + @Operation(summary = "Update local instance configuration", requestBody = @RequestBody(required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = LocalInstance.class))), description = "Updates local instance configuration", responses = { @ApiResponse(responseCode = "200", description = "Ok", content = @Content(schema = @Schema(implementation = LocalInstance.class))), - @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))}) LocalInstance updateLocalInstanceConfiguration( @Parameter(name = "local-instance", required = true, content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) LocalInstance localInstance); } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/server/browse/BrowserServiceImpl.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/server/browse/BrowserServiceImpl.java index 3dda0c4268..b63bf77d29 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/server/browse/BrowserServiceImpl.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/server/browse/BrowserServiceImpl.java @@ -75,110 +75,6 @@ protected void doUnexpectedFailure(Throwable e) { super.doUnexpectedFailure(e); } - @Override - public BrowseAIPBundle retrieveBrowseAIPBundle(String aipId, String localeString, List aipFieldsToReturn) - throws AuthorizationDeniedException, GenericException, NotFoundException, RequestNotValidException { - User user = UserUtility.getUser(getThreadLocalRequest()); - Locale locale = ServerTools.parseLocale(localeString); - return Browser.retrieveBrowseAipBundle(user, aipId, locale, aipFieldsToReturn); - } - - private SelectedItems getAllItemsByClass(String selectedClass) { - if (selectedClass == null || Void.class.getName().equals(selectedClass)) { - return new SelectedItemsNone<>(); - } else { - return new SelectedItemsAll<>(selectedClass); - } - } - - @Override - public DistributedInstance createDistributedInstance(DistributedInstance distributedInstance) - throws AuthorizationDeniedException, AlreadyExistsException, NotFoundException, GenericException, - RequestNotValidException, IllegalOperationException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.createDistributedInstance(user, distributedInstance); - } - - @Override - public DistributedInstances listDistributedInstances() - throws AuthorizationDeniedException, IOException, GenericException, RequestNotValidException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.listDistributedInstances(user); - } - - @Override - public DistributedInstance retrieveDistributedInstance(String distributedInstanceId) - throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.retrieveDistributedInstance(user, distributedInstanceId); - } - - @Override - public DistributedInstance updateDistributedInstance(DistributedInstance distributedInstance) - throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.updateDistributedInstance(user, distributedInstance); - } - - @Override - public void deleteDistributedInstance(String distributedInstanceId) - throws NotFoundException, GenericException, AuthorizationDeniedException, RequestNotValidException { - User user = UserUtility.getUser(getThreadLocalRequest()); - RODAInstance.deleteDistributedInstance(user, distributedInstanceId); - } - - @Override - public void createLocalInstance(LocalInstance localInstance) throws AuthorizationDeniedException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - RODAInstance.createLocalInstance(user, localInstance); - } - - @Override - public LocalInstance retrieveLocalInstance() throws AuthorizationDeniedException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.retrieveLocalInstance(user); - } - - @Override - public void deleteLocalInstanceConfiguration() throws AuthorizationDeniedException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - RODAInstance.deleteLocalInstanceConfiguration(user); - } - - @Override - public void updateLocalInstanceConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - RODAInstance.updateLocalInstanceConfiguration(user, localInstance); - } - - @Override - public List testLocalInstanceConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException, AuthenticationDeniedException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.testLocalInstanceConfiguration(user, localInstance); - } - - @Override - public LocalInstance subscribeLocalInstance(LocalInstance localInstance) throws AuthorizationDeniedException, - GenericException, AuthenticationDeniedException, RequestNotValidException, NotFoundException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.subscribeLocalInstance(user, localInstance); - } - - @Override - public Job synchronizeBundle(LocalInstance localInstance) - throws AuthorizationDeniedException, GenericException, NotFoundException, RequestNotValidException { - User user = UserUtility.getUser(getThreadLocalRequest()); - return RODAInstance.synchronizeBundle(user, localInstance); - } - - public void removeLocalConfiguration(LocalInstance localInstance) - throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException { - User user = UserUtility.getUser(getThreadLocalRequest()); - RODAInstance.removeLocalConfiguration(user, localInstance); - } - public String getCrontabValue(String locale) { String syncSchedule = RodaCoreFactory.getRodaConfigurationAsString("core.synchronization.scheduleInfo"); String description = null; diff --git a/roda-ui/roda-wui/src/main/resources/config/i18n/client/ClientMessages.properties b/roda-ui/roda-wui/src/main/resources/config/i18n/client/ClientMessages.properties index f922095aea..23346aa833 100644 --- a/roda-ui/roda-wui/src/main/resources/config/i18n/client/ClientMessages.properties +++ b/roda-ui/roda-wui/src/main/resources/config/i18n/client/ClientMessages.properties @@ -1653,6 +1653,8 @@ applyInstanceIdToRepository:Apply instance identifier to all repository applyInstanceIdToRepositoryMessage:You will apply the instance identifier to the all repository. From this moment the system will start to create the entities with the instance identifier as well. removeLocalConfiguration:Remove Local Instance configuration. removeLocalConfigurationMessage:You will remove the local configuration. From this moment the you can not be able to synchronize with the Central Repository. +successfullyUnsubscribedTitle:Unsubscribed +successfullyUnsubscribedMessage:Successfully unsubscribed removeInstanceIdFromRepository:Remove instance identifier from all repository. removeInstanceIdFromRepositoryMessage:You will remove the instance identifier from all repository. From this moment the system will start to create the entities without the instance identifier. This action may take some time, are you sure you want to remove all identifiers ? synchronizingStatus:{0} diff --git a/scripts/distributed_instance_dev.sh b/scripts/distributed_instance_dev.sh new file mode 100755 index 0000000000..35d1498dd0 --- /dev/null +++ b/scripts/distributed_instance_dev.sh @@ -0,0 +1,45 @@ +#! /bin/bash + +# Version +STATUS=${1:-'up'} +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +RODA_PROJECT_DIR=$(readlink -f "${SCRIPT_DIR}/..") + +function up() { + echo "Starting distributed instance" + mkdir -p "$HOME/.roda_central/data/storage" + mkdir -p "$HOME/.roda_local/data/storage" + + docker compose -f "$RODA_PROJECT_DIR/deploys/distributed/central/docker-compose-dev.yaml" up -d + docker compose -f "$RODA_PROJECT_DIR/deploys/distributed/local/docker-compose-dev.yaml" up -d + + echo "Run 'mvn -pl roda-ui/roda-wui -am spring-boot:run -Pdebug-main-central' to start the central instance" + echo "Open another terminal and run 'mvn -pl roda-ui/roda-wui -am spring-boot:run -Pdebug-main-local' to start the local instance" +} + +function down() { + echo "Stopping distributed instance" + docker compose -f "$RODA_PROJECT_DIR/deploys/distributed/central/docker-compose-dev.yaml" down -v + docker compose -f "$RODA_PROJECT_DIR/deploys/distributed/local/docker-compose-dev.yaml" down -v +} + +function clean() { + echo "Cleaning distributed instance environment" + down + rm -rf "$HOME/.roda_central/" + rm -rf "$HOME/.roda_local/" +} + +if [ "$STATUS" == 'up' ]; then + up +elif [ "$STATUS" == 'down' ]; then + down +elif [ "$STATUS" == 'clean' ]; then + clean +else + echo "Invalid status: $STATUS" + echo "Syntax: $0 [up|down|clean]" + exit 1 +fi + +exit 0