diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml
index 80cd3d6fa0..da604dde9f 100644
--- a/amps/ags/pom.xml
+++ b/amps/ags/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-amps
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml
index 2a3bd30cbd..369f16ff48 100644
--- a/amps/ags/rm-automation/pom.xml
+++ b/amps/ags/rm-automation/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-parent
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
index c3c3778968..d0a21c4cb0 100644
--- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-automation-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java
index 63ba5045a8..0e41e74dab 100644
--- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java
@@ -46,4 +46,13 @@ public class RetentionSchedule extends TestModel
private boolean isRecordLevel;
private boolean isUnpublishedUpdates;
private List actions;
+
+ public boolean getIsRecordLevel()
+ {
+ return isRecordLevel;
+ }
+
+ public void setIsRecordLevel(boolean recordLevel) {
+ isRecordLevel = recordLevel;
+ }
}
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepCollection.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepCollection.java
new file mode 100644
index 0000000000..a0e13dc630
--- /dev/null
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepCollection.java
@@ -0,0 +1,33 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.rm.community.model.retentionschedule;
+
+import org.alfresco.rest.core.RestModels;
+
+public class RetentionScheduleStepCollection extends RestModels
+{
+}
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepEntry.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepEntry.java
new file mode 100644
index 0000000000..715185236b
--- /dev/null
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleStepEntry.java
@@ -0,0 +1,38 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.rm.community.model.retentionschedule;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.alfresco.rest.core.RestModels;
+
+@Data
+public class RetentionScheduleStepEntry extends RestModels
+{
+ @JsonProperty
+ private RetentionScheduleActionDefinition entry;
+}
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java
index 83a2a142d4..ba0db9b0de 100644
--- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java
@@ -28,7 +28,9 @@ package org.alfresco.rest.rm.community.requests.gscore.api;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule;
+import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleActionDefinition;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleCollection;
+import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleStepCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
@@ -122,4 +124,75 @@ public class RetentionScheduleAPI extends RMModelRequest
{
return getRetentionSchedule(recordCategoryId, EMPTY);
}
+
+ /**
+ * Creates a step in the retention schedule.
+ *
+ * @param retentionScheduleActionDefinition The retentionScheduleActionDefinition model
+ * @param retentionScheduleId The identifier of a retention schedule id
+ * @param parameters The URL parameters to add
+ * @return The created {@link RetentionScheduleActionDefinition}
+ * @throws RuntimeException for the following cases:
+ *
+ * - {@code retentionScheduleId} is not a valid format or {@code retentionScheduleId} is invalid
+ * - authentication fails
+ * - current user does not have permission to add children to {@code retentionScheduleId}
+ * - {@code retentionScheduleId} does not exist
+ * - new name clashes with an existing node in the current parent container
+ *
+ */
+ public RetentionScheduleActionDefinition createRetentionScheduleStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition, String retentionScheduleId, String parameters)
+ {
+ mandatoryString("retentionScheduleId", retentionScheduleId);
+ mandatoryObject("retentionScheduleActionDefinition", retentionScheduleActionDefinition);
+
+ return getRmRestWrapper().processModel(RetentionScheduleActionDefinition.class, requestWithBody(
+ POST,
+ toJson(retentionScheduleActionDefinition),
+ "retention-schedules/{retentionScheduleId}/retention-steps",
+ retentionScheduleId,
+ parameters
+ ));
+ }
+
+ /**
+ * See {@link #createRetentionScheduleStep(RetentionScheduleActionDefinition, String)} (RetentionSchedule, String, String)}
+ */
+ public RetentionScheduleActionDefinition createRetentionScheduleStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition, String retentionScheduleId)
+ {
+ return createRetentionScheduleStep(retentionScheduleActionDefinition, retentionScheduleId, EMPTY);
+ }
+
+ /**
+ * Gets the retentionSchedule of a record category.
+ *
+ * @param retentionScheduleId The identifier of a record category
+ * @param parameters The URL parameters to add
+ * @return The {@link RetentionScheduleActionDefinition} for the given {@code recordCategoryId}
+ * @throws RuntimeException for the following cases:
+ *
+ * - authentication fails
+ * - current user does not have permission to read {@code recordCategoryId}
+ * - {@code recordCategoryId} does not exist
+ *
+ */
+ public RetentionScheduleStepCollection getRetentionScheduleStep(String retentionScheduleId, String parameters)
+ {
+ mandatoryString("retentionScheduleId", retentionScheduleId);
+
+ return getRmRestWrapper().processModels(RetentionScheduleStepCollection.class, simpleRequest(
+ GET,
+ "retention-schedules/{retentionScheduleId}/retention-steps?{parameters}",
+ retentionScheduleId,
+ parameters
+ ));
+ }
+
+ /**
+ * See {@link #getRetentionScheduleStep(String, String)}
+ */
+ public RetentionScheduleStepCollection getRetentionScheduleStep(String recordCategoryId)
+ {
+ return getRetentionScheduleStep(recordCategoryId, EMPTY);
+ }
}
\ No newline at end of file
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java
new file mode 100644
index 0000000000..60359e6f74
--- /dev/null
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java
@@ -0,0 +1,358 @@
+/*-
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.rm.community.retentionschedule;
+
+import org.alfresco.rest.rm.community.base.BaseRMRestTest;
+import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
+import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule;
+import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleActionDefinition;
+import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleStepCollection;
+import org.alfresco.rest.v0.RMRolesAndActionsAPI;
+import org.alfresco.utility.model.UserModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID;
+import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
+import static org.alfresco.utility.data.RandomData.getRandomName;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.CONFLICT;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.FORBIDDEN;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+import static org.springframework.http.HttpStatus.OK;
+import static org.springframework.http.HttpStatus.UNAUTHORIZED;
+import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * Retention schedule step test case
+ */
+public class RetentionScheduleStepTests extends BaseRMRestTest
+{
+ private RecordCategory recordCategory;
+ private RetentionSchedule createdRetentionSchedule;
+ private final RetentionScheduleActionDefinition retentionScheduleActionDefinition = new RetentionScheduleActionDefinition();
+ private RetentionScheduleActionDefinition createdRetentionActionDefinition;
+ private UserModel nonRMuser;
+ private final List recordCategories = new ArrayList<>();
+ private static final String TEST_USER = "testUser";
+ private static final String RECORD_CATEGORY = "recordCategory";
+ private static final String PERIOD_PROPERTY = "cm:created";
+ private static final String AUTHORITY = "authority";
+ private static final String INSTRUCTIONS = "instructions";
+ private static final int PERIOD_AMOUNT = 5;
+ private static final String PERIOD = "month";
+ private static final List EVENTS = Arrays.asList("case_closed","abolished");
+ private static final String TRANSFER_STEP = "transfer";
+ private static final String RETAIN_STEP = "retain";
+ private static final String INVALID_PERIOD = "random";
+ private static final String CUTOFF_STEP = "cutoff";
+ private static final String DESTROY_STEP = "destroy";
+ private static final String INVALID_PASSWORD = "wrongPassword";
+
+ @Autowired
+ private RMRolesAndActionsAPI rmRolesAndActionsAPI;
+
+ @BeforeClass(alwaysRun = true)
+ public void preconditionForRetentionScheduleStepTests()
+ {
+ createRMSiteIfNotExists();
+ // create a non rm user
+ nonRMuser = dataUser.createRandomTestUser(TEST_USER);
+ //Create record category
+ recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
+ recordCategories.add(recordCategory.getId());
+ RetentionSchedule retentionSchedule = new RetentionSchedule();
+ retentionSchedule.setAuthority(AUTHORITY + getRandomAlphanumeric());
+ retentionSchedule.setInstructions(INSTRUCTIONS + getRandomAlphanumeric());
+ retentionSchedule.setIsRecordLevel(false);
+ //Create retention schedule with a valid user
+ createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
+ .createRetentionSchedule(retentionSchedule, recordCategory.getId());
+
+ retentionScheduleActionDefinition.setName(RETAIN_STEP);
+ retentionScheduleActionDefinition.setDescription(INSTRUCTIONS);
+ retentionScheduleActionDefinition.setPeriodAmount(PERIOD_AMOUNT);
+ retentionScheduleActionDefinition.setPeriodProperty(PERIOD_PROPERTY);
+ retentionScheduleActionDefinition.setPeriod(PERIOD);
+ retentionScheduleActionDefinition.setCombineDispositionStepConditions(false);
+ retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(true);
+ retentionScheduleActionDefinition.setEvents(EVENTS);
+ }
+
+ @Test(priority = 1)
+ public void createRetentionScheduleStepFor422()
+ {
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ //Creating the first action "transfer" should give 422
+ actionDefinition.setName(TRANSFER_STEP);
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(UNPROCESSABLE_ENTITY);
+ }
+
+ @Test(priority = 2)
+ public void createRetentionScheduleStepWithInvalidPeriodValue()
+ {
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ actionDefinition.setName(RETAIN_STEP);
+ //Invalid period value
+ actionDefinition.setPeriod(INVALID_PERIOD);
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(BAD_REQUEST);
+ }
+
+ @Test(priority = 3)
+ public void createRetentionScheduleWithInvalidStep()
+ {
+ RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
+ recordCategories.add(recordCategory.getId());
+ RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ actionDefinition.setName(RETAIN_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
+ actionDefinition1.setName(TRANSFER_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
+ actionDefinition2.setName(CUTOFF_STEP);
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2,retentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(CONFLICT);
+ }
+
+ @Test(priority = 4)
+ public void createRetentionScheduleWithInvalidStepAfterDestroy()
+ {
+ RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
+ recordCategories.add(recordCategory.getId());
+ RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ actionDefinition.setName(RETAIN_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
+ actionDefinition1.setName(DESTROY_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
+ actionDefinition2.setName(CUTOFF_STEP);
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2,retentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(CONFLICT);
+ }
+
+ @Test(priority = 5)
+ public void createRetentionScheduleWithSameStep()
+ {
+ RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
+ recordCategories.add(recordCategory.getId());
+ RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ actionDefinition.setName(RETAIN_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
+ actionDefinition1.setName(RETAIN_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
+
+ // Verify the status code
+ assertStatusCode(CONFLICT);
+ }
+
+ @Test(priority = 6)
+ public void createRetentionScheduleWithMultipleTransferStep()
+ {
+ RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
+ recordCategories.add(recordCategory.getId());
+ RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
+ RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
+ actionDefinition.setName(RETAIN_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
+
+ assertStatusCode(CREATED);
+
+ RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
+ actionDefinition1.setName(TRANSFER_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId());
+
+ RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
+ actionDefinition2.setName(TRANSFER_STEP);
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(CREATED);
+ }
+
+ @Test(priority = 7)
+ public void createRetentionScheduleStepFor201()
+ {
+ //Create retention schedule action definition
+ createdRetentionActionDefinition = getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(CREATED);
+ // Find this retention schedule is created one or not
+ assertEquals(createdRetentionActionDefinition.getName(), retentionScheduleActionDefinition.getName());
+ assertEquals(createdRetentionActionDefinition.getDescription(), retentionScheduleActionDefinition.getDescription());
+ assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionScheduleActionDefinition.getPeriodAmount());
+ assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionScheduleActionDefinition.isCombineDispositionStepConditions());
+ assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent());
+ }
+
+ @Test(priority = 8)
+ public void createRetentionScheduleStepFor401()
+ {
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(UNAUTHORIZED);
+ }
+
+ @Test(priority = 9)
+ public void createRetentionScheduleStepFor403()
+ {
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(FORBIDDEN);
+ }
+
+ @Test(priority = 10)
+ public void retentionScheduleStepFor400()
+ {
+ getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId());
+ // Verify the status code
+ assertStatusCode(BAD_REQUEST);
+ }
+
+ @Test(priority = 11)
+ public void createRetentionScheduleStepFor404()
+ {
+ //Create retention schedule action definition
+ getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(retentionScheduleActionDefinition,getRandomAlphanumeric());
+ // Verify the status code
+ assertStatusCode(NOT_FOUND);
+ }
+
+ @Test(priority = 12)
+ public void retentionScheduleStepFor403()
+ {
+ // Get retention schedule steps with user having no rights
+ getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).getRetentionScheduleStep(createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(FORBIDDEN);
+ }
+
+ @Test(priority = 13)
+ public void retentionScheduleStepFor401()
+ {
+ getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(UNAUTHORIZED);
+ }
+
+ @Test(priority = 14)
+ public void retentionScheduleStepWith200()
+ {
+ RetentionScheduleStepCollection receiveRetentionStepCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(createdRetentionSchedule.getId());
+ // Verify the status code
+ assertStatusCode(OK);
+ receiveRetentionStepCollection.getEntries().forEach(c ->
+ {
+ RetentionScheduleActionDefinition retentionActionDef = c.getEntry();
+ assertNotNull(retentionActionDef.getId());
+ // Find this retention schedule is created one or not
+ assertEquals(createdRetentionActionDefinition.getId(), retentionActionDef.getId());
+ assertEquals(createdRetentionActionDefinition.getName(), retentionActionDef.getName());
+ assertEquals(createdRetentionActionDefinition.getDescription(), retentionActionDef.getDescription());
+ assertEquals(createdRetentionActionDefinition.getPeriod(), retentionActionDef.getPeriod());
+ assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionActionDef.getPeriodAmount());
+ assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionActionDef.isCombineDispositionStepConditions());
+ assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionActionDef.isEligibleOnFirstCompleteEvent());
+ });
+ }
+
+ private RetentionSchedule createRetentionSchedule(RecordCategory recordCategory)
+ {
+ RetentionSchedule retentionSchedule = new RetentionSchedule();
+ retentionSchedule.setAuthority(AUTHORITY + getRandomAlphanumeric());
+ retentionSchedule.setInstructions(INSTRUCTIONS + getRandomAlphanumeric());
+ retentionSchedule.setIsRecordLevel(false);
+ //Create retention schedule with a valid user
+ retentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
+ .createRetentionSchedule(retentionSchedule, recordCategory.getId());
+ // Verify the status code
+ assertStatusCode(CREATED);
+ return retentionSchedule;
+ }
+
+ private static RetentionScheduleActionDefinition getRetentionScheduleActionDefinition()
+ {
+ RetentionScheduleActionDefinition actionDefinition = new RetentionScheduleActionDefinition();
+ actionDefinition.setDescription(INSTRUCTIONS);
+ actionDefinition.setPeriodAmount(PERIOD_AMOUNT);
+ actionDefinition.setPeriodProperty(PERIOD_PROPERTY);
+ actionDefinition.setPeriod(PERIOD);
+ actionDefinition.setCombineDispositionStepConditions(false);
+ actionDefinition.setEligibleOnFirstCompleteEvent(true);
+ actionDefinition.setEvents(EVENTS);
+ return actionDefinition;
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void cleanUpRetentionScheduleStepTests()
+ {
+ rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(),
+ getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategory.getName());
+ recordCategories.forEach(this::deleteRecordCategory);
+ dataUser.deleteUser(nonRMuser);
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java
index 017530e385..c15c6774a4 100644
--- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java
@@ -145,7 +145,7 @@ public class RetentionScheduleTests extends BaseRMRestTest
boolean isRecordLevel = false;
retentionSchedule.setAuthority(authority);
retentionSchedule.setInstructions(instructions);
- retentionSchedule.setRecordLevel(isRecordLevel);
+ retentionSchedule.setIsRecordLevel(isRecordLevel);
//Create retention schedule with a valid user
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
@@ -155,7 +155,7 @@ public class RetentionScheduleTests extends BaseRMRestTest
assertStatusCode(CREATED);
assertEquals(createdRetentionSchedule.getAuthority(), authority);
assertEquals(createdRetentionSchedule.getInstructions(), instructions);
- assertFalse(createdRetentionSchedule.isRecordLevel());
+ assertFalse(createdRetentionSchedule.getIsRecordLevel());
assertNotNull(createdRetentionSchedule.getId());
}
@@ -254,7 +254,7 @@ public class RetentionScheduleTests extends BaseRMRestTest
assertEquals(createdRetentionSchedule.getParentId(),retentionSchedule.getParentId());
assertEquals(createdRetentionSchedule.getAuthority(), retentionSchedule.getAuthority());
assertEquals(createdRetentionSchedule.getInstructions(), retentionSchedule.getInstructions());
- assertEquals(createdRetentionSchedule.isRecordLevel(), retentionSchedule.isRecordLevel());
+ assertEquals(createdRetentionSchedule.getIsRecordLevel(), retentionSchedule.getIsRecordLevel());
assertEquals(createdRetentionSchedule.isUnpublishedUpdates(), retentionSchedule.isUnpublishedUpdates());
});
}
diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml
index b0163be9a1..7d13b2a3c8 100644
--- a/amps/ags/rm-community/pom.xml
+++ b/amps/ags/rm-community/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-parent
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml
index 970c73a5ee..efb01d2730 100644
--- a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml
+++ b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml
@@ -31,6 +31,7 @@
+
@@ -154,6 +155,13 @@
+
+
+
+
+
+
+
diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml
index a7cf0395a8..37c330acea 100644
--- a/amps/ags/rm-community/rm-community-repo/pom.xml
+++ b/amps/ags/rm-community/rm-community-repo/pom.xml
@@ -8,7 +8,7 @@
org.alfresco
alfresco-governance-services-community-repo-parent
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java
index 7cd3334d67..b392993023 100644
--- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java
@@ -35,9 +35,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinitionImpl;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
@@ -56,6 +59,8 @@ import org.alfresco.rm.rest.api.model.Record;
import org.alfresco.rm.rest.api.model.RecordCategory;
import org.alfresco.rm.rest.api.model.RecordCategoryChild;
import org.alfresco.rm.rest.api.model.RecordFolder;
+import org.alfresco.rm.rest.api.model.RetentionPeriod;
+import org.alfresco.rm.rest.api.model.RetentionSteps;
import org.alfresco.rm.rest.api.model.Transfer;
import org.alfresco.rm.rest.api.model.TransferChild;
import org.alfresco.rm.rest.api.model.TransferContainer;
@@ -75,8 +80,9 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
-
-import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Utility class containing Alfresco and RM java services required by the API
@@ -88,6 +94,9 @@ import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagement
public class ApiNodesModelFactory
{
+ /** Logger */
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiNodesModelFactory.class);
+
// excluded namespaces (aspects, properties, assoc types)
public static final List EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
@@ -109,6 +118,7 @@ public class ApiNodesModelFactory
private PersonService personService;
private DispositionService dispositionService;
private ServiceRegistry serviceRegistry;
+ private RecordsManagementServiceRegistry services;
public NodeService getNodeService()
{
@@ -160,6 +170,11 @@ public class ApiNodesModelFactory
this.serviceRegistry = serviceRegistry;
}
+ public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry services)
+ {
+ this.services = services;
+ }
+
/**
* Helper method that sets the basic information for most of the node types.
*
@@ -511,15 +526,15 @@ public class ApiNodesModelFactory
}
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
{
- if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
+ if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordFolder(true);
}
- if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
+ if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordCategory(false);
}
- if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
+ if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
}
@@ -530,11 +545,11 @@ public class ApiNodesModelFactory
}
else
{
- if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
+ if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordFolder(false);
}
- if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
+ if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordCategory(true);
}
@@ -543,13 +558,28 @@ public class ApiNodesModelFactory
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
recordCategoryChild.setHasRetentionSchedule(ds != null);
}
- if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
+ if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsClosed(null);
}
}
}
+ private boolean isRecordCategoryChildClosed(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List includeParam)
+ {
+ return (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED));
+ }
+
+ private boolean isRecordCategory(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List includeParam)
+ {
+ return (!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY));
+ }
+
+ private boolean isRecordFolder(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List includeParam)
+ {
+ return (!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER));
+ }
+
/**
* Utility method that maps record specific fields
@@ -572,7 +602,8 @@ public class ApiNodesModelFactory
{
Serializable val = info.getProperties().get(ContentModel.PROP_CONTENT);
- if ((val != null) && (val instanceof ContentData)) {
+ if (val instanceof ContentData)
+ {
ContentData cd = (ContentData)val;
String mimeType = cd.getMimetype();
String mimeTypeName = serviceRegistry.getMimetypeService().getDisplaysByMimetype().get(mimeType);
@@ -914,7 +945,7 @@ public class ApiNodesModelFactory
}
retentionSchedule.setInstructions(dispositionSchedule.getDispositionInstructions());
retentionSchedule.setAuthority(dispositionSchedule.getDispositionAuthority());
- retentionSchedule.setRecordLevel(dispositionSchedule.isRecordLevelDisposition());
+ retentionSchedule.setIsRecordLevel(dispositionSchedule.isRecordLevelDisposition());
boolean unpublishedUpdates = dispositionSchedule.getDispositionActionDefinitions().stream()
.map(DispositionActionDefinition::getNodeRef)
@@ -951,9 +982,9 @@ public class ApiNodesModelFactory
retentionScheduleActionDefinition.setName(dispositionActionDefinition.getName());
retentionScheduleActionDefinition.setDescription(dispositionActionDefinition.getDescription());
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent());
- if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null)
+ if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null)
{
- retentionScheduleActionDefinition.setCombineDispositionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
+ retentionScheduleActionDefinition.setCombineDispositionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
}
retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation());
if (dispositionActionDefinition.getGhostOnDestroy() != null)
@@ -970,9 +1001,11 @@ public class ApiNodesModelFactory
*/
private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
- if(dispositionActionDefinition.getPeriodProperty() != null) {
+ if(dispositionActionDefinition.getPeriodProperty() != null)
+ {
retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService));
}
+
String period = dispositionActionDefinition.getPeriod().toString();
if (!period.isEmpty())
{
@@ -982,19 +1015,22 @@ public class ApiNodesModelFactory
// period -> 'month'
// periodAmount -> 10
String[] periodArray = period.split("\\|");
+
if (periodArray.length > 0)
{
retentionScheduleActionDefinition.setPeriod(periodArray[0]);
}
+
if (periodArray.length > 1)
{
try
{
retentionScheduleActionDefinition.setPeriodAmount(Integer.parseInt(periodArray[1]));
}
- catch (NumberFormatException e)
+ catch (NumberFormatException numberFormatException)
{
- throw new NumberFormatException("Error parsing period amount: " + e.getMessage());
+ LOGGER.error("Error parsing period amount: {}{}", numberFormatException.getMessage(), periodArray[1], numberFormatException);
+ throw numberFormatException;
}
}
}
@@ -1033,4 +1069,83 @@ public class ApiNodesModelFactory
retentionSchedule.setActions(actions);
}
}
+
+ /**
+ * this method is used for creation of retention schedule action definition params
+ * @param nodeInfo retention schedule action definition
+ * @return Map
+ */
+ public Map createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo)
+ {
+ Map actionDefinitionParams= new HashMap<>();
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, nodeInfo.getName());
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, nodeInfo.getDescription());
+ StringBuilder retentionPeriod = new StringBuilder(nodeInfo.getPeriod()).append("|");
+ if(isPeriodAmountApplicable(nodeInfo.getPeriod()))
+ {
+ retentionPeriod.append(nodeInfo.getPeriodAmount());
+ }
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, retentionPeriod.toString());
+ QName periodProperty = QName.createQName(nodeInfo.getPeriodProperty(), namespaceService);
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD_PROPERTY, periodProperty);
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT_COMBINATION,
+ nodeInfo.isEligibleOnFirstCompleteEvent());
+ actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS,
+ nodeInfo.isCombineDispositionStepConditions());
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION,
+ nodeInfo.getLocation());
+ List inputEvents = nodeInfo.getEvents();
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents);
+ if (RetentionSteps.DESTROY.stepName.equals(nodeInfo.getName()) && nodeInfo.isRetainRecordMetadataAfterDestruction())
+ {
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost");
+ }
+ else
+ {
+ actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "delete");
+ }
+ return actionDefinitionParams;
+ }
+
+ /**
+ * this method is used retrieve retention schedule action details
+ * @param retentionScheduleNodeRef nodeRef
+ * @return List
+ */
+ public List getRetentionActions(NodeRef retentionScheduleNodeRef)
+ {
+ List assocs = nodeService.getChildAssocs(
+ retentionScheduleNodeRef,
+ RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
+ RegexQNamePattern.MATCH_ALL);
+ // we are getting disposition action definitions based on retention schedule child association.
+ // setting the index value for each action.
+ List actions;
+ actions = IntStream.range(0, assocs.size())
+ .mapToObj(index ->
+ {
+ ChildAssociationRef assoc = assocs.get(index);
+ return new DispositionActionDefinitionImpl(
+ services.getRecordsManagementEventService(),
+ services.getRecordsManagementActionService(),
+ nodeService,
+ assoc.getChildRef(),
+ index);
+ })
+ .collect(Collectors.toList());
+ return actions;
+ }
+
+ /**
+ * this method is used to check period amount applicable or not for particular period
+ * @param period period
+ * @return boolean
+ */
+ private boolean isPeriodAmountApplicable(String period)
+ {
+ // periodAmount property only applicable for following periods
+ // day, week, month, quarter, year and duration
+ return period.equals(RetentionPeriod.DAY.periodName) || period.equals(RetentionPeriod.MONTH.periodName) || period.equals(RetentionPeriod.QUARTER.periodName)
+ || period.equals(RetentionPeriod.WEEK.periodName) || period.equals(RetentionPeriod.XML_DURATION.periodName) || period.equals(RetentionPeriod.YEAR.periodName);
+ }
}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionEvents.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionEvents.java
new file mode 100644
index 0000000000..76b330ce7f
--- /dev/null
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionEvents.java
@@ -0,0 +1,56 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rm.rest.api.model;
+
+/**
+ * Retention event values
+ */
+public enum RetentionEvents
+{
+ CASE_CLOSED("case_closed"),
+ ABOLISHED("abolished"),
+ RE_DESIGNATED("re_designated"),
+ NO_LONGER_NEEDED("no_longer_needed"),
+ SUPERSEDED("superseded"),
+ VERSIONED("versioned"),
+ STUDY_COMPLETE("study_complete"),
+ TRAINING_COMPLETE("training_complete"),
+ TRANSFERRED_INACTIVE_STORAGE("related_record_trasfered_inactive_storage"),
+ OBSOLETE("obsolete"),
+ ALLOWANCES_GRANTED_TERMINATED("all_allowances_granted_are_terminated"),
+ WGI_ACTION_COMPLETE("WGI_action_complete"),
+ SEPARATION("separation"),
+ CASE_COMPLETE("case_complete"),
+ DECLASSIFICATION_REVIEW("declassification_review");
+
+ public final String eventName;
+
+ RetentionEvents(String eventName)
+ {
+ this.eventName = eventName;
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionPeriod.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionPeriod.java
new file mode 100644
index 0000000000..21bfb4cdf6
--- /dev/null
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionPeriod.java
@@ -0,0 +1,55 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rm.rest.api.model;
+
+/**
+ * Retention period values
+ */
+public enum RetentionPeriod
+{
+ DAY("day"),
+ END_OF_FINANCIAL_MONTH("fmend"),
+ END_OF_FINANCIAL_QUARTER("fqend"),
+ END_OF_FINANCIAL_YEAR("fyend"),
+ IMMEDIATELY("immediately"),
+ END_OF_MONTH("monthend"),
+ END_OF_QUARTER("quarterend"),
+ END_OF_YEAR("yearend"),
+ MONTH("month"),
+ NONE("none"),
+ QUARTER("quarter"),
+ WEEK("week"),
+ XML_DURATION("duration"),
+ YEAR("year");
+
+ public final String periodName;
+
+ RetentionPeriod(String periodName)
+ {
+ this.periodName = periodName;
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java
index 1f698d0f33..d1869ebf86 100644
--- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java
@@ -27,6 +27,7 @@
package org.alfresco.rm.rest.api.model;
import lombok.Data;
+
import java.util.List;
/**
@@ -42,4 +43,14 @@ public class RetentionSchedule
private boolean isRecordLevel;
private boolean isUnpublishedUpdates;
private List actions;
-}
+
+ public boolean getIsRecordLevel()
+ {
+ return isRecordLevel;
+ }
+
+ public void setIsRecordLevel(boolean recordLevel)
+ {
+ isRecordLevel = recordLevel;
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java
new file mode 100644
index 0000000000..e8ecbd32bf
--- /dev/null
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java
@@ -0,0 +1,46 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rm.rest.api.model;
+
+/**
+ * Retention steps values
+ */
+public enum RetentionSteps
+{
+ RETAIN("retain"),
+ CUTOFF("cutoff"),
+ TRANSFER("transfer"),
+ ACCESSION("accession"),
+ DESTROY("destroy");
+
+ public final String stepName;
+
+ RetentionSteps(String stepName)
+ {
+ this.stepName = stepName;
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java
new file mode 100644
index 0000000000..8e4c443751
--- /dev/null
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java
@@ -0,0 +1,243 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rm.rest.api.retentionschedule;
+
+import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl;
+import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
+import org.alfresco.rest.framework.WebApiDescription;
+import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
+import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
+import org.alfresco.rest.framework.core.exceptions.UnprocessableContentException;
+import org.alfresco.rest.framework.resource.RelationshipResource;
+import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
+import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
+import org.alfresco.rm.rest.api.model.RetentionEvents;
+import org.alfresco.rm.rest.api.model.RetentionPeriod;
+import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
+import org.alfresco.rm.rest.api.model.RetentionSteps;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
+import static org.alfresco.util.ParameterCheck.mandatory;
+
+/**
+ * Retention schedule action relation is used to perform the retention schedule step operations.
+ */
+@RelationshipResource(name = "retention-steps", entityResource = RetentionScheduleEntityResource.class, title = "Retention Schedule Action")
+public class RetentionScheduleActionRelation implements RelationshipResourceAction.Read,
+ RelationshipResourceAction.Create
+{
+ private FilePlanComponentsApiUtils apiUtils;
+ protected NodeService nodeService;
+ private RecordsManagementServiceRegistry service;
+ private ApiNodesModelFactory nodesModelFactory;
+
+ public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
+ {
+ this.apiUtils = apiUtils;
+ }
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
+ {
+ this.nodesModelFactory = nodesModelFactory;
+ }
+
+ public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry service)
+ {
+ this.service = service;
+ }
+
+ @Override
+ @WebApiDescription(title="Create a retention schedule step for the particular retention schedule using the 'retentionScheduleId'")
+ public List create(String retentionScheduleId, List nodeInfos, Parameters parameters)
+ {
+ checkNotBlank("retentionScheduleId", retentionScheduleId);
+ mandatory("entity", nodeInfos);
+ mandatory("parameters", parameters);
+ NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
+ // validation for the order of the step
+ retentionScheduleStepValidation(retentionScheduleNodeRef, nodeInfos.get(0));
+ // request property validation
+ retentionScheduleRequestValidation(nodeInfos.get(0));
+ // create the parameters for the action definition
+ Map actionDefinitionParams = nodesModelFactory.createRetentionActionDefinitionParams(nodeInfos.get(0));
+ // create the child association from the schedule to the action definition
+ NodeRef actionNodeRef = this.nodeService.createNode(retentionScheduleNodeRef,
+ RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
+ QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
+ QName.createValidLocalName(nodeInfos.get(0).getName())),
+ RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
+ DispositionSchedule dispositionSchedule = new DispositionScheduleImpl(service, nodeService, retentionScheduleNodeRef);
+ DispositionActionDefinition dispositionActionDefinition = dispositionSchedule.getDispositionActionDefinition(actionNodeRef.getId());
+ List responseActions = new ArrayList<>();
+ if (dispositionActionDefinition != null)
+ {
+ responseActions.add(nodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition));
+ }
+ return responseActions;
+ }
+
+ @Override
+ @WebApiDescription(title = "Return a paged list of retention schedule action definition based on the 'retentionScheduleId'")
+ public CollectionWithPagingInfo readAll(String retentionScheduleId, Parameters parameters)
+ {
+ checkNotBlank("retentionScheduleId", retentionScheduleId);
+ mandatory("parameters", parameters);
+ NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
+ List actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
+ List actionDefinitionList = actions.stream()
+ .map(nodesModelFactory::mapRetentionScheduleActionDefData)
+ .collect(Collectors.toList());
+ return CollectionWithPagingInfo.asPaged(parameters.getPaging(), actionDefinitionList, false,
+ actionDefinitionList.size());
+ }
+
+ /**
+ * this method is used to validate the order of the retention schedule step
+ * @param retentionScheduleNodeRef nodeRef
+ * @param retentionScheduleActionDefinition retention schedule action definition
+ */
+ private void retentionScheduleStepValidation(NodeRef retentionScheduleNodeRef, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
+ {
+ List actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
+ Set completedActions = new HashSet<>();
+ if (!actions.isEmpty())
+ {
+ completedActions = actions.stream()
+ .map(DispositionActionDefinition::getName)
+ .collect(Collectors.toSet());
+ }
+
+ if (completedActions.contains(RetentionSteps.DESTROY.stepName))
+ {
+ throw new ConstraintViolatedException("Invalid Step - destroy action is already added . No other action is allowed after Destroy.");
+ }
+
+ if (checkStepAlreadyExists(completedActions, retentionScheduleActionDefinition.getName()))
+ {
+ throw new ConstraintViolatedException("Invalid Step - This step already exists. You can’t create it again. Only transfer action is allowed multiple times.");
+ }
+
+ if (firstStepValidation(actions, retentionScheduleActionDefinition.getName()))
+ {
+ throw new UnprocessableContentException("Invalid Step - cutoff or retain should be the first step");
+ }
+
+ if (isCutOffStepAllowed(completedActions, retentionScheduleActionDefinition.getName()))
+ {
+ throw new ConstraintViolatedException("Invalid Step - Can't use cutoff after transfer or accession");
+ }
+ }
+
+ /**
+ * this method is used to validate the request of the retention schedule
+ * @param retentionScheduleActionDefinition retention schedule action definition
+ */
+ private void retentionScheduleRequestValidation(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
+ {
+ // step name validation
+ if (invalidStepNameCheck(retentionScheduleActionDefinition.getName()))
+ {
+ throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName());
+ }
+ // period value validation
+ if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod()))
+ {
+ throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod());
+ }
+ // event name validation
+ if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents()))
+ {
+ throw new InvalidArgumentException("event value is invalid: " + retentionScheduleActionDefinition.getEvents());
+ }
+ // periodProperty validation
+ List validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf");
+ if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals))
+ {
+ throw new InvalidArgumentException("periodProperty value is invalid: " + retentionScheduleActionDefinition.getPeriodProperty());
+ }
+ }
+
+ private boolean checkStepAlreadyExists(Set completedActions, String stepName)
+ {
+ return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName);
+ }
+
+ private boolean firstStepValidation(List actions, String stepName)
+ {
+ return actions.isEmpty()
+ && !stepName.equals(RetentionSteps.CUTOFF.stepName) && (!stepName.equals(RetentionSteps.RETAIN.stepName));
+ }
+
+ private boolean isCutOffStepAllowed(Set completedActions, String stepName)
+ {
+ return (completedActions.contains(RetentionSteps.TRANSFER.stepName) || completedActions.contains(RetentionSteps.ACCESSION.stepName))
+ && stepName.equals(RetentionSteps.CUTOFF.stepName);
+ }
+
+ private boolean invalidStepNameCheck(String stepName)
+ {
+ return stepName != null && Arrays.stream(RetentionSteps.values())
+ .noneMatch(retentionStep -> retentionStep.stepName.equals(stepName));
+ }
+
+ private boolean invalidPeriodCheck(String period)
+ {
+ return period != null && Arrays.stream(RetentionPeriod.values())
+ .noneMatch(retentionPeriod -> retentionPeriod.periodName.equals(period));
+ }
+
+ private boolean invalidEventNameCheck(List events)
+ {
+ return !events.isEmpty() && events.stream()
+ .anyMatch(event -> Arrays.stream(RetentionEvents.values())
+ .noneMatch(retentionEvent -> retentionEvent.eventName.equals(event)));
+ }
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleEntityResource.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleEntityResource.java
new file mode 100644
index 0000000000..e305fdedf7
--- /dev/null
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleEntityResource.java
@@ -0,0 +1,38 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rm.rest.api.retentionschedule;
+
+import org.alfresco.rest.framework.resource.EntityResource;
+
+/**
+ * Retention schedule entity resource
+ */
+@EntityResource(name="retention-schedules", title = "Retention Schedule")
+public class RetentionScheduleEntityResource
+{
+
+}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java
index 60a7a3b856..86583c27da 100644
--- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java
+++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java
@@ -54,13 +54,11 @@ import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagement
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.TYPE_RECORD_CATEGORY;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
-import lombok.Data;
/**
* Retention schedule relation is used perform retention schedule operation for a record category.
*/
@RelationshipResource(name = "retention-schedules", entityResource = RecordCategoriesEntityResource.class, title = "Retention Schedule")
-@Data
public class RetentionScheduleRelation implements RelationshipResourceAction.Read,
RelationshipResourceAction.Create
{
@@ -70,6 +68,26 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea
private DispositionService dispositionService;
protected NodeService nodeService;
+ public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
+ {
+ this.apiUtils = apiUtils;
+ }
+
+ public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
+ {
+ this.nodesModelFactory = nodesModelFactory;
+ }
+
+ public void setDispositionService(DispositionService dispositionService)
+ {
+ this.dispositionService = dispositionService;
+ }
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
@Override
@WebApiDescription(title="Create a retention schedule for the particular record category using the 'recordCategoryId'")
public List create(String recordCategoryId, List nodeInfos, Parameters parameters)
@@ -83,7 +101,7 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea
Map dsProps = new HashMap<>();
dsProps.put(PROP_DISPOSITION_AUTHORITY, nodeInfos.get(0).getAuthority());
dsProps.put(PROP_DISPOSITION_INSTRUCTIONS, nodeInfos.get(0).getInstructions());
- dsProps.put(PROP_RECORD_LEVEL_DISPOSITION, nodeInfos.get(0).isRecordLevel());
+ dsProps.put(PROP_RECORD_LEVEL_DISPOSITION, nodeInfos.get(0).getIsRecordLevel());
DispositionSchedule dispositionSchedule = dispositionService.createDispositionSchedule(parentNodeRef, dsProps);
RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
result.add(retentionSchedule);
diff --git a/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java b/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java
index 2b89472fde..7c8b1b3411 100644
--- a/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java
+++ b/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java
@@ -39,7 +39,6 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
/**
@@ -72,11 +71,17 @@ public class RetentionScheduleModelUnitTest extends BaseUnitTest
when(dispositionSchedule.isRecordLevelDisposition()).thenReturn(false);
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
// Call the method
- RetentionSchedule expectedResult = apiNodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
- assertEquals(expectedResult.getId(), dispositionSchedule.getNodeRef().getId());
- assertEquals(expectedResult.getAuthority(), dispositionSchedule.getDispositionAuthority());
- assertEquals(expectedResult.getInstructions(), dispositionSchedule.getDispositionInstructions());
- assertEquals(expectedResult.isRecordLevel(), dispositionSchedule.isRecordLevelDisposition());
+ RetentionSchedule actualResult = apiNodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
+
+ //Expected Result
+ RetentionSchedule expectedResult = new RetentionSchedule();
+ expectedResult.setId(nodeRef.getId());
+ expectedResult.setParentId(filePlan.getId());
+ expectedResult.setAuthority(AUTHORITY);
+ expectedResult.setInstructions(INSTRUCTIONS);
+
+ // Assertions
+ assertEquals(expectedResult, actualResult);
}
@Test
@@ -96,15 +101,26 @@ public class RetentionScheduleModelUnitTest extends BaseUnitTest
when(dispositionActionDefinition.getId()).thenReturn(nodeRef.getId());
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
// Call the method
- RetentionScheduleActionDefinition expectedResult = apiNodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition);
- String resultPeriod = expectedResult.getPeriod() + "|" + expectedResult.getPeriodAmount();
- // Assertions
- assertEquals(expectedResult.getId(), dispositionActionDefinition.getId());
- assertEquals(expectedResult.getName(), dispositionActionDefinition.getName());
- assertEquals(expectedResult.getDescription(), dispositionActionDefinition.getDescription());
- assertEquals(expectedResult.getIndex(), dispositionActionDefinition.getIndex());
- assertEquals(expectedResult.getLocation(), dispositionActionDefinition.getLocation());
- assertEquals(new Period(resultPeriod), dispositionActionDefinition.getPeriod());
- assertTrue(expectedResult.isRetainRecordMetadataAfterDestruction());
+ RetentionScheduleActionDefinition actualResult = apiNodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition);
+
+ //Expected Result
+ RetentionScheduleActionDefinition expectedResult = getRetentionScheduleActionDefinition(nodeRef);
+
+ // Assertion
+ assertEquals(expectedResult, actualResult);
+ }
+
+ private static RetentionScheduleActionDefinition getRetentionScheduleActionDefinition(NodeRef nodeRef)
+ {
+ RetentionScheduleActionDefinition expectedResult = new RetentionScheduleActionDefinition();
+ expectedResult.setId(nodeRef.getId());
+ expectedResult.setName(RETAIN_STEP);
+ expectedResult.setDescription("Description");
+ expectedResult.setIndex(1);
+ expectedResult.setLocation("location");
+ expectedResult.setPeriod("month");
+ expectedResult.setPeriodAmount(10);
+ expectedResult.setRetainRecordMetadataAfterDestruction(true);
+ return expectedResult;
}
}
\ No newline at end of file
diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
index 59f55ce44f..461d366003 100644
--- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
+++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-repo-parent
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/pom.xml b/amps/pom.xml
index cde64b28e3..8833e10762 100644
--- a/amps/pom.xml
+++ b/amps/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml
index 31e39694f5..2ffc74bc31 100644
--- a/amps/share-services/pom.xml
+++ b/amps/share-services/pom.xml
@@ -8,7 +8,7 @@
org.alfresco
alfresco-community-repo-amps
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/core/pom.xml b/core/pom.xml
index 22c55b58ce..b1658281c6 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/data-model/pom.xml b/data-model/pom.xml
index b703d5918f..37b59eb6a9 100644
--- a/data-model/pom.xml
+++ b/data-model/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/mmt/pom.xml b/mmt/pom.xml
index f940ea4664..deef149f0e 100644
--- a/mmt/pom.xml
+++ b/mmt/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml
index 211c0d904e..3a5d0ebad0 100644
--- a/packaging/distribution/pom.xml
+++ b/packaging/distribution/pom.xml
@@ -9,6 +9,6 @@
org.alfresco
alfresco-community-repo-packaging
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml
index 3affd65da1..deeb184100 100644
--- a/packaging/docker-alfresco/pom.xml
+++ b/packaging/docker-alfresco/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-packaging
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/pom.xml b/packaging/pom.xml
index 6b6b298451..15bcb302d6 100644
--- a/packaging/pom.xml
+++ b/packaging/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml
index 5d585a9dd8..6712aa55a2 100644
--- a/packaging/tests/pom.xml
+++ b/packaging/tests/pom.xml
@@ -6,7 +6,7 @@
org.alfresco
alfresco-community-repo-packaging
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml
index 3f8800ea26..26f15be8ee 100644
--- a/packaging/tests/tas-cmis/pom.xml
+++ b/packaging/tests/tas-cmis/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-tests
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml
index 1080873d7c..f6d07fe019 100644
--- a/packaging/tests/tas-email/pom.xml
+++ b/packaging/tests/tas-email/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml
index e6b323086b..0665997e70 100644
--- a/packaging/tests/tas-integration/pom.xml
+++ b/packaging/tests/tas-integration/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml
index 5a72760007..4d13def062 100644
--- a/packaging/tests/tas-restapi/pom.xml
+++ b/packaging/tests/tas-restapi/pom.xml
@@ -8,7 +8,7 @@
org.alfresco
alfresco-community-repo-tests
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml
index 6bebe1a61f..09c252b4f1 100644
--- a/packaging/tests/tas-webdav/pom.xml
+++ b/packaging/tests/tas-webdav/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml
index 44817efdce..d4208eefbb 100644
--- a/packaging/war/pom.xml
+++ b/packaging/war/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-packaging
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/pom.xml b/pom.xml
index 84646c808e..e5d7153fcb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
pom
Alfresco Community Repo Parent
diff --git a/remote-api/pom.xml b/remote-api/pom.xml
index 842546833b..68d15be3ff 100644
--- a/remote-api/pom.xml
+++ b/remote-api/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT
diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/UnprocessableContentException.java b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/UnprocessableContentException.java
new file mode 100644
index 0000000000..df2babf44d
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/UnprocessableContentException.java
@@ -0,0 +1,40 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2024 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.framework.core.exceptions;
+
+/**
+ * Unprocessable Content
+ */
+public class UnprocessableContentException extends ApiException
+{
+
+ private static final long serialVersionUID = -6857652090677361159L;
+
+ public UnprocessableContentException(String msgId)
+ {
+ super(msgId);
+ }
+}
\ No newline at end of file
diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml
index f87a8fd513..b1c39daa82 100644
--- a/remote-api/src/main/resources/alfresco/public-rest-context.xml
+++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml
@@ -178,6 +178,7 @@
+
diff --git a/repository/pom.xml b/repository/pom.xml
index 24b4bf1ab2..1290166374 100644
--- a/repository/pom.xml
+++ b/repository/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 23.3.0.61-SNAPSHOT
+ 23.3.0.63-SNAPSHOT