mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-11-05 15:32:21 +00:00
Compare commits
1 Commits
priyanka_m
...
feature/Up
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1390b30302 |
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -52,7 +52,3 @@ updates:
|
|||||||
interval: "daily"
|
interval: "daily"
|
||||||
time: "22:00"
|
time: "22:00"
|
||||||
timezone: Africa/Abidjan
|
timezone: Africa/Abidjan
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "monthly"
|
|
||||||
|
|||||||
454
.github/workflows/ci.yml
vendored
454
.github/workflows/ci.yml
vendored
File diff suppressed because it is too large
Load Diff
20
.github/workflows/master_release.yml
vendored
20
.github/workflows/master_release.yml
vendored
@@ -31,15 +31,15 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[no release]') &&
|
!contains(github.event.head_commit.message, '[no release]') &&
|
||||||
github.event_name != 'pull_request'
|
github.event_name != 'pull_request'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.35.2
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v1.35.2
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
|
||||||
- name: "Init"
|
- name: "Init"
|
||||||
run: bash ./scripts/ci/init.sh
|
run: bash ./scripts/ci/init.sh
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
|
||||||
with:
|
with:
|
||||||
username: ${{ env.GIT_USERNAME }}
|
username: ${{ env.GIT_USERNAME }}
|
||||||
email: ${{ env.GIT_EMAIL }}
|
email: ${{ env.GIT_EMAIL }}
|
||||||
@@ -60,15 +60,15 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[no downstream]') &&
|
!contains(github.event.head_commit.message, '[no downstream]') &&
|
||||||
github.event_name != 'pull_request'
|
github.event_name != 'pull_request'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.35.2
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v1.35.2
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
|
||||||
- name: "Init"
|
- name: "Init"
|
||||||
run: bash ./scripts/ci/init.sh
|
run: bash ./scripts/ci/init.sh
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
|
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
|
||||||
with:
|
with:
|
||||||
username: ${{ env.GIT_USERNAME }}
|
username: ${{ env.GIT_USERNAME }}
|
||||||
email: ${{ env.GIT_EMAIL }}
|
email: ${{ env.GIT_EMAIL }}
|
||||||
|
|||||||
75
README.md
75
README.md
@@ -2,57 +2,38 @@
|
|||||||
|
|
||||||
[](https://github.com/Alfresco/alfresco-community-repo/actions/workflows/master_release.yml)
|
[](https://github.com/Alfresco/alfresco-community-repo/actions/workflows/master_release.yml)
|
||||||
|
|
||||||
## Table of Contents
|
#### Alfresco Core
|
||||||
1. [Content](#content)
|
|
||||||
2. [Artifacts](#artifacts)
|
|
||||||
3. [Setup](#setting-up-and-building-your-development-environment)
|
|
||||||
4. [Branches](#branches)
|
|
||||||
5. [Contributing](#contributing-guide)
|
|
||||||
6. [Helpful links](#helpful-links)
|
|
||||||
|
|
||||||
|
|
||||||
## Content
|
|
||||||
Alfresco Community Repository contains following libraries:
|
|
||||||
|
|
||||||
### Alfresco Core
|
|
||||||
Core is a library packaged as a jar file which contains the following:
|
|
||||||
|
|
||||||
|
Alfresco Core is a library packaged as a jar file which contains the following:
|
||||||
* Various helpers and utils
|
* Various helpers and utils
|
||||||
* Canned queries interface and supporting classes
|
* Canned queries interface and supporting classes
|
||||||
* Generic encryption supporting classes
|
* Generic encryption supporting classes
|
||||||
|
|
||||||
### Alfresco Data Model
|
#### Alfresco Data Model
|
||||||
|
Data model is a library packaged as a jar file which contains the following:
|
||||||
Data Model is a library packaged as a jar file which contains the following:
|
|
||||||
|
|
||||||
* Dictionary, Repository and Search Services interfaces
|
* Dictionary, Repository and Search Services interfaces
|
||||||
* Models for data types and Dictionary implementation
|
* Models for data types and Dictionary implementation
|
||||||
* Parsers
|
* Parsers
|
||||||
|
|
||||||
### Alfresco Repository
|
#### Alfresco Repository
|
||||||
|
|
||||||
Repository is a library packaged as a jar file which contains the following:
|
Repository is a library packaged as a jar file which contains the following:
|
||||||
|
|
||||||
* DAOs and SQL scripts
|
* DAOs and SQL scripts
|
||||||
* Various Service implementations
|
* Various Service implementations
|
||||||
* Utility classes
|
* Utility classes
|
||||||
|
|
||||||
### Alfresco Remote API
|
#### Alfresco Remote API
|
||||||
|
|
||||||
Remote API is a library packaged as a jar file which contains the following:
|
Remote API is a library packaged as a jar file which contains the following:
|
||||||
|
|
||||||
* REST API framework
|
* REST API framework
|
||||||
* WebScript implementations including [V1 REST APIs](https://hub.alfresco.com/t5/alfresco-content-services-blog/v1-rest-api-10-things-you-should-know/ba-p/287692)
|
* WebScript implementations including [V1 REST APIs](https://hub.alfresco.com/t5/alfresco-content-services-blog/v1-rest-api-10-things-you-should-know/ba-p/287692)
|
||||||
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
|
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
|
||||||
|
|
||||||
## Artifacts
|
#### Artifacts
|
||||||
|
|
||||||
The artifacts can be obtained by:
|
The artifacts can be obtained by:
|
||||||
* downloading from [Alfresco maven repository](https://artifacts.alfresco.com/nexus/#browse/browse:public)
|
* downloading from [Alfresco maven repository](https://artifacts.alfresco.com/nexus/content/groups/public)
|
||||||
* as Maven dependency by adding the dependency to your pom file:
|
* as Maven dependency by adding the dependency to your pom file:
|
||||||
|
~~~
|
||||||
~~~xml
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-core</artifactId>
|
<artifactId>alfresco-core</artifactId>
|
||||||
@@ -83,46 +64,34 @@ The artifacts can be obtained by:
|
|||||||
<version>version</version>
|
<version>version</version>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
and Alfresco maven repository:
|
and Alfresco maven repository:
|
||||||
|
~~~
|
||||||
~~~xml
|
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>alfresco-maven-repo</id>
|
<id>alfresco-maven-repo</id>
|
||||||
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
|
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The SNAPSHOT versions of the artifact are not published.
|
The SNAPSHOT versions of the artifact are not published.
|
||||||
|
|
||||||
## Setting up and building your development environment
|
## Setting up and building your development environment
|
||||||
|
See the [Development Tomcat Environment](https://github.com/Alfresco/acs-community-packaging/tree/master/dev/README.md)
|
||||||
See the [**Development Tomcat Environment**](https://github.com/Alfresco/acs-community-packaging/tree/master/dev/README.md)
|
page which will show you how to try out your repository changes in a local tomcat instance.
|
||||||
page which will show you how to try out your repository changes in a local Tomcat instance or using Docker containers.
|
If you wish to use Docker images, take a look at the aliases ending in `D` and the docker-compose files in this
|
||||||
|
project's test modules.
|
||||||
|
|
||||||
## Branches
|
## Branches
|
||||||
|
This project has a branch for each ACS release. For example the code in ACS 6.2.1 is a
|
||||||
This project has a branch for each ACS release. For example the code in ACS 6.2.2 is a
|
branch called `releases/6.2.2`. In addition to the original 6.2.2 release it will also contain Hot Fixes
|
||||||
branch called **`release/6.2.2`**. In addition to the original 6.2.2 release it will also contain Hot Fixes
|
added later. The latest unreleased code is on the `master` branch. There are also `.N` branches, such as
|
||||||
added later. The latest unreleased code is on the **`master`** branch. There are also **`.N`** branches, such as
|
`releases/7.1.N` on which we gather unreleased fixes for future service pack releases. They do not indicate
|
||||||
**`release/7.1.N`** on which we gather unreleased fixes for future service pack releases. They do not indicate
|
|
||||||
that one is planned.
|
that one is planned.
|
||||||
|
|
||||||
For historic reasons the version of artifacts created on each branch do not match the ACS version.
|
For historic reasons the version of artifacts created on each branch do not match the ACS version.
|
||||||
For example artifact in ACS 7.2.0 will be **`14.<something>`**.
|
For example artifact in ACS 7.2.0 will be `14.<something>`.
|
||||||
|
|
||||||
The enterprise projects which extend the **`alfresco-community-repo`** use the same branch names and leading
|
The enterprise projects which extend the `alfresco-community-repo` use the same branch names and leading
|
||||||
artifact version number.
|
artifact version number.
|
||||||
|
|
||||||
## Contributing guide
|
### Contributing guide
|
||||||
|
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
|
||||||
Please use [**this guide**](CONTRIBUTING.md) to make a contribution to the project.
|
|
||||||
|
|
||||||
## Helpful links
|
|
||||||
|
|
||||||
- [Alfresco Content Services Documentation](https://docs.alfresco.com/content-services/latest/)
|
|
||||||
- [Alfresco Platform](https://www.hyland.com/en/products/alfresco-platform)
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -84,12 +84,6 @@
|
|||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.awaitility</groupId>
|
|
||||||
<artifactId>awaitility</artifactId>
|
|
||||||
<version>${dependency.awaitility.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
@@ -98,7 +92,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.docker-java</groupId>
|
<groupId>com.github.docker-java</groupId>
|
||||||
<artifactId>docker-java</artifactId>
|
<artifactId>docker-java</artifactId>
|
||||||
<version>3.3.6</version>
|
<version>3.3.2</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI;
|
|||||||
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI;
|
|
||||||
import org.alfresco.utility.data.DataUserAIS;
|
import org.alfresco.utility.data.DataUserAIS;
|
||||||
import org.alfresco.utility.model.RepoTestModel;
|
import org.alfresco.utility.model.RepoTestModel;
|
||||||
import org.alfresco.utility.model.UserModel;
|
import org.alfresco.utility.model.UserModel;
|
||||||
@@ -255,14 +254,4 @@ public class RestAPIFactory
|
|||||||
{
|
{
|
||||||
return getGSCoreAPI(userModel).usingHoldsAPI();
|
return getGSCoreAPI(userModel).usingHoldsAPI();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RetentionScheduleAPI getRetentionScheduleAPI()
|
|
||||||
{
|
|
||||||
return getGSCoreAPI(null).usingRetentionScheduleAPI();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RetentionScheduleAPI getRetentionScheduleAPI(UserModel userModel)
|
|
||||||
{
|
|
||||||
return getGSCoreAPI(userModel).usingRetentionScheduleAPI();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*-
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class BulkBodyCancel
|
|
||||||
{
|
|
||||||
private String reason;
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.alfresco.rest.search.RestRequestQueryModel;
|
|
||||||
import org.alfresco.utility.model.TestModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* POJO for hold bulk request
|
|
||||||
*
|
|
||||||
* @author Damian Ujma
|
|
||||||
*/
|
|
||||||
@Builder
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class HoldBulkOperation extends TestModel
|
|
||||||
{
|
|
||||||
public enum HoldBulkOperationType
|
|
||||||
{
|
|
||||||
ADD
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(required = true)
|
|
||||||
private RestRequestQueryModel query;
|
|
||||||
@JsonProperty(required = true)
|
|
||||||
private HoldBulkOperationType op;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* POJO for hold bulk request entry
|
|
||||||
*
|
|
||||||
* @author Damian Ujma
|
|
||||||
*/
|
|
||||||
@Builder
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class HoldBulkOperationEntry
|
|
||||||
{
|
|
||||||
private String bulkStatusId;
|
|
||||||
|
|
||||||
private long totalItems;
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.alfresco.utility.model.TestModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* POJO for hold bulk request
|
|
||||||
*
|
|
||||||
* @author Damian Ujma
|
|
||||||
*/
|
|
||||||
@Builder
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class HoldBulkStatus extends TestModel
|
|
||||||
{
|
|
||||||
private String bulkStatusId;
|
|
||||||
|
|
||||||
private String startTime;
|
|
||||||
|
|
||||||
private String endTime;
|
|
||||||
|
|
||||||
private long processedItems;
|
|
||||||
|
|
||||||
private long errorsCount;
|
|
||||||
|
|
||||||
private long totalItems;
|
|
||||||
|
|
||||||
private String lastError;
|
|
||||||
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
private boolean isCancelled;
|
|
||||||
|
|
||||||
private String cancellationReason;
|
|
||||||
|
|
||||||
private HoldBulkOperation holdBulkOperation;
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import org.alfresco.rest.core.RestModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle collection of {@link HoldBulkStatusEntry}
|
|
||||||
*
|
|
||||||
* @author Damian Ujma
|
|
||||||
*/
|
|
||||||
public class HoldBulkStatusCollection extends RestModels<HoldBulkStatusEntry, HoldBulkStatusCollection>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.hold;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.alfresco.rest.core.RestModels;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class HoldBulkStatusEntry extends RestModels<HoldBulkStatus, HoldBulkStatusEntry>
|
|
||||||
{
|
|
||||||
private HoldBulkStatus entry;
|
|
||||||
}
|
|
||||||
@@ -48,5 +48,5 @@ import org.alfresco.rest.core.RestModels;
|
|||||||
public class HoldChildEntry extends RestModels<Hold, HoldChildEntry>
|
public class HoldChildEntry extends RestModels<Hold, HoldChildEntry>
|
||||||
{
|
{
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private HoldChild entry;
|
private HoldChildEntry entry;
|
||||||
}
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.retentionschedule;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.alfresco.utility.model.TestModel;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* retention schedule
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class RetentionSchedule extends TestModel
|
|
||||||
{
|
|
||||||
private String id ;
|
|
||||||
private String parentId;
|
|
||||||
private String authority;
|
|
||||||
private String instructions;
|
|
||||||
private boolean isRecordLevel;
|
|
||||||
private boolean isUnpublishedUpdates;
|
|
||||||
private List<RetentionScheduleActionDefinition> actions;
|
|
||||||
|
|
||||||
public boolean getIsRecordLevel()
|
|
||||||
{
|
|
||||||
return isRecordLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsRecordLevel(boolean recordLevel) {
|
|
||||||
isRecordLevel = recordLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.retentionschedule;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* retention schedule action definition
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class RetentionScheduleActionDefinition
|
|
||||||
{
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private int periodAmount;
|
|
||||||
private String period;
|
|
||||||
private String periodProperty;
|
|
||||||
private boolean combineRetentionStepConditions;
|
|
||||||
private List<String> events;
|
|
||||||
private boolean eligibleOnFirstCompleteEvent;
|
|
||||||
private String description;
|
|
||||||
private boolean retainRecordMetadataAfterDestruction;
|
|
||||||
private String location;
|
|
||||||
private int index;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.retentionschedule;
|
|
||||||
|
|
||||||
import org.alfresco.rest.core.RestModels;
|
|
||||||
public class RetentionScheduleCollection extends RestModels<RetentionScheduleEntry, RetentionScheduleCollection>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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 RetentionScheduleEntry extends RestModels<RetentionSchedule, RetentionScheduleEntry>
|
|
||||||
{
|
|
||||||
@JsonProperty
|
|
||||||
private RetentionSchedule entry;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.model.retentionschedule;
|
|
||||||
|
|
||||||
import org.alfresco.rest.core.RestModels;
|
|
||||||
|
|
||||||
public class RetentionScheduleStepCollection extends RestModels<RetentionScheduleStepEntry, RetentionScheduleStepCollection>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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<RetentionScheduleActionDefinition, RetentionScheduleStepEntry>
|
|
||||||
{
|
|
||||||
@JsonProperty
|
|
||||||
private RetentionScheduleActionDefinition entry;
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,6 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI;
|
|||||||
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
|
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
|
||||||
import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the entire GS Core API
|
* Defines the entire GS Core API
|
||||||
@@ -194,9 +193,4 @@ public class GSCoreAPI extends RMModelRequest
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HoldsAPI usingHoldsAPI() { return new HoldsAPI(getRmRestWrapper()); }
|
public HoldsAPI usingHoldsAPI() { return new HoldsAPI(getRmRestWrapper()); }
|
||||||
|
|
||||||
public RetentionScheduleAPI usingRetentionScheduleAPI()
|
|
||||||
{
|
|
||||||
return new RetentionScheduleAPI(getRmRestWrapper());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,7 @@ import static org.springframework.http.HttpMethod.POST;
|
|||||||
import static org.springframework.http.HttpMethod.PUT;
|
import static org.springframework.http.HttpMethod.PUT;
|
||||||
|
|
||||||
import org.alfresco.rest.core.RMRestWrapper;
|
import org.alfresco.rest.core.RMRestWrapper;
|
||||||
import org.alfresco.rest.rm.community.model.hold.BulkBodyCancel;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.Hold;
|
import org.alfresco.rest.rm.community.model.hold.Hold;
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkOperation;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkOperationEntry;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkStatus;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkStatusCollection;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldChild;
|
import org.alfresco.rest.rm.community.model.hold.HoldChild;
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldChildCollection;
|
import org.alfresco.rest.rm.community.model.hold.HoldChildCollection;
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldDeletionReason;
|
import org.alfresco.rest.rm.community.model.hold.HoldDeletionReason;
|
||||||
@@ -292,155 +287,4 @@ public class HoldsAPI extends RMModelRequest
|
|||||||
{
|
{
|
||||||
deleteHoldChild(holdId, holdChildId, EMPTY);
|
deleteHoldChild(holdId, holdChildId, EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a bulk process for a hold.
|
|
||||||
*
|
|
||||||
* @param holdBulkOperation The bulk operation details
|
|
||||||
* @param hold The identifier of a hold
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @return The {@link HoldBulkOperationEntry} for the started bulk process
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code hold} or {@code holdBulkOperation} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to start a bulk process for {@code hold}</li>
|
|
||||||
* <li>{@code hold} does not exist</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public HoldBulkOperationEntry startBulkProcess(HoldBulkOperation holdBulkOperation, String hold, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryObject("holdBulkOperation", holdBulkOperation);
|
|
||||||
mandatoryString("hold", hold);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModel(HoldBulkOperationEntry.class, requestWithBody(
|
|
||||||
POST,
|
|
||||||
toJson(holdBulkOperation),
|
|
||||||
"holds/{hold}/bulk",
|
|
||||||
hold,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #startBulkProcess(HoldBulkOperation, String, String)}
|
|
||||||
*/
|
|
||||||
public HoldBulkOperationEntry startBulkProcess(HoldBulkOperation holdBulkOperation, String hold)
|
|
||||||
{
|
|
||||||
return startBulkProcess(holdBulkOperation, hold, EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the status of a bulk process for a hold.
|
|
||||||
*
|
|
||||||
* @param holdId The identifier of a hold
|
|
||||||
* @param holdBulkStatusId The identifier of a bulk status operation
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @return The {@link HoldBulkStatus} for the given {@code holdId} and {@code holdBulkStatusId}
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code holdId} or {@code holdBulkStatusId} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to get the bulk status for {@code holdId}</li>
|
|
||||||
* <li>{@code holdId} or {@code holdBulkStatusId} does not exist</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public HoldBulkStatus getBulkStatus(String holdId, String holdBulkStatusId, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryString("holdId", holdId);
|
|
||||||
mandatoryString("holdBulkStatusId", holdBulkStatusId);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModel(HoldBulkStatus.class, simpleRequest(
|
|
||||||
GET,
|
|
||||||
"holds/{holdId}/bulk-statuses/{holdBulkStatusId}",
|
|
||||||
holdId,
|
|
||||||
holdBulkStatusId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #getBulkStatus(String, String, String)}
|
|
||||||
*/
|
|
||||||
public HoldBulkStatus getBulkStatus(String holdId, String holdBulkStatusId)
|
|
||||||
{
|
|
||||||
return getBulkStatus(holdId, holdBulkStatusId, EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the statuses of all bulk processes for a hold.
|
|
||||||
*
|
|
||||||
* @param holdId The identifier of a hold
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @return The {@link HoldBulkStatusCollection} for the given {@code holdId}
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code holdId} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to get the bulk statuses for {@code holdId}</li>
|
|
||||||
* <li>{@code holdId} does not exist</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public HoldBulkStatusCollection getBulkStatuses(String holdId, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryString("holdId", holdId);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModels(HoldBulkStatusCollection.class, simpleRequest(
|
|
||||||
GET,
|
|
||||||
"holds/{holdId}/bulk-statuses",
|
|
||||||
holdId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #getBulkStatuses(String, String)}
|
|
||||||
*/
|
|
||||||
public HoldBulkStatusCollection getBulkStatuses(String holdId)
|
|
||||||
{
|
|
||||||
return getBulkStatuses(holdId, EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels a bulk operation for a hold.
|
|
||||||
*
|
|
||||||
* @param holdId The identifier of a hold
|
|
||||||
* @param bulkStatusId The identifier of a bulk status operation
|
|
||||||
* @param bulkBodyCancel The bulk body cancel model
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code holdId}, {@code bulkStatusId} or {@code bulkBodyCancel} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to cancel the bulk operation for {@code bulkStatusId}</li>
|
|
||||||
* <li>{@code holdId} or {@code bulkStatusId} does not exist</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public void cancelBulkOperation(String holdId, String bulkStatusId, BulkBodyCancel bulkBodyCancel, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryString("holdId", holdId);
|
|
||||||
mandatoryString("bulkStatusId", bulkStatusId);
|
|
||||||
mandatoryObject("bulkBodyCancel", bulkBodyCancel);
|
|
||||||
|
|
||||||
getRmRestWrapper().processEmptyModel(requestWithBody(
|
|
||||||
POST,
|
|
||||||
toJson(bulkBodyCancel),
|
|
||||||
"holds/{holdId}/bulk-statuses/{bulkStatusId}/cancel",
|
|
||||||
holdId,
|
|
||||||
bulkStatusId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #cancelBulkOperation(String, String, BulkBodyCancel, String)}
|
|
||||||
*/
|
|
||||||
public void cancelBulkOperation(String holdId, String bulkStatusId, BulkBodyCancel bulkBodyCancel)
|
|
||||||
{
|
|
||||||
mandatoryString("holdId", holdId);
|
|
||||||
mandatoryString("bulkStatusId", bulkStatusId);
|
|
||||||
mandatoryObject("bulkBodyCancel", bulkBodyCancel);
|
|
||||||
|
|
||||||
cancelBulkOperation(holdId, bulkStatusId, bulkBodyCancel, EMPTY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,198 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
import static org.alfresco.rest.core.RestRequest.simpleRequest;
|
|
||||||
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
|
|
||||||
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
|
|
||||||
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.EMPTY;
|
|
||||||
import static org.springframework.http.HttpMethod.GET;
|
|
||||||
import static org.springframework.http.HttpMethod.POST;
|
|
||||||
|
|
||||||
public class RetentionScheduleAPI extends RMModelRequest
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param rmRestWrapper
|
|
||||||
*/
|
|
||||||
public RetentionScheduleAPI(RMRestWrapper rmRestWrapper)
|
|
||||||
{
|
|
||||||
super(rmRestWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a retention schedule.
|
|
||||||
*
|
|
||||||
* @param retentionScheduleModel The retentionSchedule model
|
|
||||||
* @param recordCategoryId The identifier of a record category
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @return The created {@link RetentionSchedule}
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code recordCategoryId} is not a valid format or {@code recordCategoryId} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to add children to {@code recordCategoryId}</li>
|
|
||||||
* <li>{@code recordCategoryId} does not exist</li>
|
|
||||||
* <li>new name clashes with an existing node in the current parent container</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryString("recordCategoryId", recordCategoryId);
|
|
||||||
mandatoryObject("retentionScheduleModel", retentionScheduleModel);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModel(RetentionSchedule.class, requestWithBody(
|
|
||||||
POST,
|
|
||||||
toJson(retentionScheduleModel),
|
|
||||||
"record-categories/{recordCategoryId}/retention-schedules",
|
|
||||||
recordCategoryId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #createRetentionSchedule(RetentionSchedule, String, String)}
|
|
||||||
*/
|
|
||||||
public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId)
|
|
||||||
{
|
|
||||||
return createRetentionSchedule(retentionScheduleModel, recordCategoryId, EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the retentionSchedule of a record category.
|
|
||||||
*
|
|
||||||
* @param recordCategoryId The identifier of a record category
|
|
||||||
* @param parameters The URL parameters to add
|
|
||||||
* @return The {@link RetentionSchedule} for the given {@code recordCategoryId}
|
|
||||||
* @throws RuntimeException for the following cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to read {@code recordCategoryId}</li>
|
|
||||||
* <li>{@code recordCategoryId} does not exist</li>
|
|
||||||
*</ul>
|
|
||||||
*/
|
|
||||||
public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId, String parameters)
|
|
||||||
{
|
|
||||||
mandatoryString("recordCategoryId", recordCategoryId);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModels(RetentionScheduleCollection.class, simpleRequest(
|
|
||||||
GET,
|
|
||||||
"record-categories/{recordCategoryId}/retention-schedules?{parameters}",
|
|
||||||
recordCategoryId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #getRetentionSchedule(String, String)}
|
|
||||||
*/
|
|
||||||
public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId)
|
|
||||||
{
|
|
||||||
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:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code retentionScheduleId} is not a valid format or {@code retentionScheduleId} is invalid</li>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to add children to {@code retentionScheduleId}</li>
|
|
||||||
* <li>{@code retentionScheduleId} does not exist</li>
|
|
||||||
* <li>new name clashes with an existing node in the current parent container</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
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:
|
|
||||||
* <ul>
|
|
||||||
* <li>authentication fails</li>
|
|
||||||
* <li>current user does not have permission to read {@code recordCategoryId}</li>
|
|
||||||
* <li>{@code recordCategoryId} does not exist</li>
|
|
||||||
*</ul>
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,614 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rest.rm.community.hold;
|
|
||||||
|
|
||||||
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
|
|
||||||
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
|
|
||||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
|
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
|
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
|
|
||||||
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
|
|
||||||
import static org.alfresco.utility.report.log.Step.STEP;
|
|
||||||
import static org.awaitility.Awaitility.await;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.springframework.http.HttpStatus.ACCEPTED;
|
|
||||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
|
||||||
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 java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.alfresco.dataprep.CMISUtil;
|
|
||||||
import org.alfresco.dataprep.ContentActions;
|
|
||||||
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.BulkBodyCancel;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.Hold;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkOperation;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkOperation.HoldBulkOperationType;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkOperationEntry;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkStatus;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkStatusCollection;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldBulkStatusEntry;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldChild;
|
|
||||||
import org.alfresco.rest.rm.community.model.hold.HoldChildEntry;
|
|
||||||
import org.alfresco.rest.rm.community.model.user.UserRoles;
|
|
||||||
import org.alfresco.rest.search.RestRequestQueryModel;
|
|
||||||
import org.alfresco.rest.search.SearchRequest;
|
|
||||||
import org.alfresco.rest.v0.service.RoleService;
|
|
||||||
import org.alfresco.utility.constants.UserRole;
|
|
||||||
import org.alfresco.utility.model.FileModel;
|
|
||||||
import org.alfresco.utility.model.FolderModel;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API tests for adding items to holds via the bulk process
|
|
||||||
*/
|
|
||||||
public class AddToHoldsBulkV1Tests extends BaseRMRestTest
|
|
||||||
{
|
|
||||||
private static final String ACCESS_DENIED_ERROR_MESSAGE = "Access Denied. You do not have the appropriate " +
|
|
||||||
"permissions to perform this operation.";
|
|
||||||
private static final int NUMBER_OF_FILES = 5;
|
|
||||||
private final List<FileModel> addedFiles = new ArrayList<>();
|
|
||||||
private final List<UserModel> users = new ArrayList<>();
|
|
||||||
private final List<Hold> holds = new ArrayList<>();
|
|
||||||
private Hold hold;
|
|
||||||
private Hold hold2;
|
|
||||||
private Hold hold3;
|
|
||||||
private FolderModel rootFolder;
|
|
||||||
private HoldBulkOperation holdBulkOperation;
|
|
||||||
@Autowired
|
|
||||||
private RoleService roleService;
|
|
||||||
@Autowired
|
|
||||||
private ContentActions contentActions;
|
|
||||||
|
|
||||||
@BeforeClass(alwaysRun = true)
|
|
||||||
public void preconditionForAddContentToHold()
|
|
||||||
{
|
|
||||||
STEP("Create a hold.");
|
|
||||||
hold = getRestAPIFactory().getFilePlansAPI(getAdminUser()).createHold(
|
|
||||||
Hold.builder().name("HOLD" + generateTestPrefix(AddToHoldsV1Tests.class)).description(HOLD_DESCRIPTION)
|
|
||||||
.reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
|
|
||||||
holds.add(hold);
|
|
||||||
|
|
||||||
STEP("Create test files.");
|
|
||||||
testSite = dataSite.usingAdmin().createPublicRandomSite();
|
|
||||||
|
|
||||||
rootFolder = dataContent.usingAdmin().usingSite(testSite).createFolder();
|
|
||||||
FolderModel folder1 = dataContent.usingAdmin().usingResource(rootFolder).createFolder();
|
|
||||||
FolderModel folder2 = dataContent.usingAdmin().usingResource(folder1).createFolder();
|
|
||||||
|
|
||||||
// Add files to subfolders in the site
|
|
||||||
for (int i = 0; i < NUMBER_OF_FILES; i++)
|
|
||||||
{
|
|
||||||
FileModel documentHeld = dataContent.usingAdmin()
|
|
||||||
.usingResource(i % 2 == 0 ? folder1 : folder2)
|
|
||||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
|
||||||
addedFiles.add(documentHeld);
|
|
||||||
}
|
|
||||||
|
|
||||||
RestRequestQueryModel queryReq = getContentFromSiteQuery(testSite.getId());
|
|
||||||
SearchRequest searchRequest = new SearchRequest();
|
|
||||||
searchRequest.setQuery(queryReq);
|
|
||||||
|
|
||||||
STEP("Wait until all files are searchable.");
|
|
||||||
await().atMost(30, TimeUnit.SECONDS)
|
|
||||||
.until(() -> getRestAPIFactory().getSearchAPI(null).search(searchRequest).getPagination()
|
|
||||||
.getTotalItems() == NUMBER_OF_FILES);
|
|
||||||
|
|
||||||
holdBulkOperation = HoldBulkOperation.builder()
|
|
||||||
.query(queryReq)
|
|
||||||
.op(HoldBulkOperationType.ADD).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then the content is added to the hold and the status of the bulk operation is DONE
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void addContentFromTestSiteToHoldUsingBulkAPI()
|
|
||||||
{
|
|
||||||
UserModel userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userAddHoldPermission);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
assertEquals(NUMBER_OF_FILES, bulkOperationEntry.getTotalItems());
|
|
||||||
|
|
||||||
STEP("Wait until all files are added to the hold.");
|
|
||||||
await().atMost(20, TimeUnit.SECONDS).until(
|
|
||||||
() -> getRestAPIFactory().getHoldsAPI(getAdminUser()).getChildren(hold.getId()).getEntries().size()
|
|
||||||
== NUMBER_OF_FILES);
|
|
||||||
List<String> holdChildrenNodeRefs = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getChildren(hold.getId()).getEntries().stream().map(HoldChildEntry::getEntry).map(
|
|
||||||
HoldChild::getId).toList();
|
|
||||||
assertEquals(addedFiles.stream().map(FileModel::getNodeRefWithoutVersion).sorted().toList(),
|
|
||||||
holdChildrenNodeRefs.stream().sorted().toList());
|
|
||||||
|
|
||||||
STEP("Check the bulk status.");
|
|
||||||
HoldBulkStatus holdBulkStatus = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatus(hold.getId(), bulkOperationEntry.getBulkStatusId());
|
|
||||||
assertBulkProcessStatus(holdBulkStatus, NUMBER_OF_FILES, 0, null, holdBulkOperation);
|
|
||||||
|
|
||||||
STEP("Check the bulk statuses.");
|
|
||||||
HoldBulkStatusCollection holdBulkStatusCollection = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatuses(hold.getId());
|
|
||||||
assertEquals(Arrays.asList(holdBulkStatus),
|
|
||||||
holdBulkStatusCollection.getEntries().stream().map(HoldBulkStatusEntry::getEntry).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a folder and all subfolders to a hold using the bulk API
|
|
||||||
* Then the content is added to the hold and the status of the bulk operation is DONE
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void addContentFromFolderAndAllSubfoldersToHoldUsingBulkAPI()
|
|
||||||
{
|
|
||||||
hold3 = getRestAPIFactory().getFilePlansAPI(getAdminUser()).createHold(
|
|
||||||
Hold.builder().name("HOLD" + generateTestPrefix(AddToHoldsV1Tests.class)).description(HOLD_DESCRIPTION)
|
|
||||||
.reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
|
|
||||||
holds.add(hold3);
|
|
||||||
|
|
||||||
UserModel userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold3.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userAddHoldPermission);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
// Get content from folder and all subfolders of the root folder
|
|
||||||
HoldBulkOperation bulkOperation = HoldBulkOperation.builder()
|
|
||||||
.query(getContentFromFolderAndAllSubfoldersQuery(rootFolder.getNodeRefWithoutVersion()))
|
|
||||||
.op(HoldBulkOperationType.ADD).build();
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.startBulkProcess(bulkOperation, hold3.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
assertEquals(NUMBER_OF_FILES, bulkOperationEntry.getTotalItems());
|
|
||||||
|
|
||||||
STEP("Wait until all files are added to the hold.");
|
|
||||||
await().atMost(20, TimeUnit.SECONDS).until(
|
|
||||||
() -> getRestAPIFactory().getHoldsAPI(getAdminUser()).getChildren(hold3.getId()).getEntries().size()
|
|
||||||
== NUMBER_OF_FILES);
|
|
||||||
List<String> holdChildrenNodeRefs = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getChildren(hold3.getId()).getEntries().stream().map(HoldChildEntry::getEntry).map(
|
|
||||||
HoldChild::getId).toList();
|
|
||||||
assertEquals(addedFiles.stream().map(FileModel::getNodeRefWithoutVersion).sorted().toList(),
|
|
||||||
holdChildrenNodeRefs.stream().sorted().toList());
|
|
||||||
|
|
||||||
STEP("Check the bulk status.");
|
|
||||||
HoldBulkStatus holdBulkStatus = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatus(hold3.getId(), bulkOperationEntry.getBulkStatusId());
|
|
||||||
assertBulkProcessStatus(holdBulkStatus, NUMBER_OF_FILES, 0, null, bulkOperation);
|
|
||||||
|
|
||||||
STEP("Check the bulk statuses.");
|
|
||||||
HoldBulkStatusCollection holdBulkStatusCollection = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatuses(hold3.getId());
|
|
||||||
assertEquals(List.of(holdBulkStatus),
|
|
||||||
holdBulkStatusCollection.getEntries().stream().map(HoldBulkStatusEntry::getEntry).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user without the add to hold capability
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then the user receives access denied error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessWithUserWithoutAddToHoldCapability()
|
|
||||||
{
|
|
||||||
UserModel userWithoutAddToHoldCapability = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole
|
|
||||||
.SiteCollaborator,
|
|
||||||
hold.getId(), UserRoles.ROLE_RM_POWER_USER, PERMISSION_FILING);
|
|
||||||
users.add(userWithoutAddToHoldCapability);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
getRestAPIFactory().getHoldsAPI(userWithoutAddToHoldCapability)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response status code and the error message.");
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(ACCESS_DENIED_ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user without the filing permission on a hold
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then the user receives access denied error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessWithUserWithoutFilingPermissionOnAHold()
|
|
||||||
{
|
|
||||||
// User without filing permission on a hold
|
|
||||||
UserModel userWithoutPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_READ_RECORDS);
|
|
||||||
users.add(userWithoutPermission);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
getRestAPIFactory().getHoldsAPI(userWithoutPermission)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response status code and the error message.");
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(ACCESS_DENIED_ERROR_MESSAGE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user without the write permission on all the content
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then all processed items are marked as errors and the last error message contains access denied error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessWithUserWithoutWritePermissionOnTheContent()
|
|
||||||
{
|
|
||||||
// User without write permission on the content
|
|
||||||
UserModel userWithoutPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(
|
|
||||||
testSite, UserRole.SiteConsumer,
|
|
||||||
hold.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userWithoutPermission);
|
|
||||||
|
|
||||||
// Wait until permissions are reverted
|
|
||||||
SearchRequest searchRequest = new SearchRequest();
|
|
||||||
searchRequest.setQuery(holdBulkOperation.getQuery());
|
|
||||||
await().atMost(30, TimeUnit.SECONDS)
|
|
||||||
.until(() -> getRestAPIFactory().getSearchAPI(userWithoutPermission).search(searchRequest).getPagination()
|
|
||||||
.getTotalItems() == NUMBER_OF_FILES);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(
|
|
||||||
userWithoutPermission).startBulkProcess(holdBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response.");
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
|
|
||||||
await().atMost(20, TimeUnit.SECONDS).until(() ->
|
|
||||||
Objects.equals(getRestAPIFactory().getHoldsAPI(userWithoutPermission)
|
|
||||||
.getBulkStatus(hold.getId(), bulkOperationEntry.getBulkStatusId()).getStatus(), "DONE"));
|
|
||||||
|
|
||||||
HoldBulkStatus holdBulkStatus = getRestAPIFactory().getHoldsAPI(userWithoutPermission)
|
|
||||||
.getBulkStatus(hold.getId(), bulkOperationEntry.getBulkStatusId());
|
|
||||||
assertBulkProcessStatus(holdBulkStatus, NUMBER_OF_FILES, NUMBER_OF_FILES, ACCESS_DENIED_ERROR_MESSAGE,
|
|
||||||
holdBulkOperation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user without the write permission on one file
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then all processed items are added to the hold except the one that the user does not have write permission
|
|
||||||
* And the status of the bulk operation is DONE, contains the error message and the number of errors is 1
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessWithUserWithoutWritePermissionOnOneFile()
|
|
||||||
{
|
|
||||||
hold2 = getRestAPIFactory().getFilePlansAPI(getAdminUser()).createHold(
|
|
||||||
Hold.builder().name("HOLD" + generateTestPrefix(AddToHoldsV1Tests.class)).description(HOLD_DESCRIPTION)
|
|
||||||
.reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
|
|
||||||
holds.add(hold2);
|
|
||||||
|
|
||||||
UserModel userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold2.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userAddHoldPermission);
|
|
||||||
|
|
||||||
contentActions.setPermissionForUser(getAdminUser().getUsername(), getAdminUser().getPassword(),
|
|
||||||
testSite.getId(), addedFiles.get(0).getName(), userAddHoldPermission.getUsername(),
|
|
||||||
UserRole.SiteConsumer.getRoleId(), false);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold2.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
assertEquals(NUMBER_OF_FILES, bulkOperationEntry.getTotalItems());
|
|
||||||
|
|
||||||
STEP("Wait until all files are added to the hold.");
|
|
||||||
await().atMost(30, TimeUnit.SECONDS).until(
|
|
||||||
() -> getRestAPIFactory().getHoldsAPI(getAdminUser()).getChildren(hold2.getId()).getEntries().size()
|
|
||||||
== NUMBER_OF_FILES - 1);
|
|
||||||
await().atMost(30, TimeUnit.SECONDS).until(
|
|
||||||
() -> getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatus(hold2.getId(), bulkOperationEntry.getBulkStatusId()).getProcessedItems()
|
|
||||||
== NUMBER_OF_FILES);
|
|
||||||
List<String> holdChildrenNodeRefs = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getChildren(hold2.getId()).getEntries().stream().map(HoldChildEntry::getEntry).map(
|
|
||||||
HoldChild::getId).toList();
|
|
||||||
assertEquals(addedFiles.stream().skip(1).map(FileModel::getNodeRefWithoutVersion).sorted().toList(),
|
|
||||||
holdChildrenNodeRefs.stream().sorted().toList());
|
|
||||||
|
|
||||||
STEP("Check the bulk status.");
|
|
||||||
HoldBulkStatus holdBulkStatus = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatus(hold2.getId(), bulkOperationEntry.getBulkStatusId());
|
|
||||||
assertBulkProcessStatus(holdBulkStatus, NUMBER_OF_FILES, 1, ACCESS_DENIED_ERROR_MESSAGE, holdBulkOperation);
|
|
||||||
|
|
||||||
STEP("Check the bulk statuses.");
|
|
||||||
HoldBulkStatusCollection holdBulkStatusCollection = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.getBulkStatuses(hold2.getId());
|
|
||||||
assertEquals(List.of(holdBulkStatus),
|
|
||||||
holdBulkStatusCollection.getEntries().stream().map(HoldBulkStatusEntry::getEntry).toList());
|
|
||||||
|
|
||||||
// Revert the permissions
|
|
||||||
contentActions.setPermissionForUser(getAdminUser().getUsername(), getAdminUser().getPassword(),
|
|
||||||
testSite.getId(), addedFiles.get(0).getName(), userAddHoldPermission.getUsername(),
|
|
||||||
UserRole.SiteCollaborator.getRoleId(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an unauthenticated user
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* Then the user receives unauthorized error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessAsUnauthenticatedUser()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process as unauthenticated user");
|
|
||||||
getRestAPIFactory().getHoldsAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword"))
|
|
||||||
.startBulkProcess(holdBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And the hold does not exist
|
|
||||||
* Then the user receives not found error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessForNonExistentHold()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process for non existent hold");
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).startBulkProcess(holdBulkOperation, "nonExistentHoldId");
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* and the bulk operation is invalid
|
|
||||||
* Then the user receives bad request error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusesForInvalidOperation()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process for non existent hold");
|
|
||||||
|
|
||||||
HoldBulkOperation invalidHoldBulkOperation = HoldBulkOperation.builder().op(null)
|
|
||||||
.query(holdBulkOperation.getQuery()).build();
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).startBulkProcess(invalidHoldBulkOperation, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And the hold does not exist
|
|
||||||
* Then the user receives not found error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusForNonExistentHold()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process for non existent hold");
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).getBulkStatus("nonExistentHoldId", "nonExistenBulkStatusId");
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And the bulk status does not exist
|
|
||||||
* Then the user receives not found error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusForNonExistentBulkStatus()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process for non bulk status");
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).getBulkStatus(hold.getId(), "nonExistenBulkStatusId");
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And the hold does not exist
|
|
||||||
* Then the user receives not found error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusesForNonExistentHold()
|
|
||||||
{
|
|
||||||
STEP("Start bulk process for non existent hold");
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).getBulkStatuses("nonExistentHoldId");
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from all sites to a hold using the bulk API to exceed the limit (30 items)
|
|
||||||
* Then the user receives bad request error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExceedingBulkOperationLimit()
|
|
||||||
{
|
|
||||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
|
||||||
queryReq.setQuery("TYPE:content");
|
|
||||||
queryReq.setLanguage("afts");
|
|
||||||
|
|
||||||
HoldBulkOperation exceedLimitOp = HoldBulkOperation.builder()
|
|
||||||
.query(queryReq)
|
|
||||||
.op(HoldBulkOperationType.ADD).build();
|
|
||||||
|
|
||||||
STEP("Start bulk process to exceed the limit");
|
|
||||||
getRestAPIFactory().getHoldsAPI(getAdminUser()).startBulkProcess(exceedLimitOp, hold.getId());
|
|
||||||
|
|
||||||
STEP("Verify the response status code.");
|
|
||||||
assertStatusCode(BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And then the user cancels the bulk operation
|
|
||||||
* Then the user receives OK status code
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessCancellationWithAllowedUser()
|
|
||||||
{
|
|
||||||
Hold hold4 = getRestAPIFactory().getFilePlansAPI(getAdminUser()).createHold(
|
|
||||||
Hold.builder().name("HOLD" + generateTestPrefix(AddToHoldsV1Tests.class)).description(HOLD_DESCRIPTION)
|
|
||||||
.reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
|
|
||||||
holds.add(hold4);
|
|
||||||
|
|
||||||
UserModel userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold4.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userAddHoldPermission);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold4.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
assertEquals(NUMBER_OF_FILES, bulkOperationEntry.getTotalItems());
|
|
||||||
|
|
||||||
STEP("Cancel the bulk operation.");
|
|
||||||
getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.cancelBulkOperation(hold4.getId(), bulkOperationEntry.getBulkStatusId(), new BulkBodyCancel());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a user with the add to hold capability and hold filing permission
|
|
||||||
* When the user adds content from a site to a hold using the bulk API
|
|
||||||
* And a 2nd user without the add to hold capability cancels the bulk operation
|
|
||||||
* Then the 2nd user receives access denied error
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBulkProcessCancellationWithUserWithoutAddToHoldCapability()
|
|
||||||
{
|
|
||||||
Hold hold5 = getRestAPIFactory().getFilePlansAPI(getAdminUser()).createHold(
|
|
||||||
Hold.builder().name("HOLD" + generateTestPrefix(AddToHoldsV1Tests.class)).description(HOLD_DESCRIPTION)
|
|
||||||
.reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
|
|
||||||
holds.add(hold5);
|
|
||||||
|
|
||||||
UserModel userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole.SiteCollaborator, hold5.getId(), UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
|
||||||
users.add(userAddHoldPermission);
|
|
||||||
|
|
||||||
STEP("Add content from the site to the hold using the bulk API.");
|
|
||||||
HoldBulkOperationEntry bulkOperationEntry = getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
|
|
||||||
.startBulkProcess(holdBulkOperation, hold5.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(ACCEPTED);
|
|
||||||
assertEquals(NUMBER_OF_FILES, bulkOperationEntry.getTotalItems());
|
|
||||||
|
|
||||||
UserModel userWithoutAddToHoldCapability = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
|
|
||||||
UserRole
|
|
||||||
.SiteCollaborator,
|
|
||||||
hold5.getId(), UserRoles.ROLE_RM_POWER_USER, PERMISSION_FILING);
|
|
||||||
users.add(userWithoutAddToHoldCapability);
|
|
||||||
|
|
||||||
STEP("Cancel the bulk operation.");
|
|
||||||
getRestAPIFactory().getHoldsAPI(userWithoutAddToHoldCapability)
|
|
||||||
.cancelBulkOperation(hold5.getId(), bulkOperationEntry.getBulkStatusId(), new BulkBodyCancel());
|
|
||||||
|
|
||||||
STEP("Verify the response status code and the error message.");
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(ACCESS_DENIED_ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertBulkProcessStatus(HoldBulkStatus holdBulkStatus, long expectedProcessedItems,
|
|
||||||
int expectedErrorsCount, String expectedErrorMessage, HoldBulkOperation holdBulkOperation)
|
|
||||||
{
|
|
||||||
assertEquals("DONE", holdBulkStatus.getStatus());
|
|
||||||
assertEquals(expectedProcessedItems, holdBulkStatus.getTotalItems());
|
|
||||||
assertEquals(expectedProcessedItems, holdBulkStatus.getProcessedItems());
|
|
||||||
assertEquals(expectedErrorsCount, holdBulkStatus.getErrorsCount());
|
|
||||||
assertEquals(holdBulkStatus.getHoldBulkOperation(), holdBulkOperation);
|
|
||||||
assertNotNull(holdBulkStatus.getStartTime());
|
|
||||||
assertNotNull(holdBulkStatus.getEndTime());
|
|
||||||
|
|
||||||
if (expectedErrorMessage != null)
|
|
||||||
{
|
|
||||||
assertTrue(holdBulkStatus.getLastError().contains(expectedErrorMessage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RestRequestQueryModel getContentFromSiteQuery(String siteId)
|
|
||||||
{
|
|
||||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
|
||||||
queryReq.setQuery("SITE:\"" + siteId + "\" and TYPE:content");
|
|
||||||
queryReq.setLanguage("afts");
|
|
||||||
return queryReq;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RestRequestQueryModel getContentFromFolderAndAllSubfoldersQuery(String folderId)
|
|
||||||
{
|
|
||||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
|
||||||
queryReq.setQuery("ANCESTOR:\"workspace://SpacesStore/" + folderId + "\" and TYPE:content");
|
|
||||||
queryReq.setLanguage("afts");
|
|
||||||
return queryReq;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass(alwaysRun = true)
|
|
||||||
public void cleanupAddToHoldsBulkV1Tests()
|
|
||||||
{
|
|
||||||
dataSite.usingAdmin().deleteSite(testSite);
|
|
||||||
users.forEach(user -> getDataUser().usingAdmin().deleteUser(user));
|
|
||||||
holds.forEach(hold -> getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(hold.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,377 +0,0 @@
|
|||||||
/*-
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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<String> 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<String> 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 = "destroyContent";
|
|
||||||
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.setCombineRetentionStepConditions(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);
|
|
||||||
actionDefinition.setLocation("location");
|
|
||||||
//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);
|
|
||||||
actionDefinition1.setLocation("location");
|
|
||||||
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 combineRetentionStepConditionsNotValidForNonAccessionStep()
|
|
||||||
{
|
|
||||||
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
|
|
||||||
recordCategories.add(recordCategory.getId());
|
|
||||||
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
|
|
||||||
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
|
|
||||||
actionDefinition.setName(RETAIN_STEP);
|
|
||||||
actionDefinition.setCombineRetentionStepConditions(true);
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
|
|
||||||
|
|
||||||
assertStatusCode(BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 6)
|
|
||||||
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 = 7)
|
|
||||||
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);
|
|
||||||
actionDefinition1.setLocation("location");
|
|
||||||
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId());
|
|
||||||
|
|
||||||
RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
|
|
||||||
actionDefinition2.setName(TRANSFER_STEP);
|
|
||||||
actionDefinition2.setLocation("location");
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(CREATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 8)
|
|
||||||
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.isCombineRetentionStepConditions(), retentionScheduleActionDefinition.isCombineRetentionStepConditions());
|
|
||||||
assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 9)
|
|
||||||
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 = 10)
|
|
||||||
public void createRetentionScheduleStepFor403()
|
|
||||||
{
|
|
||||||
//Create retention schedule action definition
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 11)
|
|
||||||
public void retentionScheduleStepFor400()
|
|
||||||
{
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 12)
|
|
||||||
public void createRetentionScheduleStepFor404()
|
|
||||||
{
|
|
||||||
//Create retention schedule action definition
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(retentionScheduleActionDefinition,getRandomAlphanumeric());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 13)
|
|
||||||
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 = 14)
|
|
||||||
public void retentionScheduleStepFor401()
|
|
||||||
{
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(priority = 15)
|
|
||||||
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.isCombineRetentionStepConditions(), retentionActionDef.isCombineRetentionStepConditions());
|
|
||||||
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.setCombineRetentionStepConditions(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
/*-
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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.RetentionScheduleCollection;
|
|
||||||
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 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.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.testng.Assert.assertFalse;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.AssertJUnit.assertEquals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class contains the tests for the Retention Schedule CRUD V1 API
|
|
||||||
*/
|
|
||||||
public class RetentionScheduleTests extends BaseRMRestTest
|
|
||||||
{
|
|
||||||
private RecordCategory recordCategory;
|
|
||||||
private RetentionSchedule createdRetentionSchedule;
|
|
||||||
private UserModel nonRMuser;
|
|
||||||
@Autowired
|
|
||||||
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
|
|
||||||
|
|
||||||
@BeforeClass(alwaysRun = true)
|
|
||||||
public void preconditionForRetentionScheduleTests()
|
|
||||||
{
|
|
||||||
createRMSiteIfNotExists();
|
|
||||||
// create a non rm user
|
|
||||||
nonRMuser = dataUser.createRandomTestUser("testUser");
|
|
||||||
//Create record category
|
|
||||||
recordCategory = createRootCategory(getRandomName("recordCategory"));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to create a retention schedule with a user having no rights
|
|
||||||
* Then it will give 403 as status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 1)
|
|
||||||
public void createRetentionScheduleFor403()
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
|
|
||||||
// Create retention schedule with user having no rights
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionSchedule(retentionSchedule, recordCategory.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category does not exists
|
|
||||||
* When I ask the API to create a retention schedule on a category Id
|
|
||||||
* Then it will give 404 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 2)
|
|
||||||
public void createRetentionScheduleFor404()
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
|
|
||||||
//Create retention schedule with category id not exist
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().createRetentionSchedule(retentionSchedule, getRandomAlphanumeric());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to create a retention schedule on a category id with a user having unauthorized access
|
|
||||||
* Then it will give 401 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 3)
|
|
||||||
public void createRetentionScheduleFor401()
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
|
|
||||||
//Create retention schedule with a user with unauthorized access
|
|
||||||
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).createRetentionSchedule(retentionSchedule, recordCategory.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to create a retention schedule with a user having access
|
|
||||||
* Then it is created with a 201 status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 4)
|
|
||||||
public void createRetentionScheduleFor201()
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
String authority = "authority" + getRandomAlphanumeric();
|
|
||||||
String instructions = "instructions" + getRandomAlphanumeric();
|
|
||||||
boolean isRecordLevel = false;
|
|
||||||
retentionSchedule.setAuthority(authority);
|
|
||||||
retentionSchedule.setInstructions(instructions);
|
|
||||||
retentionSchedule.setIsRecordLevel(isRecordLevel);
|
|
||||||
|
|
||||||
//Create retention schedule with a valid user
|
|
||||||
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
|
|
||||||
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(CREATED);
|
|
||||||
assertEquals(createdRetentionSchedule.getAuthority(), authority);
|
|
||||||
assertEquals(createdRetentionSchedule.getInstructions(), instructions);
|
|
||||||
assertFalse(createdRetentionSchedule.getIsRecordLevel());
|
|
||||||
assertNotNull(createdRetentionSchedule.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to create a retention schedule on a category id having retention schedule already
|
|
||||||
* Then it will give 409 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 5)
|
|
||||||
public void createRetentionScheduleFor409()
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
//Create retention schedule on a category with already having retention schedule
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI()
|
|
||||||
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
|
|
||||||
|
|
||||||
assertStatusCode(CONFLICT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to get a retention schedule on a given categoryId with a user having no rights
|
|
||||||
* Then it will give 403
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 6)
|
|
||||||
public void retentionScheduleWith403()
|
|
||||||
{
|
|
||||||
//Get retention schedule with user having no rights
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).getRetentionSchedule(recordCategory.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category does not exists
|
|
||||||
* When I ask the API to get a retention schedule on a category Id
|
|
||||||
* Then it will give 404 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 7)
|
|
||||||
public void retentionScheduleWith404()
|
|
||||||
{
|
|
||||||
|
|
||||||
//Get retention schedule with category id that does not exist
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(getRandomAlphanumeric());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to get a retention schedule on a categoryId with a user having unauthorized access
|
|
||||||
* Then it will give 401 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 8)
|
|
||||||
public void retentionScheduleWith401()
|
|
||||||
{
|
|
||||||
//Create retention schedule with a user with unauthorized access
|
|
||||||
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).getRetentionSchedule(recordCategory.getId());
|
|
||||||
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Given that a record category exists
|
|
||||||
* When I ask the API to get a retention schedule on a categoryId with a user having access
|
|
||||||
* Then it will give retentionSchedule with 200 as a status code
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Test(priority = 9)
|
|
||||||
public void retentionScheduleWith200()
|
|
||||||
{
|
|
||||||
RetentionScheduleCollection retentionScheduleCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(recordCategory.getId());
|
|
||||||
// Verify the status code
|
|
||||||
assertStatusCode(OK);
|
|
||||||
retentionScheduleCollection.getEntries().forEach(c ->
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = c.getEntry();
|
|
||||||
String retentionScheduleId = retentionSchedule.getId();
|
|
||||||
assertNotNull(retentionScheduleId);
|
|
||||||
logger.info("Checking retention schedule " + retentionScheduleId);
|
|
||||||
|
|
||||||
// Find this retention schedule is created one or not
|
|
||||||
assertEquals(createdRetentionSchedule.getId(), retentionScheduleId);
|
|
||||||
assertEquals(createdRetentionSchedule.getParentId(),retentionSchedule.getParentId());
|
|
||||||
assertEquals(createdRetentionSchedule.getAuthority(), retentionSchedule.getAuthority());
|
|
||||||
assertEquals(createdRetentionSchedule.getInstructions(), retentionSchedule.getInstructions());
|
|
||||||
assertEquals(createdRetentionSchedule.getIsRecordLevel(), retentionSchedule.getIsRecordLevel());
|
|
||||||
assertEquals(createdRetentionSchedule.isUnpublishedUpdates(), retentionSchedule.isUnpublishedUpdates());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass(alwaysRun = true)
|
|
||||||
public void cleanUpRetentionScheduleTests()
|
|
||||||
{
|
|
||||||
rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
|
||||||
getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategory.getName());
|
|
||||||
deleteRecordCategory(recordCategory.getId());
|
|
||||||
dataUser.deleteUser(nonRMuser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -45,9 +45,9 @@ serverHealth.showTenants=false
|
|||||||
# testManagement.username=<username>
|
# testManagement.username=<username>
|
||||||
# testManagement.apiKey=<api-key>
|
# testManagement.apiKey=<api-key>
|
||||||
# testManagement.project=<id-of-your-project
|
# testManagement.project=<id-of-your-project
|
||||||
# testManagement.testRun=<test-run-name>
|
# testManagement.testRun=<test-run-name>
|
||||||
# testManagement.includeOnlyTestCasesExecuted=true #if you want to include in your run ONLY the test cases that you run, then set this value to false
|
# testManagement.includeOnlyTestCasesExecuted=true #if you want to include in your run ONLY the test cases that you run, then set this value to false
|
||||||
# testManagement.rateLimitInSeconds=1 #is the default rate limit after what minimum time, should we upload the next request. http://docs.gurock.com/testrail-api2/introduction #Rate Limit
|
# testManagement.rateLimitInSeconds=1 #is the default rate limit after what minimum time, should we upload the next request. http://docs.gurock.com/testrail-api2/introduction #Rate Limit
|
||||||
# testManagement.suiteId=23 (the id of the Master suite)
|
# testManagement.suiteId=23 (the id of the Master suite)
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
testManagement.enabled=false
|
testManagement.enabled=false
|
||||||
@@ -72,7 +72,7 @@ reports.path=./target/reports
|
|||||||
#
|
#
|
||||||
# MySQL:
|
# MySQL:
|
||||||
# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
|
# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
|
||||||
#
|
#
|
||||||
# PostgreSQL:
|
# PostgreSQL:
|
||||||
# db.url = jdbc:postgresql://<your-DB-IP>:3306/alfresco
|
# db.url = jdbc:postgresql://<your-DB-IP>:3306/alfresco
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
SOLR6_TAG=2.0.11
|
SOLR6_TAG=2.0.10
|
||||||
POSTGRES_TAG=15.4
|
POSTGRES_TAG=15.4
|
||||||
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
||||||
|
|||||||
@@ -139,26 +139,3 @@ content.metadata.async.extract.6.enabled=false
|
|||||||
|
|
||||||
# Max number of entries returned in Record search view
|
# Max number of entries returned in Record search view
|
||||||
rm.recordSearch.maxItems=500
|
rm.recordSearch.maxItems=500
|
||||||
|
|
||||||
#
|
|
||||||
# Hold bulk
|
|
||||||
#
|
|
||||||
# The number of worker threads.
|
|
||||||
rm.hold.bulk.threadCount=2
|
|
||||||
# The maximum number of total items to process in a single bulk operation.
|
|
||||||
rm.hold.bulk.maxItems=1000
|
|
||||||
# The number of entries to be fetched from the Search Service as a next set of work object to process.
|
|
||||||
rm.hold.bulk.batchSize=100
|
|
||||||
# The number of entries to process before reporting progress.
|
|
||||||
rm.hold.bulk.logging.interval=100
|
|
||||||
# The number of entries we process at a time in a transaction.
|
|
||||||
rm.hold.bulk.itemsPerTransaction=1
|
|
||||||
# The maximum number of bulk requests we can process in parallel.
|
|
||||||
rm.hold.bulk.maxParallelRequests=10
|
|
||||||
|
|
||||||
cache.bulkHoldStatusCache.cluster.type=fully-distributed
|
|
||||||
cache.bulkHoldStatusCache.timeToLiveSeconds=2592000
|
|
||||||
cache.bulkHoldRegistryCache.cluster.type=fully-distributed
|
|
||||||
cache.bulkHoldRegistryCache.timeToLiveSeconds=2592000
|
|
||||||
cache.bulkCancellationsCache.cluster.type=fully-distributed
|
|
||||||
cache.bulkCancellationsCache.timeToLiveSeconds=2592000
|
|
||||||
@@ -31,11 +31,6 @@
|
|||||||
<cm:description>Configuration information for the Records Management application.</cm:description>
|
<cm:description>Configuration information for the Records Management application.</cm:description>
|
||||||
</view:properties>
|
</view:properties>
|
||||||
|
|
||||||
<view:aspects>
|
|
||||||
<sys:undeletable/>
|
|
||||||
<sys:unmovable/>
|
|
||||||
</view:aspects>
|
|
||||||
|
|
||||||
<view:associations>
|
<view:associations>
|
||||||
<cm:contains>
|
<cm:contains>
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
parent="declarativeCapability">
|
parent="declarativeCapability">
|
||||||
<property name="name" value="DeleteRecordFolder"/>
|
<property name="name" value="DeleteRecordFolder"/>
|
||||||
<property name="private" value="true"/>
|
<property name="private" value="true"/>
|
||||||
<property name="permission" value="DeleteRecords"/>
|
<property name="permission" value="CreateModifyDestroyFolders"/>
|
||||||
<property name="kinds">
|
<property name="kinds">
|
||||||
<list>
|
<list>
|
||||||
<value>RECORD_FOLDER</value>
|
<value>RECORD_FOLDER</value>
|
||||||
|
|||||||
@@ -89,9 +89,6 @@
|
|||||||
<!-- Import RM Audit -->
|
<!-- Import RM Audit -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-audit-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-audit-context.xml"/>
|
||||||
|
|
||||||
<!-- Import RM Bulk -->
|
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-bulk-context.xml"/>
|
|
||||||
|
|
||||||
<!-- Import RM query context -->
|
<!-- Import RM query context -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/query/rm-query-context.xml" />
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/query/rm-query-context.xml" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:context="http://www.springframework.org/schema/context"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
|
||||||
http://www.springframework.org/schema/context
|
|
||||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
|
||||||
|
|
||||||
<bean id="holdBulkService"
|
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkServiceImpl">
|
|
||||||
<property name="serviceRegistry" ref="ServiceRegistry" />
|
|
||||||
<property name="transactionService" ref="transactionService" />
|
|
||||||
<property name="searchMapper" ref="searchapiSearchMapper" />
|
|
||||||
<property name="bulkMonitor" ref="holdBulkMonitor" />
|
|
||||||
<property name="holdService" ref="HoldService" />
|
|
||||||
<property name="capabilityService" ref="CapabilityService" />
|
|
||||||
<property name="permissionService" ref="PermissionService" />
|
|
||||||
<property name="nodeService" ref="NodeService" />
|
|
||||||
<property name="threadCount">
|
|
||||||
<value>${rm.hold.bulk.threadCount}</value>
|
|
||||||
</property>
|
|
||||||
<property name="batchSize">
|
|
||||||
<value>${rm.hold.bulk.batchSize}</value>
|
|
||||||
</property>
|
|
||||||
<property name="maxItems">
|
|
||||||
<value>${rm.hold.bulk.maxItems}</value>
|
|
||||||
</property>
|
|
||||||
<property name="loggingInterval">
|
|
||||||
<value>${rm.hold.bulk.logging.interval}</value>
|
|
||||||
</property>
|
|
||||||
<property name="itemsPerTransaction">
|
|
||||||
<value>${rm.hold.bulk.itemsPerTransaction}</value>
|
|
||||||
</property>
|
|
||||||
<property name="maxParallelRequests">
|
|
||||||
<value>${rm.hold.bulk.maxParallelRequests}</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="holdBulkMonitor" class="org.alfresco.module.org_alfresco_module_rm.bulk.hold.DefaultHoldBulkMonitor">
|
|
||||||
<property name="holdProgressCache" ref="holdProgressCache" />
|
|
||||||
<property name="holdProcessRegistry" ref="holdProcessRegistry" />
|
|
||||||
<property name="bulkCancellationsCache" ref="bulkCancellationsCache" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
|
|
||||||
<bean name="holdProgressCache" factory-bean="cacheFactory" factory-method="createCache">
|
|
||||||
<constructor-arg value="cache.bulkHoldStatusCache" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean name="holdProcessRegistry" factory-bean="cacheFactory" factory-method="createCache">
|
|
||||||
<constructor-arg value="cache.bulkHoldRegistryCache" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean name="bulkCancellationsCache" factory-bean="cacheFactory" factory-method="createCache">
|
|
||||||
<constructor-arg value="cache.bulkCancellationsCache" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
||||||
@@ -31,7 +31,6 @@
|
|||||||
<property name="personService" ref="PersonService"/>
|
<property name="personService" ref="PersonService"/>
|
||||||
<property name="dispositionService" ref="DispositionService"/>
|
<property name="dispositionService" ref="DispositionService"/>
|
||||||
<property name="serviceRegistry" ref="ServiceRegistry"/>
|
<property name="serviceRegistry" ref="ServiceRegistry"/>
|
||||||
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="searchTypesFactory" class="org.alfresco.rm.rest.api.impl.SearchTypesFactory">
|
<bean id="searchTypesFactory" class="org.alfresco.rm.rest.api.impl.SearchTypesFactory">
|
||||||
@@ -84,14 +83,6 @@
|
|||||||
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
||||||
<property name="fileFolderService" ref="FileFolderService" />
|
<property name="fileFolderService" ref="FileFolderService" />
|
||||||
<property name="transactionService" ref="transactionService" />
|
<property name="transactionService" ref="transactionService" />
|
||||||
<property name="holdBulkService" ref="holdBulkService" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean class="org.alfresco.rm.rest.api.holds.HoldsBulkStatusesRelation" >
|
|
||||||
<property name="holdBulkMonitor" ref="holdBulkMonitor" />
|
|
||||||
<property name="holdBulkService" ref="holdBulkService" />
|
|
||||||
<property name="apiUtils" ref="apiUtils" />
|
|
||||||
<property name="permissionService" ref="PermissionService" />
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rm.rest.api.holds.HoldsChildrenRelation">
|
<bean class="org.alfresco.rm.rest.api.holds.HoldsChildrenRelation">
|
||||||
@@ -148,20 +139,6 @@
|
|||||||
<property name="transactionService" ref="transactionService" />
|
<property name="transactionService" ref="transactionService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rm.rest.api.retentionschedule.RetentionScheduleRelation">
|
|
||||||
<property name="apiUtils" ref="apiUtils" />
|
|
||||||
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
|
||||||
<property name="dispositionService" ref="DispositionService"/>
|
|
||||||
<property name="nodeService" ref="NodeService"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean class="org.alfresco.rm.rest.api.retentionschedule.RetentionScheduleActionRelation">
|
|
||||||
<property name="apiUtils" ref="apiUtils" />
|
|
||||||
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
|
||||||
<property name="nodeService" ref="NodeService"/>
|
|
||||||
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderEntityResource">
|
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderEntityResource">
|
||||||
<property name="apiUtils" ref="apiUtils" />
|
<property name="apiUtils" ref="apiUtils" />
|
||||||
<property name="fileFolderService" ref="FileFolderService" />
|
<property name="fileFolderService" ref="FileFolderService" />
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ services:
|
|||||||
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
|
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
|
||||||
-Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
|
-Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
|
||||||
-DlocalTransform.core-aio.url=http://transform-core-aio:8090/
|
-DlocalTransform.core-aio.url=http://transform-core-aio:8090/
|
||||||
-Drm.hold.bulk.maxItems=5
|
|
||||||
-Drm.hold.bulk.batchSize=2
|
|
||||||
"
|
"
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -155,12 +155,6 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.awaitility</groupId>
|
|
||||||
<artifactId>awaitility</artifactId>
|
|
||||||
<version>${dependency.awaitility.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,265 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import static java.util.concurrent.Executors.newFixedThreadPool;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import org.alfresco.repo.batch.BatchProcessWorkProvider;
|
|
||||||
import org.alfresco.repo.batch.BatchProcessor;
|
|
||||||
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
|
|
||||||
import org.alfresco.rest.api.search.impl.SearchMapper;
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
|
||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class for executing bulk operations on nodes based on search query results
|
|
||||||
*/
|
|
||||||
public abstract class BulkBaseService<T> implements InitializingBean
|
|
||||||
{
|
|
||||||
private static final Log LOG = LogFactory.getLog(BulkBaseService.class);
|
|
||||||
protected ExecutorService executorService;
|
|
||||||
protected ServiceRegistry serviceRegistry;
|
|
||||||
protected SearchService searchService;
|
|
||||||
protected TransactionService transactionService;
|
|
||||||
protected SearchMapper searchMapper;
|
|
||||||
protected BulkMonitor<T> bulkMonitor;
|
|
||||||
|
|
||||||
protected int threadCount;
|
|
||||||
protected int batchSize;
|
|
||||||
protected int itemsPerTransaction;
|
|
||||||
protected int maxItems;
|
|
||||||
protected int loggingInterval;
|
|
||||||
protected int maxParallelRequests;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet() throws Exception
|
|
||||||
{
|
|
||||||
this.searchService = serviceRegistry.getSearchService();
|
|
||||||
this.executorService = newFixedThreadPool(maxParallelRequests);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute bulk operation on node based on the search query results
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param bulkOperation bulk operation
|
|
||||||
* @return bulk status
|
|
||||||
*/
|
|
||||||
public T execute(NodeRef nodeRef, BulkOperation bulkOperation)
|
|
||||||
{
|
|
||||||
checkPermissions(nodeRef, bulkOperation);
|
|
||||||
|
|
||||||
ResultSet resultSet = getTotalItems(bulkOperation.searchQuery(), maxItems);
|
|
||||||
if (maxItems < resultSet.getNumberFound() || resultSet.hasMore())
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException("Too many items to process. Please refine your query.");
|
|
||||||
}
|
|
||||||
long totalItems = resultSet.getNumberFound();
|
|
||||||
// Generate a random process id
|
|
||||||
String processId = UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
T initBulkStatus = getInitBulkStatus(processId, totalItems);
|
|
||||||
bulkMonitor.updateBulkStatus(initBulkStatus);
|
|
||||||
bulkMonitor.registerProcess(nodeRef, processId, bulkOperation);
|
|
||||||
|
|
||||||
BulkProgress bulkProgress = new BulkProgress(totalItems, processId, new AtomicBoolean(false),
|
|
||||||
new AtomicInteger(0));
|
|
||||||
BatchProcessWorker<NodeRef> batchProcessWorker = getWorkerProvider(nodeRef, bulkOperation, bulkProgress);
|
|
||||||
BulkStatusUpdater bulkStatusUpdater = getBulkStatusUpdater();
|
|
||||||
|
|
||||||
BatchProcessor<NodeRef> batchProcessor = new BatchProcessor<>(
|
|
||||||
processId,
|
|
||||||
transactionService.getRetryingTransactionHelper(),
|
|
||||||
getWorkProvider(bulkOperation, bulkStatusUpdater, bulkProgress),
|
|
||||||
threadCount,
|
|
||||||
itemsPerTransaction,
|
|
||||||
bulkStatusUpdater,
|
|
||||||
LOG,
|
|
||||||
loggingInterval);
|
|
||||||
|
|
||||||
runAsyncBatchProcessor(batchProcessor, batchProcessWorker, bulkStatusUpdater);
|
|
||||||
return initBulkStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run batch processor
|
|
||||||
*/
|
|
||||||
protected void runAsyncBatchProcessor(BatchProcessor<NodeRef> batchProcessor,
|
|
||||||
BatchProcessWorker<NodeRef> batchProcessWorker, BulkStatusUpdater bulkStatusUpdater)
|
|
||||||
{
|
|
||||||
Runnable backgroundLogic = () -> {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOG.debug("Started processing batch with name: " + batchProcessor.getProcessName());
|
|
||||||
}
|
|
||||||
batchProcessor.processLong(batchProcessWorker, true);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOG.debug("Processing batch with name: " + batchProcessor.getProcessName() + " completed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
LOG.error("Error processing batch with name: " + batchProcessor.getProcessName(), exception);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
bulkStatusUpdater.update();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
executorService.submit(backgroundLogic);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get initial bulk status
|
|
||||||
*
|
|
||||||
* @param processId process id
|
|
||||||
* @param totalItems total items
|
|
||||||
* @return bulk status
|
|
||||||
*/
|
|
||||||
protected abstract T getInitBulkStatus(String processId, long totalItems);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get bulk status updater
|
|
||||||
*
|
|
||||||
* @return bulk status updater
|
|
||||||
*/
|
|
||||||
protected abstract BulkStatusUpdater getBulkStatusUpdater();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get work provider
|
|
||||||
*
|
|
||||||
* @param bulkOperation bulk operation
|
|
||||||
* @param bulkStatusUpdater bulk status updater
|
|
||||||
* @param bulkProgress bulk progress
|
|
||||||
* @return work provider
|
|
||||||
*/
|
|
||||||
protected abstract BatchProcessWorkProvider<NodeRef> getWorkProvider(BulkOperation bulkOperation,
|
|
||||||
BulkStatusUpdater bulkStatusUpdater, BulkProgress bulkProgress);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get worker provider
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param bulkOperation bulk operation
|
|
||||||
* @param bulkProgress bulk progress
|
|
||||||
* @return worker provider
|
|
||||||
*/
|
|
||||||
protected abstract BatchProcessWorker<NodeRef> getWorkerProvider(NodeRef nodeRef, BulkOperation bulkOperation,
|
|
||||||
BulkProgress bulkProgress);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check permissions
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param bulkOperation bulk operation
|
|
||||||
*/
|
|
||||||
protected abstract void checkPermissions(NodeRef nodeRef, BulkOperation bulkOperation);
|
|
||||||
|
|
||||||
protected ResultSet getTotalItems(Query searchQuery, int skipCount)
|
|
||||||
{
|
|
||||||
SearchParameters searchParams = new SearchParameters();
|
|
||||||
searchMapper.setDefaults(searchParams);
|
|
||||||
searchMapper.fromQuery(searchParams, searchQuery);
|
|
||||||
searchParams.setSkipCount(skipCount);
|
|
||||||
searchParams.setMaxItems(1);
|
|
||||||
searchParams.setLimit(1);
|
|
||||||
return searchService.query(searchParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
|
||||||
{
|
|
||||||
this.serviceRegistry = serviceRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSearchService(SearchService searchService)
|
|
||||||
{
|
|
||||||
this.searchService = searchService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionService(TransactionService transactionService)
|
|
||||||
{
|
|
||||||
this.transactionService = transactionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSearchMapper(SearchMapper searchMapper)
|
|
||||||
{
|
|
||||||
this.searchMapper = searchMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBulkMonitor(BulkMonitor<T> bulkMonitor)
|
|
||||||
{
|
|
||||||
this.bulkMonitor = bulkMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThreadCount(int threadCount)
|
|
||||||
{
|
|
||||||
this.threadCount = threadCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBatchSize(int batchSize)
|
|
||||||
{
|
|
||||||
this.batchSize = batchSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxItems(int maxItems)
|
|
||||||
{
|
|
||||||
this.maxItems = maxItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoggingInterval(int loggingInterval)
|
|
||||||
{
|
|
||||||
this.loggingInterval = loggingInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setItemsPerTransaction(int itemsPerTransaction)
|
|
||||||
{
|
|
||||||
this.itemsPerTransaction = itemsPerTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxParallelRequests(int maxParallelRequests)
|
|
||||||
{
|
|
||||||
this.maxParallelRequests = maxParallelRequests;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An immutable POJO to represent a bulk cancellation request
|
|
||||||
*/
|
|
||||||
public record BulkCancellationRequest(String reason)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for monitoring the progress of a bulk operation
|
|
||||||
*/
|
|
||||||
public interface BulkMonitor<T>
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Update the bulk status
|
|
||||||
*
|
|
||||||
* @param bulkStatus the bulk status
|
|
||||||
*/
|
|
||||||
void updateBulkStatus(T bulkStatus);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a process
|
|
||||||
*
|
|
||||||
* @param nodeRef the node reference
|
|
||||||
* @param processId the process id
|
|
||||||
* @param bulkOperation the bulk operation
|
|
||||||
*/
|
|
||||||
void registerProcess(NodeRef nodeRef, String processId, BulkOperation bulkOperation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bulk status
|
|
||||||
*
|
|
||||||
* @param bulkStatusId the bulk status id
|
|
||||||
* @return the bulk status
|
|
||||||
*/
|
|
||||||
T getBulkStatus(String bulkStatusId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel a bulk operation
|
|
||||||
*
|
|
||||||
* @param bulkStatusId
|
|
||||||
* @param bulkCancellationRequest
|
|
||||||
*/
|
|
||||||
void cancelBulkOperation(String bulkStatusId, BulkCancellationRequest bulkCancellationRequest);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a bulk operation is cancelled
|
|
||||||
*
|
|
||||||
* @param bulkStatusId
|
|
||||||
* @return true if the bulk operation is cancelled
|
|
||||||
*/
|
|
||||||
boolean isCancelled(String bulkStatusId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bulk cancellation request
|
|
||||||
*
|
|
||||||
* @param bulkStatusId
|
|
||||||
* @return cancellation reason
|
|
||||||
*/
|
|
||||||
BulkCancellationRequest getBulkCancellationRequest(String bulkStatusId);
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An immutable POJO to represent a bulk operation
|
|
||||||
*/
|
|
||||||
public record BulkOperation(Query searchQuery, String operationType) implements Serializable
|
|
||||||
{
|
|
||||||
public BulkOperation
|
|
||||||
{
|
|
||||||
if (operationType == null || searchQuery == null)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Operation type and search query must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An immutable POJO to represent the progress of a bulk operation
|
|
||||||
*/
|
|
||||||
public record BulkProgress(long totalItems, String processId, AtomicBoolean cancelled, AtomicInteger currentNodeNumber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for updating the status of a bulk operation
|
|
||||||
*/
|
|
||||||
public interface BulkStatusUpdater extends ApplicationEventPublisher
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Update the bulk status
|
|
||||||
*/
|
|
||||||
void update();
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.util.Pair;
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default hold bulk monitor implementation
|
|
||||||
*/
|
|
||||||
public class DefaultHoldBulkMonitor extends AbstractLifecycleBean implements HoldBulkMonitor
|
|
||||||
{
|
|
||||||
protected SimpleCache<String, HoldBulkStatus> holdProgressCache;
|
|
||||||
protected SimpleCache<String, BulkCancellationRequest> bulkCancellationsCache;
|
|
||||||
protected SimpleCache<Pair<String, String>, HoldBulkProcessDetails> holdProcessRegistry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBulkStatus(HoldBulkStatus holdBulkStatus)
|
|
||||||
{
|
|
||||||
holdProgressCache.put(holdBulkStatus.bulkStatusId(), holdBulkStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerProcess(NodeRef holdRef, String processId, BulkOperation bulkOperation)
|
|
||||||
{
|
|
||||||
if (holdRef != null && processId != null)
|
|
||||||
{
|
|
||||||
holdProcessRegistry.put(new Pair<>(holdRef.getId(), processId),
|
|
||||||
new HoldBulkProcessDetails(processId, getCurrentInstanceDetails(), bulkOperation));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HoldBulkStatus getBulkStatus(String bulkStatusId)
|
|
||||||
{
|
|
||||||
return holdProgressCache.get(bulkStatusId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelBulkOperation(String bulkStatusId, BulkCancellationRequest bulkCancellationRequest)
|
|
||||||
{
|
|
||||||
bulkCancellationsCache.put(bulkStatusId, bulkCancellationRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCancelled(String bulkStatusId)
|
|
||||||
{
|
|
||||||
return bulkCancellationsCache.contains(bulkStatusId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BulkCancellationRequest getBulkCancellationRequest(String bulkStatusId)
|
|
||||||
{
|
|
||||||
return bulkCancellationsCache.get(bulkStatusId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HoldBulkStatusAndProcessDetails> getBulkStatusesWithProcessDetails(String holdId)
|
|
||||||
{
|
|
||||||
return holdProcessRegistry.getKeys().stream()
|
|
||||||
.filter(holdIdAndBulkStatusId -> holdId.equals(holdIdAndBulkStatusId.getFirst()))
|
|
||||||
.map(holdIdAndBulkStatusId -> holdProcessRegistry.get(holdIdAndBulkStatusId))
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.map(createHoldBulkStatusAndProcessDetails())
|
|
||||||
.filter(statusAndProcess -> Objects.nonNull(statusAndProcess.holdBulkStatus()))
|
|
||||||
.sorted(sortBulkStatuses())
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HoldBulkStatusAndProcessDetails getBulkStatusWithProcessDetails(String holdId, String bulkStatusId)
|
|
||||||
{
|
|
||||||
return Optional.ofNullable(holdProcessRegistry.get(new Pair<>(holdId, bulkStatusId)))
|
|
||||||
.map(createHoldBulkStatusAndProcessDetails())
|
|
||||||
.filter(statusAndProcess -> Objects.nonNull(statusAndProcess.holdBulkStatus()))
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getCurrentInstanceDetails()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Function<HoldBulkProcessDetails, HoldBulkStatusAndProcessDetails> createHoldBulkStatusAndProcessDetails()
|
|
||||||
{
|
|
||||||
return bulkProcessDetails -> new HoldBulkStatusAndProcessDetails(
|
|
||||||
getBulkStatus(bulkProcessDetails.bulkStatusId()), bulkProcessDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static Comparator<HoldBulkStatusAndProcessDetails> sortBulkStatuses()
|
|
||||||
{
|
|
||||||
return Comparator.<HoldBulkStatusAndProcessDetails, Date>comparing(
|
|
||||||
statusAndProcess -> statusAndProcess.holdBulkStatus().endTime(),
|
|
||||||
Comparator.nullsLast(Comparator.naturalOrder()))
|
|
||||||
.thenComparing(statusAndProcess -> statusAndProcess.holdBulkStatus().startTime(),
|
|
||||||
Comparator.nullsLast(Comparator.naturalOrder()))
|
|
||||||
.reversed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldProgressCache(
|
|
||||||
SimpleCache<String, HoldBulkStatus> holdProgressCache)
|
|
||||||
{
|
|
||||||
this.holdProgressCache = holdProgressCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldProcessRegistry(
|
|
||||||
SimpleCache<Pair<String, String>, HoldBulkProcessDetails> holdProcessRegistry)
|
|
||||||
{
|
|
||||||
this.holdProcessRegistry = holdProcessRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBulkCancellationsCache(
|
|
||||||
SimpleCache<String, BulkCancellationRequest> bulkCancellationsCache)
|
|
||||||
{
|
|
||||||
this.bulkCancellationsCache = bulkCancellationsCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onBootstrap(ApplicationEvent applicationEvent)
|
|
||||||
{
|
|
||||||
// NOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onShutdown(ApplicationEvent applicationEvent)
|
|
||||||
{
|
|
||||||
// NOOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkMonitor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for monitoring the progress of a bulk hold operation
|
|
||||||
*/
|
|
||||||
public interface HoldBulkMonitor extends BulkMonitor<HoldBulkStatus>
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Get the bulk statuses with process details for a hold
|
|
||||||
*
|
|
||||||
* @param holdId the hold id
|
|
||||||
* @return the bulk statuses with process details
|
|
||||||
*/
|
|
||||||
List<HoldBulkStatusAndProcessDetails> getBulkStatusesWithProcessDetails(String holdId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bulk status with process details
|
|
||||||
*
|
|
||||||
* @param holdId the hold id
|
|
||||||
* @param bulkStatusId the bulk status id
|
|
||||||
* @return the bulk status with process details
|
|
||||||
*/
|
|
||||||
HoldBulkStatusAndProcessDetails getBulkStatusWithProcessDetails(String holdId, String bulkStatusId);
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple immutable POJO to hold the details of a bulk process
|
|
||||||
*/
|
|
||||||
public record HoldBulkProcessDetails(String bulkStatusId, String creatorInstance, BulkOperation bulkOperation) implements Serializable
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface defining a hold bulk service.
|
|
||||||
*/
|
|
||||||
public interface HoldBulkService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Initiates a bulk operation on a hold.
|
|
||||||
*
|
|
||||||
* @param holdRef The hold reference
|
|
||||||
* @param bulkOperation The bulk operation
|
|
||||||
* @return The initial status of the bulk operation
|
|
||||||
*/
|
|
||||||
HoldBulkStatus execute(NodeRef holdRef, BulkOperation bulkOperation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels a bulk operation.
|
|
||||||
*
|
|
||||||
* @param holdRef The hold reference
|
|
||||||
* @param bulkStatusId The bulk status id
|
|
||||||
* @param bulkCancellationRequest The bulk cancellation request
|
|
||||||
*/
|
|
||||||
void cancelBulkOperation(NodeRef holdRef, String bulkStatusId, BulkCancellationRequest bulkCancellationRequest);
|
|
||||||
}
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import static org.alfresco.model.ContentModel.PROP_NAME;
|
|
||||||
import static org.alfresco.rm.rest.api.model.HoldBulkOperationType.ADD;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkBaseService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkProgress;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkStatusUpdater;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
|
||||||
import org.alfresco.repo.batch.BatchProcessWorkProvider;
|
|
||||||
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkOperationType;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
|
||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.extensions.surf.util.I18NUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of the {@link HoldBulkService} interface.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("PMD.PreserveStackTrace")
|
|
||||||
public class HoldBulkServiceImpl extends BulkBaseService<HoldBulkStatus> implements HoldBulkService
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HoldBulkServiceImpl.class);
|
|
||||||
private static final String MSG_ERR_ACCESS_DENIED = "permissions.err_access_denied";
|
|
||||||
|
|
||||||
private HoldService holdService;
|
|
||||||
private CapabilityService capabilityService;
|
|
||||||
private PermissionService permissionService;
|
|
||||||
private NodeService nodeService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HoldBulkStatus getInitBulkStatus(String processId, long totalItems)
|
|
||||||
{
|
|
||||||
return new HoldBulkStatus(processId, null, null, 0, 0, totalItems, null, false, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BulkStatusUpdater getBulkStatusUpdater()
|
|
||||||
{
|
|
||||||
return new HoldBulkStatusUpdater((HoldBulkMonitor) bulkMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BatchProcessWorkProvider<NodeRef> getWorkProvider(BulkOperation bulkOperation,
|
|
||||||
BulkStatusUpdater bulkStatusUpdater, BulkProgress bulkProgress)
|
|
||||||
{
|
|
||||||
return new AddToHoldWorkerProvider(bulkOperation, bulkStatusUpdater, bulkProgress,
|
|
||||||
(HoldBulkMonitor) bulkMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BatchProcessWorker<NodeRef> getWorkerProvider(NodeRef nodeRef, BulkOperation bulkOperation,
|
|
||||||
BulkProgress bulkProgress)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HoldBulkOperationType holdBulkOperationType = HoldBulkOperationType.valueOf(bulkOperation.operationType()
|
|
||||||
.toUpperCase(Locale.ENGLISH));
|
|
||||||
return switch (holdBulkOperationType)
|
|
||||||
{
|
|
||||||
case ADD -> new AddToHoldWorkerBatch(nodeRef, bulkProgress);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
String errorMsg = "Unsupported action type when starting the bulk process: ";
|
|
||||||
if (LOGGER.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOGGER.debug("{} {}", errorMsg, bulkOperation.operationType(), e);
|
|
||||||
}
|
|
||||||
throw new InvalidArgumentException(errorMsg + bulkOperation.operationType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void checkPermissions(NodeRef holdRef, BulkOperation bulkOperation)
|
|
||||||
{
|
|
||||||
if (!holdService.isHold(holdRef))
|
|
||||||
{
|
|
||||||
final String holdName = (String) nodeService.getProperty(holdRef, PROP_NAME);
|
|
||||||
throw new InvalidArgumentException(I18NUtil.getMessage("rm.hold.not-hold", holdName), null);
|
|
||||||
}
|
|
||||||
if (ADD.name().equals(bulkOperation.operationType()) && (!AccessStatus.ALLOWED.equals(
|
|
||||||
capabilityService.getCapabilityAccessState(holdRef, RMPermissionModel.ADD_TO_HOLD)) ||
|
|
||||||
permissionService.hasPermission(holdRef, RMPermissionModel.FILING) == AccessStatus.DENIED))
|
|
||||||
{
|
|
||||||
throw new AccessDeniedException(I18NUtil.getMessage(MSG_ERR_ACCESS_DENIED));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelBulkOperation(NodeRef holdRef, String bulkStatusId, BulkCancellationRequest cancellationRequest)
|
|
||||||
{
|
|
||||||
if (bulkMonitor instanceof HoldBulkMonitor holdBulkMonitor)
|
|
||||||
{
|
|
||||||
HoldBulkStatusAndProcessDetails statusAndProcessDetails = holdBulkMonitor.getBulkStatusWithProcessDetails(
|
|
||||||
holdRef.getId(), bulkStatusId);
|
|
||||||
|
|
||||||
Optional.ofNullable(statusAndProcessDetails).map(HoldBulkStatusAndProcessDetails::holdBulkProcessDetails)
|
|
||||||
.map(HoldBulkProcessDetails::bulkOperation).ifPresent(bulkOperation -> {
|
|
||||||
checkPermissions(holdRef, bulkOperation);
|
|
||||||
holdBulkMonitor.cancelBulkOperation(bulkStatusId, cancellationRequest);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AddToHoldWorkerBatch implements BatchProcessWorker<NodeRef>
|
|
||||||
{
|
|
||||||
private final NodeRef holdRef;
|
|
||||||
private final String currentUser;
|
|
||||||
private final BulkProgress bulkProgress;
|
|
||||||
|
|
||||||
public AddToHoldWorkerBatch(NodeRef holdRef, BulkProgress bulkProgress)
|
|
||||||
{
|
|
||||||
this.holdRef = holdRef;
|
|
||||||
this.bulkProgress = bulkProgress;
|
|
||||||
currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier(NodeRef entry)
|
|
||||||
{
|
|
||||||
return entry.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeProcess()
|
|
||||||
{
|
|
||||||
AuthenticationUtil.pushAuthentication();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void process(NodeRef entry) throws Throwable
|
|
||||||
{
|
|
||||||
if (!bulkProgress.cancelled().get())
|
|
||||||
{
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(currentUser);
|
|
||||||
holdService.addToHold(holdRef, entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterProcess()
|
|
||||||
{
|
|
||||||
AuthenticationUtil.popAuthentication();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AddToHoldWorkerProvider implements BatchProcessWorkProvider<NodeRef>
|
|
||||||
{
|
|
||||||
private final HoldBulkMonitor holdBulkMonitor;
|
|
||||||
private final Query searchQuery;
|
|
||||||
private final String currentUser;
|
|
||||||
private final BulkProgress bulkProgress;
|
|
||||||
private final BulkStatusUpdater bulkStatusUpdater;
|
|
||||||
|
|
||||||
public AddToHoldWorkerProvider(BulkOperation bulkOperation,
|
|
||||||
BulkStatusUpdater bulkStatusUpdater, BulkProgress bulkProgress, HoldBulkMonitor holdBulkMonitor)
|
|
||||||
{
|
|
||||||
this.searchQuery = bulkOperation.searchQuery();
|
|
||||||
this.bulkProgress = bulkProgress;
|
|
||||||
this.bulkStatusUpdater = bulkStatusUpdater;
|
|
||||||
this.holdBulkMonitor = holdBulkMonitor;
|
|
||||||
currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTotalEstimatedWorkSize()
|
|
||||||
{
|
|
||||||
return (int) bulkProgress.totalItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalEstimatedWorkSizeLong()
|
|
||||||
{
|
|
||||||
return bulkProgress.totalItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<NodeRef> getNextWork()
|
|
||||||
{
|
|
||||||
AuthenticationUtil.pushAuthentication();
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(currentUser);
|
|
||||||
if (holdBulkMonitor.isCancelled(bulkProgress.processId()))
|
|
||||||
{
|
|
||||||
bulkProgress.cancelled().set(true);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
SearchParameters searchParams = getNextPageParameters();
|
|
||||||
ResultSet result = searchService.query(searchParams);
|
|
||||||
if (result.getNodeRefs().isEmpty())
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
AuthenticationUtil.popAuthentication();
|
|
||||||
if (LOGGER.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOGGER.debug("Processing the next work for the batch processor, skipCount={}, size={}",
|
|
||||||
searchParams.getSkipCount(), result.getNumberFound());
|
|
||||||
}
|
|
||||||
bulkProgress.currentNodeNumber().addAndGet(batchSize);
|
|
||||||
bulkStatusUpdater.update();
|
|
||||||
return result.getNodeRefs();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SearchParameters getNextPageParameters()
|
|
||||||
{
|
|
||||||
SearchParameters searchParams = new SearchParameters();
|
|
||||||
searchMapper.setDefaults(searchParams);
|
|
||||||
searchMapper.fromQuery(searchParams, searchQuery);
|
|
||||||
searchParams.setSkipCount(bulkProgress.currentNodeNumber().get());
|
|
||||||
searchParams.setMaxItems(batchSize);
|
|
||||||
searchParams.setLimit(batchSize);
|
|
||||||
searchParams.addSort("@" + ContentModel.PROP_CREATED, true);
|
|
||||||
return searchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldService(HoldService holdService)
|
|
||||||
{
|
|
||||||
this.holdService = holdService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCapabilityService(CapabilityService capabilityService)
|
|
||||||
{
|
|
||||||
this.capabilityService = capabilityService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPermissionService(PermissionService permissionService)
|
|
||||||
{
|
|
||||||
this.permissionService = permissionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNodeService(NodeService nodeService)
|
|
||||||
{
|
|
||||||
this.nodeService = nodeService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An immutable POJO that contains the status of a hold bulk operation
|
|
||||||
*/
|
|
||||||
public record HoldBulkStatus(String bulkStatusId, Date startTime, Date endTime, long processedItems, long errorsCount,
|
|
||||||
long totalItems, String lastError, boolean isCancelled, String cancellationReason)
|
|
||||||
implements Serializable
|
|
||||||
{
|
|
||||||
public enum Status
|
|
||||||
{
|
|
||||||
PENDING("PENDING"),
|
|
||||||
IN_PROGRESS("IN PROGRESS"),
|
|
||||||
DONE("DONE"),
|
|
||||||
CANCELLED("CANCELLED");
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
Status(String value)
|
|
||||||
{
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue()
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus()
|
|
||||||
{
|
|
||||||
if (isCancelled)
|
|
||||||
{
|
|
||||||
return Status.CANCELLED.getValue();
|
|
||||||
}
|
|
||||||
else if (startTime == null && endTime == null)
|
|
||||||
{
|
|
||||||
return Status.PENDING.getValue();
|
|
||||||
}
|
|
||||||
else if (startTime != null && endTime == null)
|
|
||||||
{
|
|
||||||
return Status.IN_PROGRESS.getValue();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Status.DONE.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An immutable POJO that contains the status of a hold bulk operation and the details of the process
|
|
||||||
*/
|
|
||||||
public record HoldBulkStatusAndProcessDetails(HoldBulkStatus holdBulkStatus,
|
|
||||||
HoldBulkProcessDetails holdBulkProcessDetails)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkStatusUpdater;
|
|
||||||
import org.alfresco.repo.batch.BatchMonitor;
|
|
||||||
import org.alfresco.repo.batch.BatchMonitorEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation of {@link BulkStatusUpdater} for the hold bulk operation
|
|
||||||
*/
|
|
||||||
public class HoldBulkStatusUpdater implements BulkStatusUpdater
|
|
||||||
{
|
|
||||||
private final Runnable task;
|
|
||||||
private BatchMonitor batchMonitor;
|
|
||||||
|
|
||||||
public HoldBulkStatusUpdater(HoldBulkMonitor holdBulkMonitor)
|
|
||||||
{
|
|
||||||
this.task = () -> holdBulkMonitor.updateBulkStatus(
|
|
||||||
new HoldBulkStatus(batchMonitor.getProcessName(),
|
|
||||||
batchMonitor.getStartTime(),
|
|
||||||
batchMonitor.getEndTime(),
|
|
||||||
batchMonitor.getSuccessfullyProcessedEntriesLong() + batchMonitor.getTotalErrorsLong(),
|
|
||||||
batchMonitor.getTotalErrorsLong(),
|
|
||||||
batchMonitor.getTotalResultsLong(),
|
|
||||||
batchMonitor.getLastError(),
|
|
||||||
holdBulkMonitor.isCancelled(batchMonitor.getProcessName()),
|
|
||||||
Optional.ofNullable(holdBulkMonitor.getBulkCancellationRequest(batchMonitor.getProcessName()))
|
|
||||||
.map(BulkCancellationRequest::reason)
|
|
||||||
.orElse(null)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
if (task != null && batchMonitor != null)
|
|
||||||
{
|
|
||||||
task.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void publishEvent(Object event)
|
|
||||||
{
|
|
||||||
if (event instanceof BatchMonitorEvent batchMonitorEvent)
|
|
||||||
{
|
|
||||||
batchMonitor = batchMonitorEvent.getBatchMonitor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkOperation;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkOperationType;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkStatusEntry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class for hold bulk operations
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("PMD.PreserveStackTrace")
|
|
||||||
public final class HoldBulkUtils
|
|
||||||
{
|
|
||||||
private HoldBulkUtils()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HoldBulkStatusEntry toHoldBulkStatusEntry(
|
|
||||||
HoldBulkStatusAndProcessDetails holdBulkStatusAndProcessDetails)
|
|
||||||
{
|
|
||||||
HoldBulkStatus bulkStatus = holdBulkStatusAndProcessDetails.holdBulkStatus();
|
|
||||||
BulkOperation bulkOperation = holdBulkStatusAndProcessDetails.holdBulkProcessDetails().bulkOperation();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HoldBulkOperation holdBulkOperation = new HoldBulkOperation(
|
|
||||||
new Query(bulkOperation.searchQuery().getLanguage(),
|
|
||||||
bulkOperation.searchQuery().getQuery(), bulkOperation.searchQuery().getUserQuery()),
|
|
||||||
HoldBulkOperationType.valueOf(bulkOperation.operationType()));
|
|
||||||
return new HoldBulkStatusEntry(bulkStatus.bulkStatusId(), bulkStatus.startTime(),
|
|
||||||
bulkStatus.endTime(), bulkStatus.processedItems(), bulkStatus.errorsCount(),
|
|
||||||
bulkStatus.totalItems(), bulkStatus.lastError(), bulkStatus.getStatus(),
|
|
||||||
bulkStatus.cancellationReason(), holdBulkOperation);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
String errorMsg = "Unsupported action type in the bulk operation: ";
|
|
||||||
throw new InvalidArgumentException(errorMsg + bulkOperation.operationType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -31,6 +31,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.DeclarativeCapability;
|
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.DeclarativeCapability;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||||
@@ -75,7 +76,7 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
@Override
|
@Override
|
||||||
public int evaluate(NodeRef nodeRef)
|
public int evaluate(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
return evaluate(nodeRef, null, null, null);
|
return evaluate(nodeRef, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,10 +85,9 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
* @param destination destination node reference
|
* @param destination destination node reference
|
||||||
* @param linkee linkee node reference, can be null
|
* @param linkee linkee node reference, can be null
|
||||||
* @param assocType association type, can be null
|
* @param assocType association type, can be null
|
||||||
* @param recordType record type, can be null
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int evaluate(NodeRef destination, NodeRef linkee, QName assocType, QName recordType)
|
public int evaluate(NodeRef destination, NodeRef linkee, QName assocType)
|
||||||
{
|
{
|
||||||
if (linkee != null)
|
if (linkee != null)
|
||||||
{
|
{
|
||||||
@@ -105,7 +105,7 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
{
|
{
|
||||||
if (recordService.isRecord(destination) &&
|
if (recordService.isRecord(destination) &&
|
||||||
!recordService.isDeclared(destination) &&
|
!recordService.isDeclared(destination) &&
|
||||||
permissionService.hasPermission(destination, FILE_RECORDS) == AccessStatus.ALLOWED)
|
permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
if (recordService.isRecord(linkee) &&
|
if (recordService.isRecord(linkee) &&
|
||||||
recordService.isRecord(destination) &&
|
recordService.isRecord(destination) &&
|
||||||
!recordService.isDeclared(destination) &&
|
!recordService.isDeclared(destination) &&
|
||||||
permissionService.hasPermission(destination, FILE_RECORDS) == AccessStatus.ALLOWED)
|
permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -132,15 +132,14 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
|
|
||||||
// if the destination folder is not a record folder and the user has filling capability on it, grant access to create the record
|
// if the destination folder is not a record folder and the user has filling capability on it, grant access to create the record
|
||||||
if (checkConditions(destination, conditions) &&
|
if (checkConditions(destination, conditions) &&
|
||||||
!recordFolderService.isRecordFolder(destination) &&
|
!recordFolderService.isRecordFolder(destination) )
|
||||||
permissionService.hasPermission(destination, CREATE_MODIFY_DESTROY_FILEPLAN_METADATA) == AccessStatus.ALLOWED)
|
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkConditions(destination, conditions) &&
|
if (checkConditions(destination, conditions) &&
|
||||||
recordFolderService.isRecordFolder(destination) &&
|
recordFolderService.isRecordFolder(destination) &&
|
||||||
permissionService.hasPermission(destination, FILE_RECORDS) == AccessStatus.ALLOWED)
|
permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -148,7 +147,7 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
conditions.put("capabilityCondition.closed", Boolean.TRUE);
|
conditions.put("capabilityCondition.closed", Boolean.TRUE);
|
||||||
if (checkConditions(destination, conditions) &&
|
if (checkConditions(destination, conditions) &&
|
||||||
recordFolderService.isRecordFolder(destination) &&
|
recordFolderService.isRecordFolder(destination) &&
|
||||||
permissionService.hasPermission(getFilePlanService().getFilePlan(destination), DECLARE_RECORDS_IN_CLOSED_FOLDERS) == AccessStatus.ALLOWED)
|
permissionService.hasPermission(getFilePlanService().getFilePlan(destination), RMPermissionModel.DECLARE_RECORDS_IN_CLOSED_FOLDERS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -157,32 +156,32 @@ public class CreateCapability extends DeclarativeCapability
|
|||||||
conditions.put("capabilityCondition.cutoff", Boolean.TRUE);
|
conditions.put("capabilityCondition.cutoff", Boolean.TRUE);
|
||||||
if (checkConditions(destination, conditions) &&
|
if (checkConditions(destination, conditions) &&
|
||||||
recordFolderService.isRecordFolder(destination) &&
|
recordFolderService.isRecordFolder(destination) &&
|
||||||
permissionService.hasPermission(getFilePlanService().getFilePlan(destination), CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS) == AccessStatus.ALLOWED)
|
permissionService.hasPermission(getFilePlanService().getFilePlan(destination), RMPermissionModel.CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null != recordType && recordType.equals(TYPE_RECORD_FOLDER) && capabilityService.getCapability(CREATE_MODIFY_DESTROY_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (capabilityService.getCapability(RMPermissionModel.CREATE_MODIFY_DESTROY_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
if (capabilityService.getCapability(DECLARE_RECORDS_IN_CLOSED_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (capabilityService.getCapability(RMPermissionModel.DECLARE_RECORDS_IN_CLOSED_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
if (capabilityService.getCapability(CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (capabilityService.getCapability(RMPermissionModel.CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
if (capabilityService.getCapability(CREATE_MODIFY_DESTROY_FILEPLAN_METADATA).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (capabilityService.getCapability(RMPermissionModel.CREATE_MODIFY_DESTROY_FILEPLAN_METADATA).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
if (capabilityService.getCapability(CREATE_HOLD).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (capabilityService.getCapability(RMPermissionModel.CREATE_HOLD).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
if (((ChangeOrDeleteReferencesCapability)capabilityService.getCapability(CHANGE_OR_DELETE_REFERENCES)).evaluate(destination, linkee) == AccessDecisionVoter.ACCESS_GRANTED)
|
if (((ChangeOrDeleteReferencesCapability)capabilityService.getCapability(RMPermissionModel.CHANGE_OR_DELETE_REFERENCES)).evaluate(destination, linkee) == AccessDecisionVoter.ACCESS_GRANTED)
|
||||||
{
|
{
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
package org.alfresco.module.org_alfresco_module_rm.capability.policy;
|
package org.alfresco.module.org_alfresco_module_rm.capability.policy;
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability;
|
import org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
@@ -43,18 +42,10 @@ public class CreatePolicy extends AbstractBasePolicy
|
|||||||
{
|
{
|
||||||
NodeRef linkee = null;
|
NodeRef linkee = null;
|
||||||
QName assocType = null;
|
QName assocType = null;
|
||||||
QName recordType = null;
|
|
||||||
|
|
||||||
// get the destination node
|
// get the destination node
|
||||||
NodeRef destination = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent());
|
NodeRef destination = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent());
|
||||||
|
|
||||||
//get the recordType
|
|
||||||
for (Object qname : invocation.getArguments()) {
|
|
||||||
if (qname != null && (qname.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) || qname.equals(RecordsManagementModel.TYPE_RECORD_CATEGORY))) {
|
|
||||||
recordType = (QName) qname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cad.getParameters().size() > 1)
|
if (cad.getParameters().size() > 1)
|
||||||
{
|
{
|
||||||
// get the linkee when present
|
// get the linkee when present
|
||||||
@@ -67,7 +58,7 @@ public class CreatePolicy extends AbstractBasePolicy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((CreateCapability) getCapabilityService().getCapability("Create")).evaluate(destination, linkee, assocType, recordType);
|
return ((CreateCapability) getCapabilityService().getCapability("Create")).evaluate(destination, linkee, assocType);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,6 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
@@ -201,7 +198,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
/**
|
/**
|
||||||
* Behavior to initialize the disposition schedule of a newly filed record.
|
* Behavior to initialize the disposition schedule of a newly filed record.
|
||||||
*
|
*
|
||||||
* @see RecordsManagementPolicies.OnFileRecord#onFileRecord(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnFileRecord#onFileRecord(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Behaviour(kind=BehaviourKind.CLASS, type="rma:record")
|
@Behaviour(kind=BehaviourKind.CLASS, type="rma:record")
|
||||||
@@ -219,7 +216,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#refreshDispositionAction(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#refreshDispositionAction(NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void refreshDispositionAction(NodeRef nodeRef)
|
public void refreshDispositionAction(NodeRef nodeRef)
|
||||||
@@ -245,7 +242,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
/** ========= Disposition Property Methods ========= */
|
/** ========= Disposition Property Methods ========= */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#registerDispositionProperty(DispositionProperty)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#registerDispositionProperty(org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void registerDispositionProperty(DispositionProperty dispositionProperty)
|
public void registerDispositionProperty(DispositionProperty dispositionProperty)
|
||||||
@@ -254,7 +251,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getDispositionProperties(boolean, String)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties(boolean, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<DispositionProperty> getDispositionProperties(boolean isRecordLevel, String dispositionAction)
|
public Collection<DispositionProperty> getDispositionProperties(boolean isRecordLevel, String dispositionAction)
|
||||||
@@ -273,7 +270,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getDispositionProperties()
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<DispositionProperty> getDispositionProperties()
|
public Collection<DispositionProperty> getDispositionProperties()
|
||||||
@@ -284,11 +281,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
/** ========= Disposition Schedule Methods ========= */
|
/** ========= Disposition Schedule Methods ========= */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getDispositionSchedule(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DispositionSchedule getDispositionSchedule(final NodeRef nodeRef)
|
public DispositionSchedule getDispositionSchedule(final NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
DispositionSchedule ds = null;
|
||||||
NodeRef dsNodeRef = null;
|
NodeRef dsNodeRef = null;
|
||||||
if (isRecord(nodeRef))
|
if (isRecord(nodeRef))
|
||||||
{
|
{
|
||||||
@@ -313,33 +311,36 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
if (dsNextAction != null)
|
if (dsNextAction != null)
|
||||||
{
|
{
|
||||||
final NodeRef action = dsNextAction.getNextActionNodeRef();
|
final NodeRef action = dsNextAction.getNextActionNodeRef();
|
||||||
if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF)) && !dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY))
|
if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF)))
|
||||||
{
|
{
|
||||||
final String dispositionActionName = dsNextAction.getNextActionName();
|
if (!dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY))
|
||||||
final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf();
|
|
||||||
|
|
||||||
RunAsWork<Void> runAsWork = () -> {
|
|
||||||
nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate);
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// if the current transaction is READ ONLY set the property on the node
|
|
||||||
// in a READ WRITE transaction
|
|
||||||
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
|
|
||||||
{
|
{
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback<Void>) () -> {
|
final String dispositionActionName = dsNextAction.getNextActionName();
|
||||||
AuthenticationUtil.runAsSystem(runAsWork);
|
final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf();
|
||||||
|
|
||||||
|
RunAsWork<Void> runAsWork = () -> {
|
||||||
|
nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate);
|
||||||
return null;
|
return null;
|
||||||
}, false, true);
|
};
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuthenticationUtil.runAsSystem(runAsWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME))
|
// if the current transaction is READ ONLY set the property on the node
|
||||||
{
|
// in a READ WRITE transaction
|
||||||
nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName);
|
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
|
||||||
|
{
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback<Void>) () -> {
|
||||||
|
AuthenticationUtil.runAsSystem(runAsWork);
|
||||||
|
return null;
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AuthenticationUtil.runAsSystem(runAsWork);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME))
|
||||||
|
{
|
||||||
|
nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +352,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
// Get the disposition instructions for the node reference provided
|
// Get the disposition instructions for the node reference provided
|
||||||
dsNodeRef = getDispositionScheduleImpl(nodeRef);
|
dsNodeRef = getDispositionScheduleImpl(nodeRef);
|
||||||
}
|
}
|
||||||
DispositionSchedule ds = null;
|
|
||||||
if (dsNodeRef != null)
|
if (dsNodeRef != null)
|
||||||
{
|
{
|
||||||
ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dsNodeRef);
|
ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dsNodeRef);
|
||||||
@@ -381,8 +382,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DispositionSchedule getOriginDispositionSchedule(NodeRef nodeRef)
|
public DispositionSchedule getOriginDispositionSchedule(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
NodeRef parent = this.nodeService.getPrimaryParent(nodeRef).getParentRef();
|
NodeRef parent = this.nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||||
@@ -406,7 +406,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getAssociatedDispositionSchedule(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DispositionSchedule getAssociatedDispositionSchedule(NodeRef nodeRef)
|
public DispositionSchedule getAssociatedDispositionSchedule(NodeRef nodeRef)
|
||||||
@@ -437,6 +437,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
*/
|
*/
|
||||||
private NodeRef getAssociatedDispositionScheduleImpl(NodeRef nodeRef)
|
private NodeRef getAssociatedDispositionScheduleImpl(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
NodeRef result = null;
|
||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
|
||||||
// Make sure we are dealing with an RM node
|
// Make sure we are dealing with an RM node
|
||||||
@@ -444,7 +445,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Can not find the associated retention schedule for a non records management component. (nodeRef=" + nodeRef.toString() + ")");
|
throw new AlfrescoRuntimeException("Can not find the associated retention schedule for a non records management component. (nodeRef=" + nodeRef.toString() + ")");
|
||||||
}
|
}
|
||||||
NodeRef result = null;
|
|
||||||
if (getInternalNodeService().hasAspect(nodeRef, ASPECT_SCHEDULED))
|
if (getInternalNodeService().hasAspect(nodeRef, ASPECT_SCHEDULED))
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ASSOC_DISPOSITION_SCHEDULE, RegexQNamePattern.MATCH_ALL);
|
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ASSOC_DISPOSITION_SCHEDULE, RegexQNamePattern.MATCH_ALL);
|
||||||
@@ -459,7 +459,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getAssociatedRecordsManagementContainer(DispositionSchedule)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedRecordsManagementContainer(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public NodeRef getAssociatedRecordsManagementContainer(DispositionSchedule dispositionSchedule)
|
public NodeRef getAssociatedRecordsManagementContainer(DispositionSchedule dispositionSchedule)
|
||||||
@@ -477,9 +477,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
// TODO in the future we should be able to support disposition schedule reuse, but for now just warn that
|
// TODO in the future we should be able to support disposition schedule reuse, but for now just warn that
|
||||||
// only the first disposition schedule will be considered
|
// only the first disposition schedule will be considered
|
||||||
LOGGER.atWarn().log("Retention schedule has more than one associated records management container. " +
|
if (LOGGER.isWarnEnabled())
|
||||||
"This is not currently supported so only the first container will be considered. " +
|
{
|
||||||
"(dispositionScheduleNodeRef={})", dispositionSchedule.getNodeRef());
|
LOGGER.warn("Retention schedule has more than one associated records management container. " +
|
||||||
|
"This is not currently supported so only the first container will be considered. " +
|
||||||
|
"(dispositionScheduleNodeRef=" + dispositionSchedule.getNodeRef().toString() + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the container reference
|
// Get the container reference
|
||||||
@@ -492,7 +495,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#hasDisposableItems(DispositionSchedule)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#hasDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDisposableItems(DispositionSchedule dispositionSchdule)
|
public boolean hasDisposableItems(DispositionSchedule dispositionSchdule)
|
||||||
@@ -534,16 +537,19 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null && hasDisposableItemsImpl(isRecordLevelDisposition, item))
|
else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null)
|
||||||
{
|
{
|
||||||
return true;
|
if (hasDisposableItemsImpl(isRecordLevelDisposition, item));
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getDisposableItems(DispositionSchedule)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<NodeRef> getDisposableItems(DispositionSchedule dispositionSchedule)
|
public List<NodeRef> getDisposableItems(DispositionSchedule dispositionSchedule)
|
||||||
@@ -558,7 +564,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#isDisposableItem(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItem(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isDisposableItem(NodeRef nodeRef)
|
public boolean isDisposableItem(NodeRef nodeRef)
|
||||||
@@ -598,18 +604,20 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#createDispositionSchedule(NodeRef, Map)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#createDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef, java.util.Map)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DispositionSchedule createDispositionSchedule(NodeRef nodeRef, Map<QName, Serializable> props)
|
public DispositionSchedule createDispositionSchedule(NodeRef nodeRef, Map<QName, Serializable> props)
|
||||||
{
|
{
|
||||||
|
NodeRef dsNodeRef = null;
|
||||||
|
|
||||||
// Check mandatory parameters
|
// Check mandatory parameters
|
||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
|
||||||
// Check exists
|
// Check exists
|
||||||
if (!nodeService.exists(nodeRef))
|
if (!nodeService.exists(nodeRef))
|
||||||
{
|
{
|
||||||
throw new EntityNotFoundException(nodeRef.getId());
|
throw new AlfrescoRuntimeException("Unable to create retention schedule, because node does not exist. (nodeRef=" + nodeRef.toString() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check is sub-type of rm:recordCategory
|
// Check is sub-type of rm:recordCategory
|
||||||
@@ -617,12 +625,10 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
if (!TYPE_RECORD_CATEGORY.equals(nodeRefType) &&
|
if (!TYPE_RECORD_CATEGORY.equals(nodeRefType) &&
|
||||||
!dictionaryService.isSubClass(nodeRefType, TYPE_RECORD_CATEGORY))
|
!dictionaryService.isSubClass(nodeRefType, TYPE_RECORD_CATEGORY))
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException("The given id:'" + nodeRef.getId() + "' (nodeType:" + nodeRef
|
throw new AlfrescoRuntimeException("Unable to create retention schedule on a node that is not a records management container.");
|
||||||
+ ") is not valid. Expected nodeType is:" + TYPE_RECORD_CATEGORY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
behaviourFilter.disableBehaviour(nodeRef, ASPECT_SCHEDULED);
|
behaviourFilter.disableBehaviour(nodeRef, ASPECT_SCHEDULED);
|
||||||
NodeRef dsNodeRef = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Add the schedules aspect if required
|
// Add the schedules aspect if required
|
||||||
@@ -656,7 +662,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Error since the node already has a disposition schedule set
|
// Error since the node already has a disposition schedule set
|
||||||
throw new ConstraintViolatedException("Unable to create retention schedule on node that already has a retention schedule.");
|
throw new AlfrescoRuntimeException("Unable to create retention schedule on node that already has a retention schedule.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -680,7 +686,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
// make sure at least a name has been defined
|
// make sure at least a name has been defined
|
||||||
String name = (String)actionDefinitionParams.get(PROP_DISPOSITION_ACTION_NAME);
|
String name = (String)actionDefinitionParams.get(PROP_DISPOSITION_ACTION_NAME);
|
||||||
if (name == null || name.isEmpty())
|
if (name == null || name.length() == 0)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition");
|
throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition");
|
||||||
}
|
}
|
||||||
@@ -689,10 +695,10 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
|
|
||||||
// create the child association from the schedule to the action definition
|
// create the child association from the schedule to the action definition
|
||||||
NodeRef actionNodeRef = this.nodeService.createNode(schedule.getNodeRef(),
|
NodeRef actionNodeRef = this.nodeService.createNode(schedule.getNodeRef(),
|
||||||
ASSOC_DISPOSITION_ACTION_DEFINITIONS,
|
RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
|
||||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||||
QName.createValidLocalName(name)),
|
QName.createValidLocalName(name)),
|
||||||
TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
|
RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
|
||||||
|
|
||||||
// get the updated disposition schedule and retrieve the new action definition
|
// get the updated disposition schedule and retrieve the new action definition
|
||||||
NodeRef scheduleParent = this.nodeService.getPrimaryParent(schedule.getNodeRef()).getParentRef();
|
NodeRef scheduleParent = this.nodeService.getPrimaryParent(schedule.getNodeRef()).getParentRef();
|
||||||
@@ -701,7 +707,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#removeDispositionActionDefinition(DispositionSchedule, DispositionActionDefinition)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#removeDispositionActionDefinition(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule, org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeDispositionActionDefinition(DispositionSchedule schedule, DispositionActionDefinition actionDefinition)
|
public void removeDispositionActionDefinition(DispositionSchedule schedule, DispositionActionDefinition actionDefinition)
|
||||||
@@ -771,12 +777,16 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
|
|
||||||
DispositionAction da;
|
DispositionAction da;
|
||||||
// check if current transaction is a READ ONLY one and if true create the node in a READ WRITE transaction
|
// check if current transaction is a READ ONLY one and if true create the node in a READ WRITE transaction
|
||||||
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) {
|
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
|
||||||
da = transactionService.getRetryingTransactionHelper().doInTransaction(
|
{
|
||||||
() -> createDispositionAction(nodeRef, props),
|
da =
|
||||||
false,
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<DispositionAction>()
|
||||||
true
|
{
|
||||||
);
|
public DispositionAction execute() throws Throwable
|
||||||
|
{
|
||||||
|
return createDispositionAction(nodeRef, props);
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -826,13 +836,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
Period period = dispositionActionDefinition.getPeriod();
|
Period period = dispositionActionDefinition.getPeriod();
|
||||||
if (period != null)
|
if (period != null)
|
||||||
{
|
{
|
||||||
Date contextDate;
|
Date contextDate = null;
|
||||||
|
|
||||||
// Get the period properties value
|
// Get the period properties value
|
||||||
QName periodProperty = dispositionActionDefinition.getPeriodProperty();
|
QName periodProperty = dispositionActionDefinition.getPeriodProperty();
|
||||||
if (periodProperty != null)
|
if (periodProperty != null)
|
||||||
{
|
{
|
||||||
if (PROP_DISPOSITION_AS_OF.equals(periodProperty))
|
if (RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty))
|
||||||
{
|
{
|
||||||
DispositionAction lastCompletedDispositionAction = getLastCompletedDispostionAction(nodeRef);
|
DispositionAction lastCompletedDispositionAction = getLastCompletedDispostionAction(nodeRef);
|
||||||
if (lastCompletedDispositionAction != null)
|
if (lastCompletedDispositionAction != null)
|
||||||
@@ -876,7 +886,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#isNextDispositionActionEligible(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isNextDispositionActionEligible(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isNextDispositionActionEligible(NodeRef nodeRef)
|
public boolean isNextDispositionActionEligible(NodeRef nodeRef)
|
||||||
@@ -930,7 +940,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
NodeRef eventExecution = assoc.getChildRef();
|
NodeRef eventExecution = assoc.getChildRef();
|
||||||
Boolean isCompleteValue = (Boolean) getInternalNodeService().getProperty(eventExecution, PROP_EVENT_EXECUTION_COMPLETE);
|
Boolean isCompleteValue = (Boolean) getInternalNodeService().getProperty(eventExecution, PROP_EVENT_EXECUTION_COMPLETE);
|
||||||
boolean isComplete;
|
boolean isComplete = false;
|
||||||
if (isCompleteValue != null)
|
if (isCompleteValue != null)
|
||||||
{
|
{
|
||||||
isComplete = isCompleteValue.booleanValue();
|
isComplete = isCompleteValue.booleanValue();
|
||||||
@@ -977,7 +987,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getNextDispositionAction(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getNextDispositionAction(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DispositionAction getNextDispositionAction(NodeRef nodeRef)
|
public DispositionAction getNextDispositionAction(NodeRef nodeRef)
|
||||||
@@ -996,7 +1006,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
/** ========= Disposition Action History Methods ========= */
|
/** ========= Disposition Action History Methods ========= */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getCompletedDispositionActions(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getCompletedDispositionActions(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<DispositionAction> getCompletedDispositionActions(NodeRef nodeRef)
|
public List<DispositionAction> getCompletedDispositionActions(NodeRef nodeRef)
|
||||||
@@ -1012,7 +1022,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#getLastCompletedDispostionAction(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getLastCompletedDispostionAction(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DispositionAction getLastCompletedDispostionAction(NodeRef nodeRef)
|
public DispositionAction getLastCompletedDispostionAction(NodeRef nodeRef)
|
||||||
@@ -1028,7 +1038,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#isDisposableItemCutoff(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItemCutoff(NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isDisposableItemCutoff(NodeRef nodeRef)
|
public boolean isDisposableItemCutoff(NodeRef nodeRef)
|
||||||
@@ -1038,7 +1048,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#updateNextDispositionAction(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateNextDispositionAction(final NodeRef nodeRef)
|
public void updateNextDispositionAction(final NodeRef nodeRef)
|
||||||
@@ -1048,7 +1058,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
|
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @see RunAsWork#doWork()
|
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Void doWork()
|
public Void doWork()
|
||||||
@@ -1067,7 +1077,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#updateNextDispositionAction(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule)
|
public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule)
|
||||||
@@ -1077,7 +1087,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
|
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @see RunAsWork#doWork()
|
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Void doWork()
|
public Void doWork()
|
||||||
@@ -1103,13 +1113,16 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<DispositionActionDefinition> dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions();
|
List<DispositionActionDefinition> dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions();
|
||||||
DispositionActionDefinition currentDispositionActionDefinition;
|
DispositionActionDefinition currentDispositionActionDefinition = null;
|
||||||
DispositionActionDefinition nextDispositionActionDefinition = null;
|
DispositionActionDefinition nextDispositionActionDefinition = null;
|
||||||
|
|
||||||
if (currentDispositionAction == null && !dispositionActionDefinitions.isEmpty())
|
if (currentDispositionAction == null)
|
||||||
{
|
{
|
||||||
// The next disposition action is the first action
|
if (!dispositionActionDefinitions.isEmpty())
|
||||||
nextDispositionActionDefinition = dispositionActionDefinitions.get(0);
|
{
|
||||||
|
// The next disposition action is the first action
|
||||||
|
nextDispositionActionDefinition = dispositionActionDefinitions.get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1154,7 +1167,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DispositionService#cutoffDisposableItem(NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#cutoffDisposableItem(NodeRef)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void cutoffDisposableItem(final NodeRef nodeRef)
|
public void cutoffDisposableItem(final NodeRef nodeRef)
|
||||||
@@ -1192,7 +1205,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
// runAs system so that we can close a record that has already been cutoff
|
// runAs system so that we can close a record that has already been cutoff
|
||||||
authenticationUtil.runAsSystem(new RunAsWork<Void>()
|
authenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||||
{
|
{
|
||||||
@Override
|
|
||||||
public Void doWork() throws Exception
|
public Void doWork() throws Exception
|
||||||
{
|
{
|
||||||
recordFolderService.closeRecordFolder(nodeRef);
|
recordFolderService.closeRecordFolder(nodeRef);
|
||||||
@@ -1212,7 +1224,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Date getDispositionActionDate(NodeRef record, NodeRef dispositionSchedule, String dispositionActionName)
|
public Date getDispositionActionDate(NodeRef record, NodeRef dispositionSchedule, String dispositionActionName)
|
||||||
{
|
{
|
||||||
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dispositionSchedule);
|
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dispositionSchedule);
|
||||||
@@ -1232,8 +1243,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void recalculateNextDispositionStep(NodeRef record)
|
public void recalculateNextDispositionStep(NodeRef record)
|
||||||
{
|
{
|
||||||
List<NodeRef> recordFolders = recordFolderService.getRecordFolders(record);
|
List<NodeRef> recordFolders = recordFolderService.getRecordFolders(record);
|
||||||
@@ -1374,7 +1384,14 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
Date calculatedDate = (nextDispositionActionDate != null ? nextDispositionActionDate : maxDate);
|
Date calculatedDate = (nextDispositionActionDate != null ? nextDispositionActionDate : maxDate);
|
||||||
|
|
||||||
// We only need to update the date if the current one is too early.
|
// We only need to update the date if the current one is too early.
|
||||||
return recordDate.before(calculatedDate) ? WriteMode.DATE_ONLY : WriteMode.READ_ONLY;
|
if (recordDate.before(calculatedDate))
|
||||||
|
{
|
||||||
|
return WriteMode.DATE_ONLY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return WriteMode.READ_ONLY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1397,7 +1414,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
|||||||
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, folderDS);
|
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, folderDS);
|
||||||
List<DispositionActionDefinition> dispositionActionDefinitions = ds.getDispositionActionDefinitions();
|
List<DispositionActionDefinition> dispositionActionDefinitions = ds.getDispositionActionDefinitions();
|
||||||
|
|
||||||
if (dispositionActionDefinitions != null && !dispositionActionDefinitions.isEmpty())
|
if (dispositionActionDefinitions != null && dispositionActionDefinitions.size() > 0)
|
||||||
{
|
{
|
||||||
DispositionActionDefinition firstDispositionActionDef = dispositionActionDefinitions.get(0);
|
DispositionActionDefinition firstDispositionActionDef = dispositionActionDefinitions.get(0);
|
||||||
dispositionNodeRef = folderDS;
|
dispositionNodeRef = folderDS;
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new HashSet<>(rmContainerCacheManager.get(storeRef));
|
return rmContainerCacheManager.get(storeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.holds;
|
|
||||||
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
|
|
||||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkMonitor;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatusAndProcessDetails;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkUtils;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.rest.framework.Operation;
|
|
||||||
import org.alfresco.rest.framework.WebApiDescription;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
|
|
||||||
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.rest.framework.webscripts.WithResponse;
|
|
||||||
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
|
|
||||||
import org.alfresco.rm.rest.api.model.BulkCancellationEntry;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkStatusEntry;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
|
||||||
import org.springframework.extensions.surf.util.I18NUtil;
|
|
||||||
|
|
||||||
@RelationshipResource(name = "bulk-statuses", entityResource = HoldsEntityResource.class, title = "Bulk statuses of a hold")
|
|
||||||
public class HoldsBulkStatusesRelation
|
|
||||||
implements RelationshipResourceAction.Read<HoldBulkStatusEntry>,
|
|
||||||
RelationshipResourceAction.ReadById<HoldBulkStatusEntry>
|
|
||||||
{
|
|
||||||
private HoldBulkMonitor holdBulkMonitor;
|
|
||||||
private HoldBulkService holdBulkService;
|
|
||||||
private FilePlanComponentsApiUtils apiUtils;
|
|
||||||
private PermissionService permissionService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionWithPagingInfo<HoldBulkStatusEntry> readAll(String holdId, Parameters parameters)
|
|
||||||
{
|
|
||||||
// validate parameters
|
|
||||||
checkNotBlank("holdId", holdId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
|
|
||||||
NodeRef holdRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
|
|
||||||
|
|
||||||
checkReadPermissions(holdRef);
|
|
||||||
|
|
||||||
List<HoldBulkStatusAndProcessDetails> statuses = holdBulkMonitor.getBulkStatusesWithProcessDetails(holdId);
|
|
||||||
List<HoldBulkStatusEntry> page = statuses.stream()
|
|
||||||
.map(HoldBulkUtils::toHoldBulkStatusEntry)
|
|
||||||
.skip(parameters.getPaging().getSkipCount())
|
|
||||||
.limit(parameters.getPaging().getMaxItems())
|
|
||||||
.collect(Collectors.toCollection(LinkedList::new));
|
|
||||||
|
|
||||||
int totalItems = statuses.size();
|
|
||||||
boolean hasMore = parameters.getPaging().getSkipCount() + parameters.getPaging().getMaxItems() < totalItems;
|
|
||||||
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, hasMore, totalItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HoldBulkStatusEntry readById(String holdId, String bulkStatusId, Parameters parameters)
|
|
||||||
throws RelationshipResourceNotFoundException
|
|
||||||
{
|
|
||||||
checkNotBlank("holdId", holdId);
|
|
||||||
checkNotBlank("bulkStatusId", bulkStatusId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
|
|
||||||
NodeRef holdRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
|
|
||||||
|
|
||||||
checkReadPermissions(holdRef);
|
|
||||||
|
|
||||||
return Optional.ofNullable(holdBulkMonitor.getBulkStatusWithProcessDetails(holdId, bulkStatusId))
|
|
||||||
.map(HoldBulkUtils::toHoldBulkStatusEntry)
|
|
||||||
.orElseThrow(() -> new EntityNotFoundException(bulkStatusId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation("cancel")
|
|
||||||
@WebApiDescription(title = "Cancel a bulk operation",
|
|
||||||
successStatus = HttpServletResponse.SC_OK)
|
|
||||||
public void cancelBulkOperation(String holdId, String bulkStatusId, BulkCancellationEntry bulkCancellationEntry,
|
|
||||||
Parameters parameters,
|
|
||||||
WithResponse withResponse)
|
|
||||||
{
|
|
||||||
checkNotBlank("holdId", holdId);
|
|
||||||
checkNotBlank("bulkStatusId", bulkStatusId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
|
|
||||||
NodeRef holdRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
|
|
||||||
|
|
||||||
checkReadPermissions(holdRef);
|
|
||||||
|
|
||||||
if (holdBulkMonitor.getBulkStatus(bulkStatusId) == null)
|
|
||||||
{
|
|
||||||
throw new NotFoundException("Bulk status not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
holdBulkService.cancelBulkOperation(holdRef, bulkStatusId, new BulkCancellationRequest(bulkCancellationEntry.reason()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkReadPermissions(NodeRef holdRef)
|
|
||||||
{
|
|
||||||
if (permissionService.hasReadPermission(holdRef) == AccessStatus.DENIED)
|
|
||||||
{
|
|
||||||
throw new PermissionDeniedException(I18NUtil.getMessage("permissions.err_access_denied"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldBulkMonitor(HoldBulkMonitor holdBulkMonitor)
|
|
||||||
{
|
|
||||||
this.holdBulkMonitor = holdBulkMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
|
|
||||||
{
|
|
||||||
this.apiUtils = apiUtils;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPermissionService(PermissionService permissionService)
|
|
||||||
{
|
|
||||||
this.permissionService = permissionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldBulkService(HoldBulkService holdBulkService)
|
|
||||||
{
|
|
||||||
this.holdBulkService = holdBulkService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,8 +30,6 @@ import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.c
|
|||||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
@@ -44,9 +42,6 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
|
|||||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||||
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
|
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
|
||||||
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
|
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkOperation;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldBulkOperationEntry;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatus;
|
|
||||||
import org.alfresco.rm.rest.api.model.HoldDeletionReason;
|
import org.alfresco.rm.rest.api.model.HoldDeletionReason;
|
||||||
import org.alfresco.rm.rest.api.model.HoldModel;
|
import org.alfresco.rm.rest.api.model.HoldModel;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
@@ -73,7 +68,6 @@ public class HoldsEntityResource implements
|
|||||||
private ApiNodesModelFactory nodesModelFactory;
|
private ApiNodesModelFactory nodesModelFactory;
|
||||||
private HoldService holdService;
|
private HoldService holdService;
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
private HoldBulkService holdBulkService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception
|
public void afterPropertiesSet() throws Exception
|
||||||
@@ -163,23 +157,6 @@ public class HoldsEntityResource implements
|
|||||||
return reason;
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation("bulk")
|
|
||||||
@WebApiDescription(title = "Start the hold bulk operation",
|
|
||||||
successStatus = HttpServletResponse.SC_ACCEPTED)
|
|
||||||
public HoldBulkOperationEntry bulk(String holdId, HoldBulkOperation holdBulkOperation, Parameters parameters,
|
|
||||||
WithResponse withResponse)
|
|
||||||
{
|
|
||||||
// validate parameters
|
|
||||||
checkNotBlank("holdId", holdId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
|
|
||||||
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
|
|
||||||
|
|
||||||
HoldBulkStatus holdBulkStatus = holdBulkService.execute(parentNodeRef,
|
|
||||||
new BulkOperation(holdBulkOperation.query(), holdBulkOperation.op().name()));
|
|
||||||
return new HoldBulkOperationEntry(holdBulkStatus.bulkStatusId(), holdBulkStatus.totalItems());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
|
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
|
||||||
{
|
{
|
||||||
this.apiUtils = apiUtils;
|
this.apiUtils = apiUtils;
|
||||||
@@ -204,9 +181,4 @@ public class HoldsEntityResource implements
|
|||||||
{
|
{
|
||||||
this.transactionService = transactionService;
|
this.transactionService = transactionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHoldBulkService(HoldBulkService holdBulkService)
|
|
||||||
{
|
|
||||||
this.holdBulkService = holdBulkService;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,16 +34,10 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
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.DispositionSchedule;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
import org.alfresco.rest.api.model.AssocChild;
|
import org.alfresco.rest.api.model.AssocChild;
|
||||||
@@ -59,8 +53,6 @@ import org.alfresco.rm.rest.api.model.Record;
|
|||||||
import org.alfresco.rm.rest.api.model.RecordCategory;
|
import org.alfresco.rm.rest.api.model.RecordCategory;
|
||||||
import org.alfresco.rm.rest.api.model.RecordCategoryChild;
|
import org.alfresco.rm.rest.api.model.RecordCategoryChild;
|
||||||
import org.alfresco.rm.rest.api.model.RecordFolder;
|
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.Transfer;
|
||||||
import org.alfresco.rm.rest.api.model.TransferChild;
|
import org.alfresco.rm.rest.api.model.TransferChild;
|
||||||
import org.alfresco.rm.rest.api.model.TransferContainer;
|
import org.alfresco.rm.rest.api.model.TransferContainer;
|
||||||
@@ -69,8 +61,6 @@ import org.alfresco.rm.rest.api.model.UnfiledContainer;
|
|||||||
import org.alfresco.rm.rest.api.model.UnfiledContainerChild;
|
import org.alfresco.rm.rest.api.model.UnfiledContainerChild;
|
||||||
import org.alfresco.rm.rest.api.model.UnfiledRecordFolder;
|
import org.alfresco.rm.rest.api.model.UnfiledRecordFolder;
|
||||||
import org.alfresco.rm.rest.api.model.UnfiledRecordFolderChild;
|
import org.alfresco.rm.rest.api.model.UnfiledRecordFolderChild;
|
||||||
import org.alfresco.rm.rest.api.model.RetentionSchedule;
|
|
||||||
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.model.FileInfo;
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
@@ -80,9 +70,6 @@ import org.alfresco.service.cmr.repository.NodeService;
|
|||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
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
|
* Utility class containing Alfresco and RM java services required by the API
|
||||||
@@ -94,9 +81,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class ApiNodesModelFactory
|
public class ApiNodesModelFactory
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Logger */
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ApiNodesModelFactory.class);
|
|
||||||
|
|
||||||
// excluded namespaces (aspects, properties, assoc types)
|
// excluded namespaces (aspects, properties, assoc types)
|
||||||
public static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
|
public static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||||
|
|
||||||
@@ -118,7 +102,6 @@ public class ApiNodesModelFactory
|
|||||||
private PersonService personService;
|
private PersonService personService;
|
||||||
private DispositionService dispositionService;
|
private DispositionService dispositionService;
|
||||||
private ServiceRegistry serviceRegistry;
|
private ServiceRegistry serviceRegistry;
|
||||||
private RecordsManagementServiceRegistry services;
|
|
||||||
|
|
||||||
public NodeService getNodeService()
|
public NodeService getNodeService()
|
||||||
{
|
{
|
||||||
@@ -170,11 +153,6 @@ public class ApiNodesModelFactory
|
|||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry services)
|
|
||||||
{
|
|
||||||
this.services = services;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method that sets the basic information for most of the node types.
|
* Helper method that sets the basic information for most of the node types.
|
||||||
*
|
*
|
||||||
@@ -526,15 +504,15 @@ public class ApiNodesModelFactory
|
|||||||
}
|
}
|
||||||
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
|
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
|
||||||
{
|
{
|
||||||
if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsRecordFolder(true);
|
recordCategoryChild.setIsRecordFolder(true);
|
||||||
}
|
}
|
||||||
if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsRecordCategory(false);
|
recordCategoryChild.setIsRecordCategory(false);
|
||||||
}
|
}
|
||||||
if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
|
recordCategoryChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
|
||||||
}
|
}
|
||||||
@@ -545,11 +523,11 @@ public class ApiNodesModelFactory
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsRecordFolder(false);
|
recordCategoryChild.setIsRecordFolder(false);
|
||||||
}
|
}
|
||||||
if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsRecordCategory(true);
|
recordCategoryChild.setIsRecordCategory(true);
|
||||||
}
|
}
|
||||||
@@ -558,28 +536,13 @@ public class ApiNodesModelFactory
|
|||||||
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
|
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
|
||||||
recordCategoryChild.setHasRetentionSchedule(ds != null);
|
recordCategoryChild.setHasRetentionSchedule(ds != null);
|
||||||
}
|
}
|
||||||
if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
|
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
|
||||||
{
|
{
|
||||||
recordCategoryChild.setIsClosed(null);
|
recordCategoryChild.setIsClosed(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRecordCategoryChildClosed(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam)
|
|
||||||
{
|
|
||||||
return (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRecordCategory(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List<String> 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<String> 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
|
* Utility method that maps record specific fields
|
||||||
@@ -602,8 +565,7 @@ public class ApiNodesModelFactory
|
|||||||
{
|
{
|
||||||
Serializable val = info.getProperties().get(ContentModel.PROP_CONTENT);
|
Serializable val = info.getProperties().get(ContentModel.PROP_CONTENT);
|
||||||
|
|
||||||
if (val instanceof ContentData)
|
if ((val != null) && (val instanceof ContentData)) {
|
||||||
{
|
|
||||||
ContentData cd = (ContentData)val;
|
ContentData cd = (ContentData)val;
|
||||||
String mimeType = cd.getMimetype();
|
String mimeType = cd.getMimetype();
|
||||||
String mimeTypeName = serviceRegistry.getMimetypeService().getDisplaysByMimetype().get(mimeType);
|
String mimeTypeName = serviceRegistry.getMimetypeService().getDisplaysByMimetype().get(mimeType);
|
||||||
@@ -929,238 +891,4 @@ public class ApiNodesModelFactory
|
|||||||
mapAssociations(record, info, parameters.getInclude());
|
mapAssociations(record, info, parameters.getInclude());
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Helper method that sets the information for the retention schedule type.
|
|
||||||
* @param dispositionSchedule
|
|
||||||
* @return RetentionSchedule
|
|
||||||
*/
|
|
||||||
public RetentionSchedule mapRetentionScheduleData(DispositionSchedule dispositionSchedule)
|
|
||||||
{
|
|
||||||
RetentionSchedule retentionSchedule = new RetentionSchedule();
|
|
||||||
retentionSchedule.setId(dispositionSchedule.getNodeRef().getId());
|
|
||||||
if (dispositionSchedule.getNodeRef() != null) {
|
|
||||||
NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef();
|
|
||||||
retentionSchedule.setParentId(parent.getId());
|
|
||||||
}
|
|
||||||
retentionSchedule.setInstructions(dispositionSchedule.getDispositionInstructions());
|
|
||||||
retentionSchedule.setAuthority(dispositionSchedule.getDispositionAuthority());
|
|
||||||
retentionSchedule.setIsRecordLevel(dispositionSchedule.isRecordLevelDisposition());
|
|
||||||
|
|
||||||
boolean unpublishedUpdates = dispositionSchedule.getDispositionActionDefinitions().stream()
|
|
||||||
.map(DispositionActionDefinition::getNodeRef)
|
|
||||||
.anyMatch(actionDefNodeRef -> nodeService.hasAspect(actionDefNodeRef, RecordsManagementModel.ASPECT_UNPUBLISHED_UPDATE));
|
|
||||||
retentionSchedule.setUnpublishedUpdates(unpublishedUpdates);
|
|
||||||
return retentionSchedule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that sets the information for the retention schedule action definition type.
|
|
||||||
* @param dispositionActionDefinition
|
|
||||||
* @return RetentionScheduleActionDefinition
|
|
||||||
*/
|
|
||||||
public RetentionScheduleActionDefinition mapRetentionScheduleActionDefData(DispositionActionDefinition dispositionActionDefinition)
|
|
||||||
{
|
|
||||||
RetentionScheduleActionDefinition retentionScheduleActionDefinition = new RetentionScheduleActionDefinition();
|
|
||||||
// Mapping basic properties
|
|
||||||
mapRetentionActionProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
|
|
||||||
// Mapping period and period amount
|
|
||||||
mapPeriodProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
|
|
||||||
// Mapping events properties
|
|
||||||
mapEventsProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
|
|
||||||
return retentionScheduleActionDefinition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that sets core information for the retention schedule action definition type.
|
|
||||||
* @param dispositionActionDefinition
|
|
||||||
* @param retentionScheduleActionDefinition
|
|
||||||
*/
|
|
||||||
private void mapRetentionActionProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
retentionScheduleActionDefinition.setId(dispositionActionDefinition.getId());
|
|
||||||
retentionScheduleActionDefinition.setName(dispositionActionDefinition.getName());
|
|
||||||
retentionScheduleActionDefinition.setDescription(dispositionActionDefinition.getDescription());
|
|
||||||
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent());
|
|
||||||
if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null)
|
|
||||||
{
|
|
||||||
retentionScheduleActionDefinition.setCombineRetentionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
|
|
||||||
}
|
|
||||||
retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation());
|
|
||||||
if (dispositionActionDefinition.getGhostOnDestroy() != null)
|
|
||||||
{
|
|
||||||
retentionScheduleActionDefinition.setRetainRecordMetadataAfterDestruction(dispositionActionDefinition.getGhostOnDestroy().equals("ghost"));
|
|
||||||
}
|
|
||||||
retentionScheduleActionDefinition.setIndex(dispositionActionDefinition.getIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that sets the period-related information for the retention schedule action definition type.
|
|
||||||
* @param dispositionActionDefinition
|
|
||||||
* @param retentionScheduleActionDefinition
|
|
||||||
*/
|
|
||||||
private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
if (dispositionActionDefinition.getPeriodProperty() != null)
|
|
||||||
{
|
|
||||||
retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService));
|
|
||||||
}
|
|
||||||
|
|
||||||
String period = dispositionActionDefinition.getPeriod().toString();
|
|
||||||
if (!period.isEmpty())
|
|
||||||
{
|
|
||||||
// In rest api we are splitting `period` property into `period` and `periodAmount`.
|
|
||||||
// so we need to split the period into two properties.
|
|
||||||
// ex. period -> 'month|10' so the split properties would be like below
|
|
||||||
// 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 numberFormatException)
|
|
||||||
{
|
|
||||||
LOGGER.error("Error parsing period amount: {}{}", numberFormatException.getMessage(), periodArray[1], numberFormatException);
|
|
||||||
throw numberFormatException;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that sets the events information for the retention schedule action definition type.
|
|
||||||
* @param dispositionActionDefinition
|
|
||||||
* @param retentionScheduleActionDefinition
|
|
||||||
*/
|
|
||||||
private void mapEventsProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
List<RecordsManagementEvent> events = dispositionActionDefinition.getEvents();
|
|
||||||
if (events != null && !events.isEmpty())
|
|
||||||
{
|
|
||||||
List<String> eventNames = events.stream()
|
|
||||||
.map(RecordsManagementEvent::getName)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
retentionScheduleActionDefinition.setEvents(eventNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that sets the optional information for the retention schedule type.
|
|
||||||
* @param retentionSchedule
|
|
||||||
* @param schedule
|
|
||||||
* @param includeParam
|
|
||||||
*/
|
|
||||||
public void mapRetentionScheduleOptionalInfo(RetentionSchedule retentionSchedule, DispositionSchedule schedule, List<String> includeParam)
|
|
||||||
{
|
|
||||||
if (includeParam != null && !includeParam.isEmpty() && includeParam.contains("actions"))
|
|
||||||
{
|
|
||||||
List<RetentionScheduleActionDefinition> actions = schedule.getDispositionActionDefinitions().stream()
|
|
||||||
.map(this::mapRetentionScheduleActionDefData)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
retentionSchedule.setActions(actions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this method is used for creation of retention schedule action definition params
|
|
||||||
* @param nodeInfo retention schedule action definition
|
|
||||||
* @return Map<QName, Serializable>
|
|
||||||
*/
|
|
||||||
public Map<QName, Serializable> createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo)
|
|
||||||
{
|
|
||||||
Map<QName, Serializable> actionDefinitionParams= new HashMap<>();
|
|
||||||
|
|
||||||
String retentionActionName = nodeInfo.getName();
|
|
||||||
|
|
||||||
if (nodeInfo.getName().equals(RetentionSteps.DESTROY_NODE.stepName) ||
|
|
||||||
nodeInfo.getName().equals(RetentionSteps.DESTROY_CONTENT.stepName))
|
|
||||||
{
|
|
||||||
retentionActionName = "destroy";
|
|
||||||
}
|
|
||||||
|
|
||||||
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, retentionActionName);
|
|
||||||
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());
|
|
||||||
boolean combineConditions = nodeInfo.getName().equals(RetentionSteps.ACCESSION.stepName) && nodeInfo.isCombineRetentionStepConditions();
|
|
||||||
actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, combineConditions);
|
|
||||||
|
|
||||||
if(nodeInfo.getLocation() != null && nodeInfo.getName().equals(RetentionSteps.TRANSFER.stepName))
|
|
||||||
{
|
|
||||||
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION,
|
|
||||||
nodeInfo.getLocation());
|
|
||||||
}
|
|
||||||
List<String> inputEvents = nodeInfo.getEvents();
|
|
||||||
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents);
|
|
||||||
|
|
||||||
if (RetentionSteps.DESTROY_CONTENT.stepName.equals(nodeInfo.getName()))
|
|
||||||
{
|
|
||||||
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost");
|
|
||||||
}
|
|
||||||
else if (RetentionSteps.DESTROY_NODE.stepName.equals(nodeInfo.getName()))
|
|
||||||
{
|
|
||||||
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<DispositionActionDefinition>
|
|
||||||
*/
|
|
||||||
public List<DispositionActionDefinition> getRetentionActions(NodeRef retentionScheduleNodeRef)
|
|
||||||
{
|
|
||||||
List<ChildAssociationRef> 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<DispositionActionDefinition> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class SearchTypesFactory
|
|||||||
boolean includeRecords = false;
|
boolean includeRecords = false;
|
||||||
boolean includeSubTypes = false;
|
boolean includeSubTypes = false;
|
||||||
|
|
||||||
if (q != null && q.getTree() != null)
|
if (q != null)
|
||||||
{
|
{
|
||||||
// filtering via "where" clause
|
// filtering via "where" clause
|
||||||
MapBasedQueryWalker propertyWalker = new MapBasedQueryWalker(listFolderChildrenEqualsQueryProperties, null);
|
MapBasedQueryWalker propertyWalker = new MapBasedQueryWalker(listFolderChildrenEqualsQueryProperties, null);
|
||||||
@@ -101,11 +101,11 @@ public class SearchTypesFactory
|
|||||||
Boolean isUnfiledRecordFolder = propertyWalker.getProperty(UnfiledChild.PARAM_IS_UNFILED_RECORD_FOLDER,
|
Boolean isUnfiledRecordFolder = propertyWalker.getProperty(UnfiledChild.PARAM_IS_UNFILED_RECORD_FOLDER,
|
||||||
WhereClauseParser.EQUALS, Boolean.class);
|
WhereClauseParser.EQUALS, Boolean.class);
|
||||||
Boolean isRecord = propertyWalker.getProperty(UnfiledChild.PARAM_IS_RECORD, WhereClauseParser.EQUALS, Boolean.class);
|
Boolean isRecord = propertyWalker.getProperty(UnfiledChild.PARAM_IS_RECORD, WhereClauseParser.EQUALS, Boolean.class);
|
||||||
if (checkIncludeUnfiledRecordFolders(isUnfiledRecordFolder, isRecord))
|
if ((isUnfiledRecordFolder != null && isUnfiledRecordFolder.booleanValue()) || (isRecord != null && !isRecord.booleanValue()))
|
||||||
{
|
{
|
||||||
includeUnfiledRecordFolders = true;
|
includeUnfiledRecordFolders = true;
|
||||||
}
|
}
|
||||||
else if (checkIncludeRecords(isUnfiledRecordFolder, isRecord))
|
else if ((isUnfiledRecordFolder != null && !isUnfiledRecordFolder.booleanValue()) || (isRecord != null && isRecord.booleanValue()))
|
||||||
{
|
{
|
||||||
includeRecords = true;
|
includeRecords = true;
|
||||||
}
|
}
|
||||||
@@ -199,11 +199,11 @@ public class SearchTypesFactory
|
|||||||
WhereClauseParser.EQUALS, Boolean.class);
|
WhereClauseParser.EQUALS, Boolean.class);
|
||||||
Boolean isRecordCategory = propertyWalker.getProperty(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY, WhereClauseParser.EQUALS, Boolean.class);
|
Boolean isRecordCategory = propertyWalker.getProperty(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY, WhereClauseParser.EQUALS, Boolean.class);
|
||||||
|
|
||||||
if (checkIncludeUnfiledRecordFolders(isRecordFolder, isRecordCategory))
|
if ((isRecordFolder != null && isRecordFolder.booleanValue()) || (isRecordCategory != null && !isRecordCategory.booleanValue()))
|
||||||
{
|
{
|
||||||
includeRecordFolders = true;
|
includeRecordFolders = true;
|
||||||
}
|
}
|
||||||
else if (checkIncludeRecords(isRecordFolder, isRecordCategory))
|
else if ((isRecordFolder != null && !isRecordFolder.booleanValue()) || (isRecordCategory != null && isRecordCategory.booleanValue()))
|
||||||
{
|
{
|
||||||
includeRecordCategories = true;
|
includeRecordCategories = true;
|
||||||
}
|
}
|
||||||
@@ -291,16 +291,4 @@ public class SearchTypesFactory
|
|||||||
|
|
||||||
return new Pair<>(filterNodeTypeQName, filterIncludeSubTypes);
|
return new Pair<>(filterNodeTypeQName, filterIncludeSubTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkIncludeRecords(Boolean isUnfiledRecordFolder, Boolean isRecord)
|
|
||||||
{
|
|
||||||
return (isUnfiledRecordFolder != null && !isUnfiledRecordFolder.booleanValue()) || (isRecord != null
|
|
||||||
&& isRecord.booleanValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean checkIncludeUnfiledRecordFolders(Boolean isUnfiledRecordFolder, Boolean isRecord)
|
|
||||||
{
|
|
||||||
return (isUnfiledRecordFolder != null && isUnfiledRecordFolder.booleanValue()) || (isRecord != null
|
|
||||||
&& !isRecord.booleanValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
public record BulkCancellationEntry(String reason) {}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
|
|
||||||
public record HoldBulkOperation(@JsonProperty(required = true) Query query, @JsonProperty(required = true) HoldBulkOperationType op) {}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
public record HoldBulkOperationEntry(String bulkStatusId, long totalItems){}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This enum represents the types of bulk operations that can be performed on holds
|
|
||||||
*/
|
|
||||||
public enum HoldBulkOperationType
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The ADD operation represents adding items to a hold in bulk.
|
|
||||||
*/
|
|
||||||
ADD
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public record HoldBulkStatusEntry(String bulkStatusId, Date startTime, Date endTime, long processedItems, long errorsCount,
|
|
||||||
long totalItems, String lastError, String status, String cancellationReason, HoldBulkOperation holdBulkOperation) {
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* retention schedule
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class RetentionSchedule
|
|
||||||
{
|
|
||||||
private String id ;
|
|
||||||
private String parentId;
|
|
||||||
private String authority;
|
|
||||||
private String instructions;
|
|
||||||
private boolean isRecordLevel;
|
|
||||||
private boolean isUnpublishedUpdates;
|
|
||||||
private List<RetentionScheduleActionDefinition> actions;
|
|
||||||
|
|
||||||
public boolean getIsRecordLevel()
|
|
||||||
{
|
|
||||||
return isRecordLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsRecordLevel(boolean recordLevel)
|
|
||||||
{
|
|
||||||
isRecordLevel = recordLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* retention schedule action definition
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class RetentionScheduleActionDefinition
|
|
||||||
{
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
private int periodAmount;
|
|
||||||
private String period;
|
|
||||||
private String periodProperty;
|
|
||||||
private boolean combineRetentionStepConditions;
|
|
||||||
private List<String> events;
|
|
||||||
private boolean eligibleOnFirstCompleteEvent;
|
|
||||||
private boolean retainRecordMetadataAfterDestruction;
|
|
||||||
private String location;
|
|
||||||
private int index;
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retention steps values
|
|
||||||
*/
|
|
||||||
public enum RetentionSteps
|
|
||||||
{
|
|
||||||
RETAIN("retain"),
|
|
||||||
CUTOFF("cutoff"),
|
|
||||||
TRANSFER("transfer"),
|
|
||||||
ACCESSION("accession"),
|
|
||||||
DESTROY_CONTENT("destroyContent"),
|
|
||||||
DESTROY_NODE("destroyNode");
|
|
||||||
|
|
||||||
public final String stepName;
|
|
||||||
|
|
||||||
RetentionSteps(String stepName)
|
|
||||||
{
|
|
||||||
this.stepName = stepName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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<RetentionScheduleActionDefinition>,
|
|
||||||
RelationshipResourceAction.Create<RetentionScheduleActionDefinition>
|
|
||||||
{
|
|
||||||
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<RetentionScheduleActionDefinition> create(String retentionScheduleId, List<RetentionScheduleActionDefinition> 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<QName, Serializable> 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<RetentionScheduleActionDefinition> 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<RetentionScheduleActionDefinition> readAll(String retentionScheduleId, Parameters parameters)
|
|
||||||
{
|
|
||||||
checkNotBlank("retentionScheduleId", retentionScheduleId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
|
|
||||||
List<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
|
|
||||||
List<RetentionScheduleActionDefinition> 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)
|
|
||||||
{
|
|
||||||
if (checkStepNameIsEmpty(retentionScheduleActionDefinition.getName()))
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
|
|
||||||
Set<String> completedActions = new HashSet<>();
|
|
||||||
if (!actions.isEmpty())
|
|
||||||
{
|
|
||||||
completedActions = actions.stream()
|
|
||||||
.map(DispositionActionDefinition::getName)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completedActions.contains("destroy"))
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkStepNameIsEmpty(String name)
|
|
||||||
{
|
|
||||||
return name == null || name.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
validatePeriodAndPeriodProperty(retentionScheduleActionDefinition);
|
|
||||||
|
|
||||||
// event name validation
|
|
||||||
if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents()))
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException("event value is invalid: " + retentionScheduleActionDefinition.getEvents());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateCombineRetentionStepConditionsForNonAccessionStep(retentionScheduleActionDefinition))
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("combineRetentionStepConditions property is only valid for accession step. Not valid for :" + retentionScheduleActionDefinition.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateLocationForNonTransferStep(retentionScheduleActionDefinition))
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("location property is only valid for transfer step. Not valid for :" + retentionScheduleActionDefinition.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validatePeriodAndPeriodProperty(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
// period value validation
|
|
||||||
if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod()))
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod());
|
|
||||||
}
|
|
||||||
|
|
||||||
// periodProperty validation
|
|
||||||
List<String> 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 validateCombineRetentionStepConditionsForNonAccessionStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
return !retentionScheduleActionDefinition.getName().equals(RetentionSteps.ACCESSION.stepName)
|
|
||||||
&& retentionScheduleActionDefinition.isCombineRetentionStepConditions();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean validateLocationForNonTransferStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
|
||||||
{
|
|
||||||
return retentionScheduleActionDefinition.getLocation() != null
|
|
||||||
&& !retentionScheduleActionDefinition.getName().equals(RetentionSteps.TRANSFER.stepName)
|
|
||||||
&& !retentionScheduleActionDefinition.getLocation().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkStepAlreadyExists(Set<String> completedActions, String stepName)
|
|
||||||
{
|
|
||||||
return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean firstStepValidation(List<DispositionActionDefinition> actions, String stepName)
|
|
||||||
{
|
|
||||||
return actions.isEmpty()
|
|
||||||
&& !stepName.equals(RetentionSteps.CUTOFF.stepName) && (!stepName.equals(RetentionSteps.RETAIN.stepName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCutOffStepAllowed(Set<String> 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<String> events)
|
|
||||||
{
|
|
||||||
return !events.isEmpty() && events.stream()
|
|
||||||
.anyMatch(event -> Arrays.stream(RetentionEvents.values())
|
|
||||||
.noneMatch(retentionEvent -> retentionEvent.eventName.equals(event)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #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
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.rm.rest.api.retentionschedule;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
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.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.rest.framework.WebApiDescription;
|
|
||||||
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.RetentionSchedule;
|
|
||||||
import org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_AUTHORITY;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_INSTRUCTIONS;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_RECORD_LEVEL_DISPOSITION;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retention schedule relation is used perform retention schedule operation for a record category.
|
|
||||||
*/
|
|
||||||
@RelationshipResource(name = "retention-schedules", entityResource = RecordCategoriesEntityResource.class, title = "Retention Schedule")
|
|
||||||
public class RetentionScheduleRelation implements RelationshipResourceAction.Read<RetentionSchedule>,
|
|
||||||
RelationshipResourceAction.Create<RetentionSchedule>
|
|
||||||
{
|
|
||||||
|
|
||||||
private FilePlanComponentsApiUtils apiUtils;
|
|
||||||
private ApiNodesModelFactory nodesModelFactory;
|
|
||||||
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<RetentionSchedule> create(String recordCategoryId, List<RetentionSchedule> nodeInfos, Parameters parameters)
|
|
||||||
{
|
|
||||||
checkNotBlank("recordCategoryId", recordCategoryId);
|
|
||||||
mandatory("entity", nodeInfos);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordCategoryId);
|
|
||||||
|
|
||||||
if (checkCategoryHasAssocFolder(parentNodeRef) && nodeInfos.get(0).getIsRecordLevel())
|
|
||||||
{
|
|
||||||
throw new UnprocessableContentException("Record level retention schedule cannot be created for a record category having folder associated.");
|
|
||||||
}
|
|
||||||
List<RetentionSchedule> result = new ArrayList<>();
|
|
||||||
// Create the disposition schedule
|
|
||||||
Map<QName, Serializable> 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).getIsRecordLevel());
|
|
||||||
DispositionSchedule dispositionSchedule = dispositionService.createDispositionSchedule(parentNodeRef, dsProps);
|
|
||||||
RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
|
|
||||||
result.add(retentionSchedule);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkCategoryHasAssocFolder(NodeRef nodeRef)
|
|
||||||
{
|
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
return assocs.stream()
|
|
||||||
.map(assoc -> nodeService.getType(assoc.getChildRef()))
|
|
||||||
.anyMatch(nodeType -> nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'")
|
|
||||||
public CollectionWithPagingInfo<RetentionSchedule> readAll(String recordCategoryId, Parameters parameters)
|
|
||||||
{
|
|
||||||
checkNotBlank("recordCategoryId", recordCategoryId);
|
|
||||||
mandatory("parameters", parameters);
|
|
||||||
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(recordCategoryId, TYPE_RECORD_CATEGORY);
|
|
||||||
DispositionSchedule schedule = dispositionService.getDispositionSchedule(parentNodeRef);
|
|
||||||
RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(schedule);
|
|
||||||
List<RetentionSchedule> retentionScheduleList = new ArrayList<>();
|
|
||||||
nodesModelFactory.mapRetentionScheduleOptionalInfo(retentionSchedule, schedule, parameters.getInclude());
|
|
||||||
retentionScheduleList.add(retentionSchedule);
|
|
||||||
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), retentionScheduleList, false,
|
|
||||||
retentionScheduleList.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package info that defines the Information Governance Retention Schedule REST API
|
|
||||||
*/
|
|
||||||
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
|
|
||||||
package org.alfresco.rm.rest.api.retentionschedule;
|
|
||||||
import org.alfresco.rest.framework.Api;
|
|
||||||
import org.alfresco.rest.framework.WebApi;
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.test.integration.bulk.hold;
|
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
|
||||||
|
|
||||||
import static org.awaitility.Awaitility.await;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkCancellationRequest;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkMonitor;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkServiceImpl;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatus;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatus.Status;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
|
||||||
import org.alfresco.rest.api.search.model.Query;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
|
||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
import org.springframework.extensions.webscripts.GUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hold bulk service integration test.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({ "PMD.TestClassWithoutTestCases", "PMD.JUnit4TestShouldUseTestAnnotation" })
|
|
||||||
public class HoldBulkServiceTest extends BaseRMTestCase
|
|
||||||
{
|
|
||||||
private static final int RECORD_COUNT = 10;
|
|
||||||
private final SearchService searchServiceMock = mock(SearchService.class);
|
|
||||||
private final ResultSet resultSet = mock(ResultSet.class);
|
|
||||||
private HoldBulkServiceImpl holdBulkService;
|
|
||||||
private HoldBulkMonitor holdBulkMonitor;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initServices()
|
|
||||||
{
|
|
||||||
super.initServices();
|
|
||||||
holdBulkMonitor = (HoldBulkMonitor) applicationContext.getBean("holdBulkMonitor");
|
|
||||||
holdBulkService = (HoldBulkServiceImpl) applicationContext.getBean("holdBulkService");
|
|
||||||
holdBulkService.setSearchService(searchServiceMock);
|
|
||||||
Mockito.when(searchServiceMock.query(any(SearchParameters.class))).thenReturn(resultSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCancelBulkOperation()
|
|
||||||
{
|
|
||||||
doBehaviourDrivenTest(new BehaviourDrivenTest()
|
|
||||||
{
|
|
||||||
private NodeRef hold;
|
|
||||||
private HoldBulkStatus holdBulkStatus;
|
|
||||||
private final ResultSet resultSet = mock(ResultSet.class);
|
|
||||||
|
|
||||||
public void given()
|
|
||||||
{
|
|
||||||
Mockito.when(resultSet.getNumberFound()).thenReturn(4L);
|
|
||||||
Mockito.when(resultSet.hasMore()).thenReturn(false).thenReturn(true).thenReturn(false);
|
|
||||||
Mockito.when(resultSet.getNodeRefs())
|
|
||||||
.thenAnswer((Answer<List<NodeRef>>) invocationOnMock -> {
|
|
||||||
await().pollDelay(1, SECONDS).until(() -> true);
|
|
||||||
return List.of(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate()),
|
|
||||||
new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate()));
|
|
||||||
});
|
|
||||||
// create a hold
|
|
||||||
hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void when()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = new BulkOperation(new Query("afts", "*", ""), "ADD");
|
|
||||||
// execute the bulk operation
|
|
||||||
holdBulkStatus = holdBulkService.execute(hold, bulkOperation);
|
|
||||||
// cancel the bulk operation
|
|
||||||
holdBulkMonitor.cancelBulkOperation(holdBulkStatus.bulkStatusId(),
|
|
||||||
new BulkCancellationRequest("No reason"));
|
|
||||||
await().atMost(10, SECONDS)
|
|
||||||
.until(() -> Objects.equals(
|
|
||||||
holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
Status.CANCELLED.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void then()
|
|
||||||
{
|
|
||||||
holdBulkStatus = holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId());
|
|
||||||
assertNotNull(holdBulkStatus.startTime());
|
|
||||||
assertNotNull(holdBulkStatus.endTime());
|
|
||||||
assertEquals(holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
HoldBulkStatus.Status.CANCELLED.getValue());
|
|
||||||
assertEquals(holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).cancellationReason(),
|
|
||||||
"No reason");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddRecordsToHoldViaBulk()
|
|
||||||
{
|
|
||||||
doBehaviourDrivenTest(new BehaviourDrivenTest()
|
|
||||||
{
|
|
||||||
private NodeRef hold;
|
|
||||||
private NodeRef recordFolder;
|
|
||||||
private HoldBulkStatus holdBulkStatus;
|
|
||||||
private final List<NodeRef> records = new ArrayList<>(RECORD_COUNT);
|
|
||||||
|
|
||||||
public void given()
|
|
||||||
{
|
|
||||||
Mockito.when(resultSet.getNumberFound()).thenReturn(Long.valueOf(RECORD_COUNT));
|
|
||||||
Mockito.when(resultSet.hasMore()).thenReturn(false).thenReturn(false);
|
|
||||||
// create a hold
|
|
||||||
hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate());
|
|
||||||
|
|
||||||
// create a record folder that contains records
|
|
||||||
NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate());
|
|
||||||
recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate());
|
|
||||||
for (int i = 0; i < RECORD_COUNT; i++)
|
|
||||||
{
|
|
||||||
records.add(
|
|
||||||
recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT,
|
|
||||||
null, null));
|
|
||||||
}
|
|
||||||
Mockito.when(resultSet.getNodeRefs()).thenReturn(records).thenReturn(records)
|
|
||||||
.thenReturn(Collections.emptyList());
|
|
||||||
|
|
||||||
// assert current states
|
|
||||||
assertFalse(freezeService.isFrozen(recordFolder));
|
|
||||||
assertFalse(freezeService.hasFrozenChildren(recordFolder));
|
|
||||||
for (NodeRef record : records)
|
|
||||||
{
|
|
||||||
assertFalse(freezeService.isFrozen(record));
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional check for child held caching
|
|
||||||
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN));
|
|
||||||
assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void when()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = new BulkOperation(new Query("afts", "*", ""), "ADD");
|
|
||||||
// execute the bulk operation
|
|
||||||
holdBulkStatus = holdBulkService.execute(hold, bulkOperation);
|
|
||||||
await().atMost(10, SECONDS)
|
|
||||||
.until(() -> Objects.equals(
|
|
||||||
holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
Status.DONE.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void then()
|
|
||||||
{
|
|
||||||
holdBulkStatus = holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId());
|
|
||||||
assertNotNull(holdBulkStatus.startTime());
|
|
||||||
assertNotNull(holdBulkStatus.endTime());
|
|
||||||
assertEquals(RECORD_COUNT, holdBulkStatus.totalItems());
|
|
||||||
assertEquals(RECORD_COUNT, holdBulkStatus.processedItems());
|
|
||||||
assertEquals(0, holdBulkStatus.errorsCount());
|
|
||||||
assertEquals(holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
HoldBulkStatus.Status.DONE.getValue());
|
|
||||||
|
|
||||||
// record is held
|
|
||||||
for (NodeRef record : records)
|
|
||||||
{
|
|
||||||
assertTrue(freezeService.isFrozen(record));
|
|
||||||
}
|
|
||||||
|
|
||||||
// record folder has frozen children
|
|
||||||
assertFalse(freezeService.isFrozen(recordFolder));
|
|
||||||
assertTrue(freezeService.hasFrozenChildren(recordFolder));
|
|
||||||
|
|
||||||
// record folder is not held
|
|
||||||
assertFalse(holdService.getHeld(hold).contains(recordFolder));
|
|
||||||
assertFalse(holdService.heldBy(recordFolder, true).contains(hold));
|
|
||||||
|
|
||||||
for (NodeRef record : records)
|
|
||||||
{
|
|
||||||
// hold contains record
|
|
||||||
assertTrue(holdService.getHeld(hold).contains(record));
|
|
||||||
assertTrue(holdService.heldBy(record, true).contains(hold));
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional check for child held caching
|
|
||||||
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN));
|
|
||||||
assertEquals(RECORD_COUNT, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddRecordFolderToHoldViaBulk()
|
|
||||||
{
|
|
||||||
doBehaviourDrivenTest(new BehaviourDrivenTest()
|
|
||||||
{
|
|
||||||
private NodeRef hold;
|
|
||||||
private NodeRef recordFolder;
|
|
||||||
private final List<NodeRef> records = new ArrayList<>(RECORD_COUNT);
|
|
||||||
private HoldBulkStatus holdBulkStatus;
|
|
||||||
|
|
||||||
public void given()
|
|
||||||
{
|
|
||||||
Mockito.when(resultSet.getNumberFound()).thenReturn(1L);
|
|
||||||
Mockito.when(resultSet.hasMore()).thenReturn(false).thenReturn(false);
|
|
||||||
// create a hold
|
|
||||||
hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate());
|
|
||||||
|
|
||||||
// create a record folder that contains records
|
|
||||||
NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate());
|
|
||||||
recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate());
|
|
||||||
for (int i = 0; i < RECORD_COUNT; i++)
|
|
||||||
{
|
|
||||||
records.add(
|
|
||||||
recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT,
|
|
||||||
null, null));
|
|
||||||
}
|
|
||||||
Mockito.when(resultSet.getNodeRefs()).thenReturn(Collections.singletonList(recordFolder))
|
|
||||||
.thenReturn(Collections.singletonList(recordFolder)).thenReturn(Collections.emptyList());
|
|
||||||
|
|
||||||
// assert current states
|
|
||||||
assertFalse(freezeService.isFrozen(recordFolder));
|
|
||||||
assertFalse(freezeService.hasFrozenChildren(recordFolder));
|
|
||||||
for (NodeRef record : records)
|
|
||||||
{
|
|
||||||
assertFalse(freezeService.isFrozen(record));
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional check for child held caching
|
|
||||||
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN));
|
|
||||||
assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void when()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = new BulkOperation(new Query("afts", "*", ""), "ADD");
|
|
||||||
// execute the bulk operation
|
|
||||||
holdBulkStatus = holdBulkService.execute(hold, bulkOperation);
|
|
||||||
await().atMost(10, SECONDS)
|
|
||||||
.until(() -> Objects.equals(
|
|
||||||
holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
Status.DONE.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void then()
|
|
||||||
{
|
|
||||||
holdBulkStatus = holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId());
|
|
||||||
assertNotNull(holdBulkStatus.startTime());
|
|
||||||
assertNotNull(holdBulkStatus.endTime());
|
|
||||||
assertEquals(1, holdBulkStatus.totalItems());
|
|
||||||
assertEquals(1, holdBulkStatus.processedItems());
|
|
||||||
assertEquals(0, holdBulkStatus.errorsCount());
|
|
||||||
assertEquals(holdBulkMonitor.getBulkStatus(holdBulkStatus.bulkStatusId()).getStatus(),
|
|
||||||
HoldBulkStatus.Status.DONE.getValue());
|
|
||||||
|
|
||||||
for (NodeRef record : records)
|
|
||||||
{
|
|
||||||
// record is held
|
|
||||||
assertTrue(freezeService.isFrozen(record));
|
|
||||||
assertFalse(holdService.getHeld(hold).contains(record));
|
|
||||||
assertTrue(holdService.heldBy(record, true).contains(hold));
|
|
||||||
}
|
|
||||||
|
|
||||||
// record folder has frozen children
|
|
||||||
assertTrue(freezeService.isFrozen(recordFolder));
|
|
||||||
assertTrue(freezeService.hasFrozenChildren(recordFolder));
|
|
||||||
|
|
||||||
// hold contains record folder
|
|
||||||
assertTrue(holdService.getHeld(hold).contains(recordFolder));
|
|
||||||
assertTrue(holdService.heldBy(recordFolder, true).contains(hold));
|
|
||||||
|
|
||||||
// additional check for child held caching
|
|
||||||
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN));
|
|
||||||
assertEquals(RECORD_COUNT, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -180,7 +180,6 @@ public class CreateRecordTest extends BaseRMTestCase
|
|||||||
Set<Capability> capabilities = new HashSet<>(2);
|
Set<Capability> capabilities = new HashSet<>(2);
|
||||||
capabilities.add(capabilityService.getCapability("ViewRecords"));
|
capabilities.add(capabilityService.getCapability("ViewRecords"));
|
||||||
capabilities.add(capabilityService.getCapability("CreateRecords"));
|
capabilities.add(capabilityService.getCapability("CreateRecords"));
|
||||||
capabilities.add(capabilityService.getCapability("CreateModifyDestroyFileplanMetadata"));
|
|
||||||
filePlanRoleService.createRole(filePlan, roleName, roleName, capabilities);
|
filePlanRoleService.createRole(filePlan, roleName, roleName, capabilities);
|
||||||
|
|
||||||
|
|
||||||
@@ -190,7 +189,6 @@ public class CreateRecordTest extends BaseRMTestCase
|
|||||||
|
|
||||||
//give read and file permission to user on unfiled records container
|
//give read and file permission to user on unfiled records container
|
||||||
filePlanPermissionService.setPermission(unfiledContainer , user, RMPermissionModel.FILING);
|
filePlanPermissionService.setPermission(unfiledContainer , user, RMPermissionModel.FILING);
|
||||||
filePlanPermissionService.setPermission(unfiledContainer , user, RMPermissionModel.CREATE_MODIFY_DESTROY_FILEPLAN_METADATA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void when()
|
public void when()
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorReg
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
|
||||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
@@ -439,12 +437,19 @@ public class DispositionServiceImplTest extends BaseRMTestCase
|
|||||||
|
|
||||||
// Check the disposition schedule
|
// Check the disposition schedule
|
||||||
checkDispositionSchedule(ds, "testCreateDispositionSchedule", "testCreateDispositionSchedule", false);
|
checkDispositionSchedule(ds, "testCreateDispositionSchedule", "testCreateDispositionSchedule", false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Failure: create disposition schedule on container with existing disposition schedule
|
// Failure: create disposition schedule on container with existing disposition schedule
|
||||||
Assert.assertThrows(ConstraintViolatedException.class,
|
doTestInTransaction(new FailureTest
|
||||||
() -> {
|
(
|
||||||
utils.createBasicDispositionSchedule(rmContainer);
|
"Can not create a disposition schedule on a container with an existing disposition schedule"
|
||||||
});
|
)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
utils.createBasicDispositionSchedule(rmContainer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -487,12 +492,19 @@ public class DispositionServiceImplTest extends BaseRMTestCase
|
|||||||
// Check the disposition schedule
|
// Check the disposition schedule
|
||||||
checkDispositionSchedule(testA, "testA", "testA", false);
|
checkDispositionSchedule(testA, "testA", "testA", false);
|
||||||
checkDispositionSchedule(testB, "testB", "testB", false);
|
checkDispositionSchedule(testB, "testB", "testB", false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Failure: create disposition schedule on container with existing disposition schedule
|
// Failure: create disposition schedule on container with existing disposition schedule
|
||||||
Assert.assertThrows(ConstraintViolatedException.class,
|
doTestInTransaction(new FailureTest
|
||||||
() -> {
|
(
|
||||||
utils.createBasicDispositionSchedule(rmContainer);
|
"Can not create a disposition schedule on container with an existing disposition schedule"
|
||||||
});
|
)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
utils.createBasicDispositionSchedule(mhContainer11);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# Version label
|
# Version label
|
||||||
version.major=23
|
version.major=23
|
||||||
version.minor=4
|
version.minor=3
|
||||||
version.revision=0
|
version.revision=0
|
||||||
version.label=
|
version.label=
|
||||||
|
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.bulk;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.DefaultHoldBulkMonitor;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkProcessDetails;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatus;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.bulk.hold.HoldBulkStatusAndProcessDetails;
|
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.util.Pair;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
public class DefaultHoldBulkMonitorUnitTest
|
|
||||||
{
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private SimpleCache<String, HoldBulkStatus> holdProgressCache;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private SimpleCache<Pair<String, String>, HoldBulkProcessDetails> holdProcessRegistry;
|
|
||||||
|
|
||||||
private DefaultHoldBulkMonitor holdBulkMonitor;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp()
|
|
||||||
{
|
|
||||||
MockitoAnnotations.openMocks(this);
|
|
||||||
holdBulkMonitor = new DefaultHoldBulkMonitor();
|
|
||||||
holdBulkMonitor.setHoldProgressCache(holdProgressCache);
|
|
||||||
holdBulkMonitor.setHoldProcessRegistry(holdProcessRegistry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateBulkStatus()
|
|
||||||
{
|
|
||||||
HoldBulkStatus status = new HoldBulkStatus("bulkStatusId", null, null, 0L, 0L, 0L, null, false, null);
|
|
||||||
|
|
||||||
holdBulkMonitor.updateBulkStatus(status);
|
|
||||||
|
|
||||||
Mockito.verify(holdProgressCache).put("bulkStatusId", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRegisterProcess()
|
|
||||||
{
|
|
||||||
NodeRef holdRef = new NodeRef("workspace://SpacesStore/holdId");
|
|
||||||
String processId = "processId";
|
|
||||||
when(holdProcessRegistry.get(new Pair<>(holdRef.getId(), processId))).thenReturn(null);
|
|
||||||
|
|
||||||
holdBulkMonitor.registerProcess(holdRef, processId, null);
|
|
||||||
|
|
||||||
Mockito.verify(holdProcessRegistry)
|
|
||||||
.put(new Pair<>(holdRef.getId(), processId), new HoldBulkProcessDetails(processId, null, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusesWithProcessDetailsReturnsEmptyListWhenNoProcessesWithProcessDetails()
|
|
||||||
{
|
|
||||||
when(holdProcessRegistry.getKeys()).thenReturn(Collections.emptyList());
|
|
||||||
assertEquals(Collections.emptyList(), holdBulkMonitor.getBulkStatusesWithProcessDetails("holdId"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatus()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = mock(BulkOperation.class);
|
|
||||||
HoldBulkStatus status1 = new HoldBulkStatus("process1", new Date(1000), new Date(2000), 0L, 0L, 0L, null, false,
|
|
||||||
null);
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process1"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process1", null, bulkOperation));
|
|
||||||
when(holdProgressCache.get("process1")).thenReturn(status1);
|
|
||||||
|
|
||||||
assertEquals(new HoldBulkStatusAndProcessDetails(status1,
|
|
||||||
new HoldBulkProcessDetails(status1.bulkStatusId(), null, bulkOperation)),
|
|
||||||
holdBulkMonitor.getBulkStatusWithProcessDetails("holdId", "process1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetNonExistingBulkStatus()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = mock(BulkOperation.class);
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process1"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process1", null, bulkOperation));
|
|
||||||
when(holdProgressCache.get("process1")).thenReturn(null);
|
|
||||||
|
|
||||||
assertNull(holdBulkMonitor.getBulkStatusWithProcessDetails("holdId", "process1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetBulkStatusesForHoldReturnsSortedStatusesWithProcessDetails()
|
|
||||||
{
|
|
||||||
BulkOperation bulkOperation = mock(BulkOperation.class);
|
|
||||||
HoldBulkStatus status1 = new HoldBulkStatus("process1", new Date(1000), new Date(2000), 0L, 0L, 0L, null, false,
|
|
||||||
null);
|
|
||||||
HoldBulkStatus status2 = new HoldBulkStatus("process2", new Date(3000), null, 0L, 0L, 0L, null, false, null);
|
|
||||||
HoldBulkStatus status3 = new HoldBulkStatus("process3", new Date(4000), null, 0L, 0L, 0L, null, false, null);
|
|
||||||
HoldBulkStatus status4 = new HoldBulkStatus("process4", new Date(500), new Date(800), 0L, 0L, 0L, null, false,
|
|
||||||
null);
|
|
||||||
HoldBulkStatus status5 = new HoldBulkStatus("process5", null, null, 0L, 0L, 0L, null, false, null);
|
|
||||||
|
|
||||||
when(holdProcessRegistry.getKeys()).thenReturn(
|
|
||||||
Arrays.asList(new Pair<>("holdId", "process1"), new Pair<>("holdId", "process2"),
|
|
||||||
new Pair<>("holdId", "process3"), new Pair<>("holdId", "process4"), new Pair<>("holdId", "process5"))
|
|
||||||
);
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process1"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process1", null, bulkOperation));
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process2"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process2", null, bulkOperation));
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process3"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process3", null, bulkOperation));
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process4"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process4", null, bulkOperation));
|
|
||||||
when(holdProcessRegistry.get(new Pair<>("holdId", "process5"))).thenReturn(
|
|
||||||
new HoldBulkProcessDetails("process5", null, bulkOperation));
|
|
||||||
when(holdProgressCache.get("process1")).thenReturn(status1);
|
|
||||||
when(holdProgressCache.get("process2")).thenReturn(status2);
|
|
||||||
when(holdProgressCache.get("process3")).thenReturn(status3);
|
|
||||||
when(holdProgressCache.get("process4")).thenReturn(status4);
|
|
||||||
when(holdProgressCache.get("process5")).thenReturn(status5);
|
|
||||||
|
|
||||||
assertEquals(Arrays.asList(status5, status3, status2, status1, status4).stream().map(
|
|
||||||
status -> new HoldBulkStatusAndProcessDetails(status,
|
|
||||||
new HoldBulkProcessDetails(status.bulkStatusId(), null, bulkOperation))).toList(),
|
|
||||||
holdBulkMonitor.getBulkStatusesWithProcessDetails("holdId"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%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 <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.disposition;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
|
||||||
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
|
|
||||||
import org.alfresco.rm.rest.api.model.RetentionSchedule;
|
|
||||||
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.Period;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retention schedule model unit test
|
|
||||||
*/
|
|
||||||
public class RetentionScheduleModelUnitTest extends BaseUnitTest
|
|
||||||
{
|
|
||||||
private static final String AUTHORITY = "authority";
|
|
||||||
private static final String INSTRUCTIONS = "instructions";
|
|
||||||
private static final String RETAIN_STEP = "retain";
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private ApiNodesModelFactory apiNodesModelFactory;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
DispositionSchedule dispositionSchedule;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
DispositionActionDefinition dispositionActionDefinition;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mapRetentionScheduleDataTest()
|
|
||||||
{
|
|
||||||
// Mock data
|
|
||||||
NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true);
|
|
||||||
ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record);
|
|
||||||
when(dispositionSchedule.getDispositionAuthority()).thenReturn(AUTHORITY);
|
|
||||||
when(dispositionSchedule.getDispositionInstructions()).thenReturn(INSTRUCTIONS);
|
|
||||||
when(dispositionSchedule.getNodeRef()).thenReturn(nodeRef);
|
|
||||||
when(dispositionSchedule.isRecordLevelDisposition()).thenReturn(false);
|
|
||||||
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
|
|
||||||
// Call the method
|
|
||||||
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
|
|
||||||
public void mapRetentionScheduleActionDefDataTest()
|
|
||||||
{
|
|
||||||
// Mock data
|
|
||||||
NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true);
|
|
||||||
String period = "month|10";
|
|
||||||
ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record);
|
|
||||||
when(dispositionActionDefinition.getNodeRef()).thenReturn(nodeRef);
|
|
||||||
when(dispositionActionDefinition.getName()).thenReturn(RETAIN_STEP);
|
|
||||||
when(dispositionActionDefinition.getDescription()).thenReturn("Description");
|
|
||||||
when(dispositionActionDefinition.getIndex()).thenReturn(1);
|
|
||||||
when(dispositionActionDefinition.getGhostOnDestroy()).thenReturn("ghost");
|
|
||||||
when(dispositionActionDefinition.getPeriod()).thenReturn(new Period(period));
|
|
||||||
when(dispositionActionDefinition.getLocation()).thenReturn("location");
|
|
||||||
when(dispositionActionDefinition.getId()).thenReturn(nodeRef.getId());
|
|
||||||
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
|
|
||||||
// Call the method
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -93,15 +93,15 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
|
|||||||
verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity);
|
verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity);
|
||||||
|
|
||||||
assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue());
|
assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue());
|
||||||
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringLower());
|
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringEndLower());
|
||||||
assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc());
|
assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc());
|
||||||
|
|
||||||
assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue());
|
assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue());
|
||||||
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringLower());
|
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringEndLower());
|
||||||
assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc());
|
assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc());
|
||||||
|
|
||||||
assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue());
|
assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue());
|
||||||
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringLower());
|
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringEndLower());
|
||||||
assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc());
|
assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ tags:
|
|||||||
description: Retrieve and manage unfiled record folders
|
description: Retrieve and manage unfiled record folders
|
||||||
- name: holds
|
- name: holds
|
||||||
description: Retrieve and manage holds
|
description: Retrieve and manage holds
|
||||||
- name: retention-schedules
|
|
||||||
description: Perform retention schedule specific operations
|
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
## GS sites
|
## GS sites
|
||||||
@@ -2316,145 +2314,6 @@ paths:
|
|||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Error'
|
||||||
'/holds/{holdId}/bulk-statuses':
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- holds
|
|
||||||
operationId: listBulkStatuses
|
|
||||||
summary: Get bulk statuses
|
|
||||||
description: |
|
|
||||||
Gets bulk statuses for hold with id **holdId**.
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/holdIdParam'
|
|
||||||
- $ref: '#/parameters/skipCountParam'
|
|
||||||
- $ref: '#/parameters/maxItemsParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/HoldBulkStatusPaging'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: **holdId** is not a valid format
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to read **holdId**
|
|
||||||
'404':
|
|
||||||
description: "**holdId** does not exist"
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
'/holds/{holdId}/bulk-statuses/{bulkStatusId}':
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- holds
|
|
||||||
operationId: getBulkStatus
|
|
||||||
summary: Get a bulk status
|
|
||||||
description: |
|
|
||||||
Gets a bulk status specified by **bulkStatusId** for **holdId**.
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/holdIdParam'
|
|
||||||
- $ref: '#/parameters/bulkStatusId'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/HoldBulkStatus'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: **holdId** or **bulkStatusId** is not a valid format
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to read **holdId**
|
|
||||||
'404':
|
|
||||||
description: "**holdId** or **bulkStatusId** does not exist"
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
'/holds/{holdId}/bulk-statuses/{bulkStatusId}/cancel':
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- holds
|
|
||||||
operationId: cancelBulkStatus
|
|
||||||
summary: Cancel the bulk operation
|
|
||||||
description: |
|
|
||||||
Cancels the bulk operation specified by **bulkStatusId** for **holdId**.
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/holdIdParam'
|
|
||||||
- $ref: '#/parameters/bulkStatusId'
|
|
||||||
- in: body
|
|
||||||
name: cancelReason
|
|
||||||
description: Cancel reason.
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/BulkBodyCancel'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful response
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: **holdId** or **bulkStatusId** is not a valid format
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to cancel the bulk process for **holdId** and **bulkStatusId**
|
|
||||||
'404':
|
|
||||||
description: "**holdId** or **bulkStatusId** does not exist"
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
'/holds/{holdId}/bulk':
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- holds
|
|
||||||
operationId: startHoldBulkProcess
|
|
||||||
summary: Start the hold bulk process
|
|
||||||
description: |
|
|
||||||
Start the asynchronous bulk process for a hold with id **holdId** based on search query results.
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
For example, the following JSON body starts the bulk process to add search query results
|
|
||||||
as children of a hold.
|
|
||||||
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"query": "SITE:swsdp and TYPE:content",
|
|
||||||
"language": "afts"
|
|
||||||
},
|
|
||||||
"op": "ADD"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/holdIdParam'
|
|
||||||
- in: body
|
|
||||||
name: holdBulkOperation
|
|
||||||
description: Bulk operation.
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/HoldBulkOperation'
|
|
||||||
responses:
|
|
||||||
'202':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/HoldBulkOperationEntry'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: **holdId** is not a valid format or **HoldBulkOperation** is not valid
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to start the bulk process for **holdId**
|
|
||||||
'404':
|
|
||||||
description: "**holdId** does not exist"
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
'/holds/{holdId}/delete':
|
'/holds/{holdId}/delete':
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@@ -2636,196 +2495,7 @@ paths:
|
|||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Error'
|
||||||
##retention-schedule
|
|
||||||
'/record-categories/{recordCategoryId}/retention-schedules':
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- retention-schedules
|
|
||||||
summary: Create a retention schedule
|
|
||||||
description: |
|
|
||||||
Create a retention schedule.
|
|
||||||
|
|
||||||
For example, using the following JSON body will create a retention schedule:
|
|
||||||
```JSON
|
|
||||||
{
|
|
||||||
"authority": "Retention Authority",
|
|
||||||
"instructions": "Retention Instructions",
|
|
||||||
"isRecordLevel": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
operationId: createRetentionSchedule
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/recordCategoryIdParam'
|
|
||||||
- in: body
|
|
||||||
name: retentionNodeBodyCreate
|
|
||||||
description: |
|
|
||||||
The retention schedule information to create.
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionNodeBodyCreate'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionScheduleResponse'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: value of recordCategoryId is invalid
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to create retention schedule
|
|
||||||
'404':
|
|
||||||
description: recordCategoryId does not exist
|
|
||||||
'409':
|
|
||||||
description: Retention schedule already exist for the given recordCategoryId
|
|
||||||
'422':
|
|
||||||
description: Record level retention schedule cannot be created for a record category having folder associated
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- retention-schedules
|
|
||||||
summary: Get the retention schedule for a record category
|
|
||||||
description: |
|
|
||||||
Get the retention schedule for a record category.
|
|
||||||
|
|
||||||
You can use the **include** parameter (include=actions) to return additional information.
|
|
||||||
|
|
||||||
operationId: getRetentionScheduleList
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/recordCategoryIdParam'
|
|
||||||
- $ref: '#/parameters/retentionScheduleIncludeParam'
|
|
||||||
- $ref: '#/parameters/skipCountParam'
|
|
||||||
- $ref: '#/parameters/maxItemsParam'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionScheduleResponseList'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: value of recordCategoryId is invalid
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to get retention schedule
|
|
||||||
'404':
|
|
||||||
description: recordCategoryId does not exist
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
'/retention-schedules/{retentionScheduleId}/retention-steps':
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- retention-schedules
|
|
||||||
summary: Create a step in the retention schedule
|
|
||||||
description: |
|
|
||||||
Create a step in the retention schedule.
|
|
||||||
|
|
||||||
Order of steps:
|
|
||||||
* "**retain**" or "**cutoff**" should be first
|
|
||||||
* can't use "**cutoff**" after "**transfer**" or "**accession**"
|
|
||||||
* only the "**transfer**" action is allowed multiple times
|
|
||||||
* no steps are allowed after "**destroy**"
|
|
||||||
|
|
||||||
For example, the following JSON body will create a step in the retention schedule:
|
|
||||||
```JSON
|
|
||||||
{
|
|
||||||
"name":"accession",
|
|
||||||
"description":"Step Description",
|
|
||||||
"periodAmount": 2,
|
|
||||||
"period":"month",
|
|
||||||
"periodProperty":"cm:created",
|
|
||||||
"combineRetentionStepConditions": false,
|
|
||||||
"events":["versioned"],
|
|
||||||
"eligibleOnFirstCompleteEvent": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
operationId: createRetentionScheduleAction
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/retentionScheduleIdParam'
|
|
||||||
- in: body
|
|
||||||
name: nodeBodyCreate
|
|
||||||
description: |
|
|
||||||
The retention schedule steps information to create.
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionStepNodeBodyCreate'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionStepNodeBodyResponse'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: value of retentionScheduleId is invalid
|
|
||||||
Invalid parameter (e.g. event, period, periodProperty)
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to create retention schedule step
|
|
||||||
'404':
|
|
||||||
description: retentionScheduleId does not exist
|
|
||||||
'409':
|
|
||||||
description: |
|
|
||||||
* Invalid Step - Can't use Cut Off after Transfer or Accession
|
|
||||||
* Invalid Step - Destroy action already completed. Can't do any other Action
|
|
||||||
* Invalid Step - This step already exists. You can’t create this step [Transfer action is allowed many times]
|
|
||||||
'422':
|
|
||||||
description: Cut Off or Retain should be the first step
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- retention-schedules
|
|
||||||
summary: Get the list of steps in the retention schedule
|
|
||||||
description: |
|
|
||||||
Get the list of steps in the retention schedule.
|
|
||||||
operationId: getRetentionScheduleActionList
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/retentionScheduleIdParam'
|
|
||||||
- $ref: '#/parameters/skipCountParam'
|
|
||||||
- $ref: '#/parameters/maxItemsParam'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful response
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/RetentionStepsNodeBodyResponse'
|
|
||||||
'400':
|
|
||||||
description: |
|
|
||||||
Invalid parameter: value of retentionScheduleId is invalid
|
|
||||||
'401':
|
|
||||||
description: Authentication failed
|
|
||||||
'403':
|
|
||||||
description: Current user does not have permission to get retention schedule steps
|
|
||||||
'404':
|
|
||||||
description: retentionScheduleId does not exist
|
|
||||||
default:
|
|
||||||
description: Unexpected error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Error'
|
|
||||||
parameters:
|
parameters:
|
||||||
## File plans
|
## File plans
|
||||||
filePlanEntryIncludeParam:
|
filePlanEntryIncludeParam:
|
||||||
@@ -3192,12 +2862,6 @@ parameters:
|
|||||||
description: The identifier of a child of a hold.
|
description: The identifier of a child of a hold.
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
bulkStatusId:
|
|
||||||
name: bulkStatusId
|
|
||||||
in: path
|
|
||||||
description: The identifier of a bulk process.
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
## Record
|
## Record
|
||||||
recordIdParam:
|
recordIdParam:
|
||||||
name: recordId
|
name: recordId
|
||||||
@@ -3291,22 +2955,6 @@ parameters:
|
|||||||
If true, then a name clash will cause an attempt to auto rename by finding a unique name using an integer suffix.
|
If true, then a name clash will cause an attempt to auto rename by finding a unique name using an integer suffix.
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
## RetentionSchedule
|
|
||||||
retentionScheduleIdParam:
|
|
||||||
name: retentionScheduleId
|
|
||||||
in: path
|
|
||||||
description:
|
|
||||||
The identifier of a retention schedule.
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
retentionScheduleIncludeParam:
|
|
||||||
name: include
|
|
||||||
in: query
|
|
||||||
description: |
|
|
||||||
Returns additional information about the retention schedule actions. Any optional field from the response model can be requested. For example:
|
|
||||||
* actions
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
definitions:
|
definitions:
|
||||||
FilePlanComponentBodyUpdate:
|
FilePlanComponentBodyUpdate:
|
||||||
type: object
|
type: object
|
||||||
@@ -4370,323 +4018,6 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
reason:
|
reason:
|
||||||
type: string
|
type: string
|
||||||
SearchRequestQuery:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- query
|
|
||||||
properties:
|
|
||||||
language:
|
|
||||||
description: The query language in which the query is written.
|
|
||||||
type: string
|
|
||||||
default: afts
|
|
||||||
enum:
|
|
||||||
- afts
|
|
||||||
- lucene
|
|
||||||
- cmis
|
|
||||||
userQuery:
|
|
||||||
description: The search request typed in by the user
|
|
||||||
type: string
|
|
||||||
query:
|
|
||||||
description: The query which may have been generated in some way from the userQuery
|
|
||||||
type: string
|
|
||||||
HoldBulkOperation:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
query:
|
|
||||||
$ref: '#/definitions/SearchRequestQuery'
|
|
||||||
op:
|
|
||||||
description: The operation type.
|
|
||||||
type: string
|
|
||||||
default: ADD
|
|
||||||
enum:
|
|
||||||
- ADD
|
|
||||||
HoldBulkOperationEntry:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
bulkStatusId:
|
|
||||||
type: string
|
|
||||||
totalItems:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
BulkBodyCancel:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
reason:
|
|
||||||
type: string
|
|
||||||
HoldBulkStatus:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
bulkStatusId:
|
|
||||||
type: string
|
|
||||||
startTime:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
endTime:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
processedItems:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
errorsCount:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
totalItems:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
lastError:
|
|
||||||
type: string
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- PENDING
|
|
||||||
- IN PROGRESS
|
|
||||||
- DONE
|
|
||||||
- CANCELLED
|
|
||||||
cancellationReason:
|
|
||||||
type: string
|
|
||||||
holdBulkOperation:
|
|
||||||
$ref: '#/definitions/HoldBulkOperation'
|
|
||||||
HoldBulkStatusEntry:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- entry
|
|
||||||
properties:
|
|
||||||
entry:
|
|
||||||
$ref: '#/definitions/HoldBulkStatus'
|
|
||||||
HoldBulkStatusPaging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
list:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
pagination:
|
|
||||||
$ref: '#/definitions/Pagination'
|
|
||||||
entries:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/HoldBulkStatusEntry'
|
|
||||||
RetentionNodeBodyCreate:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
authority:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Authority name for the retention schedule.
|
|
||||||
instructions:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Required instructions for the retention schedule.
|
|
||||||
isRecordLevel:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: |
|
|
||||||
This field is used to specify whether the retention schedule needs to be applied in the folder level or record level.
|
|
||||||
True will cause the the retention schedule to apply to records and false will cause the retention schedule to apply to record folders.
|
|
||||||
This cannot be changed once items start being managed by the retention schedule.
|
|
||||||
RetentionScheduleResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
parentId:
|
|
||||||
type: string
|
|
||||||
authority:
|
|
||||||
type: string
|
|
||||||
instructions:
|
|
||||||
type: string
|
|
||||||
isRecordLevel:
|
|
||||||
type: boolean
|
|
||||||
unpublishedUpdates:
|
|
||||||
type: boolean
|
|
||||||
RetentionScheduleResponseList:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
list:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
pagination:
|
|
||||||
$ref: '#/definitions/Pagination'
|
|
||||||
entries:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/FullRetentionScheduleResponse'
|
|
||||||
FullRetentionScheduleResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
parentId:
|
|
||||||
type: string
|
|
||||||
authority:
|
|
||||||
type: string
|
|
||||||
instructions:
|
|
||||||
type: string
|
|
||||||
isRecordLevel:
|
|
||||||
type: boolean
|
|
||||||
unpublishedUpdates:
|
|
||||||
type: boolean
|
|
||||||
actions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/Actions'
|
|
||||||
Actions:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
periodAmount:
|
|
||||||
type: integer
|
|
||||||
period:
|
|
||||||
type: string
|
|
||||||
periodProperty:
|
|
||||||
type: string
|
|
||||||
combineRetentionStepConditions:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
eligibleOnFirstCompleteEvent:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
retainRecordMetadataAfterDestruction:
|
|
||||||
type: boolean
|
|
||||||
location:
|
|
||||||
type: string
|
|
||||||
events:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
index:
|
|
||||||
type: integer
|
|
||||||
RetentionStepNodeBodyCreate:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- description
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The valid names are:
|
|
||||||
* retain
|
|
||||||
* cutoff
|
|
||||||
* accession
|
|
||||||
* transfer
|
|
||||||
* destroyContent
|
|
||||||
* destroyNode
|
|
||||||
|
|
||||||
destroyNode step can be used to destroy content along with record metadata.
|
|
||||||
In case, record metadata needs to be retained, then destroyContent step should be used.
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
This property is used to provide the step description.
|
|
||||||
periodAmount:
|
|
||||||
type: integer
|
|
||||||
description: |
|
|
||||||
This property is only applicable for the following period values.
|
|
||||||
* day
|
|
||||||
* month
|
|
||||||
* quarter
|
|
||||||
* week
|
|
||||||
* duration
|
|
||||||
* year
|
|
||||||
period:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Valid values for the period.
|
|
||||||
* day = Day
|
|
||||||
* fmend = End Of Financial Month
|
|
||||||
* fqend = End Of Financial Quarter
|
|
||||||
* fyend = End Of Financial Year
|
|
||||||
* immediately = Immediately
|
|
||||||
* monthend = End Of Month
|
|
||||||
* quarterend = End Of Quarter
|
|
||||||
* yearend = End Of Year
|
|
||||||
* month = Month
|
|
||||||
* none = None
|
|
||||||
* quarter = Quarter
|
|
||||||
* week = Week
|
|
||||||
* duration = XML Duration
|
|
||||||
* year = Year
|
|
||||||
|
|
||||||
If you provide XML Duration for the period value, you need to specify a time interval using XML syntax.
|
|
||||||
The syntax should take the form of:
|
|
||||||
P = Period (required)
|
|
||||||
nY = Number of years
|
|
||||||
nM = Number of months
|
|
||||||
nD = Number of days
|
|
||||||
T = Start time of a time section (required if specifying hours, minutes, or seconds)
|
|
||||||
nH = Number of hours
|
|
||||||
nM = Number of minutes
|
|
||||||
nS = Number of seconds
|
|
||||||
For example, ‘P2M10D’ represents two months and ten days.
|
|
||||||
periodProperty:
|
|
||||||
type: string
|
|
||||||
default: cm:created
|
|
||||||
description: |
|
|
||||||
Valid values for the periodProperty property
|
|
||||||
* cm:created = Created Date (defult value)
|
|
||||||
* rma:cutOffDate = Cut Off Date
|
|
||||||
* rma:dispositionAsOf = Retention Action
|
|
||||||
combineRetentionStepConditions:
|
|
||||||
type: boolean
|
|
||||||
description: |
|
|
||||||
This property is only valid for **accession** step.
|
|
||||||
This is used to specify whether to combine the period condition and events for the step execution or only consider one of them.
|
|
||||||
For example:
|
|
||||||
**periodCondition**: After a period of 2 months
|
|
||||||
**eventsCondition**: Case Closed event
|
|
||||||
This flag can be used to consider only (**periodCondition** or **eventsCondition**) or both of them at once.
|
|
||||||
events:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Valid values for the events property
|
|
||||||
* case_closed = Case Closed
|
|
||||||
* abolished = Abolished
|
|
||||||
* re_designated = Redesignated
|
|
||||||
* no_longer_needed = No Longer Needed
|
|
||||||
* superseded = Superseded
|
|
||||||
* versioned = Versioned
|
|
||||||
* study_complete = Study Complete
|
|
||||||
* training_complete = Training Complete
|
|
||||||
* related_record_trasfered_inactive_storage = Related Record Transferred to Inactive Storage
|
|
||||||
* obsolete = Obsolete
|
|
||||||
* all_allowances_granted_are_terminated = All Allowances Granted are Terminated
|
|
||||||
* WGI_action_complete = WGI Action Complete
|
|
||||||
* separation = Separation
|
|
||||||
* case_complete = Case Complete
|
|
||||||
* declassification_review = Declassification Review
|
|
||||||
eligibleOnFirstCompleteEvent:
|
|
||||||
type: boolean
|
|
||||||
description: |
|
|
||||||
* false = When all events have happened
|
|
||||||
* true = Whichever event is earlier
|
|
||||||
location:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
This property is only valid for transfer step
|
|
||||||
RetentionStepNodeBodyResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
actions:
|
|
||||||
$ref: '#/definitions/Actions'
|
|
||||||
RetentionStepsNodeBodyResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
list:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
pagination:
|
|
||||||
$ref: '#/definitions/Pagination'
|
|
||||||
entries:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/RetentionStepNodeBodyResponse'
|
|
||||||
##
|
##
|
||||||
RequestBodyFile:
|
RequestBodyFile:
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
10
core/pom.xml
10
core/pom.xml
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -47,11 +47,11 @@
|
|||||||
<artifactId>commons-math3</artifactId>
|
<artifactId>commons-math3</artifactId>
|
||||||
<version>3.6.1</version>
|
<version>3.6.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.uuid/java-uuid-generator -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.uuid</groupId>
|
<groupId>org.safehaus.jug</groupId>
|
||||||
<artifactId>java-uuid-generator</artifactId>
|
<artifactId>jug</artifactId>
|
||||||
<version>5.1.0</version>
|
<version>2.0.0</version>
|
||||||
|
<classifier>asl</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ package org.alfresco.util;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.fasterxml.uuid.Generators;
|
import org.safehaus.uuid.UUIDGenerator;
|
||||||
import org.alfresco.api.AlfrescoPublicApi;
|
import org.alfresco.api.AlfrescoPublicApi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,7 +69,7 @@ public final class GUID
|
|||||||
public static String generate()
|
public static String generate()
|
||||||
{
|
{
|
||||||
int randomInt = RANDOM.nextInt(SECURE_RANDOM_POOL_MAX_ITEMS);
|
int randomInt = RANDOM.nextInt(SECURE_RANDOM_POOL_MAX_ITEMS);
|
||||||
return Generators.randomBasedGenerator(SECURE_RANDOM_POOL[randomInt]).generate().toString();
|
return UUIDGenerator.getInstance().generateRandomBasedUUID(SECURE_RANDOM_POOL[randomInt]).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// == Not sure if we need this functionality again (derekh) ==
|
// == Not sure if we need this functionality again (derekh) ==
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2024 Alfresco Software Limited.
|
* Copyright (C) 2005-2023 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -67,14 +67,4 @@ public interface TransactionListener
|
|||||||
* be used only for cleaning up resources after a rollback has occurred.
|
* be used only for cleaning up resources after a rollback has occurred.
|
||||||
*/
|
*/
|
||||||
void afterRollback();
|
void afterRollback();
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows to provide a custom listener's order.
|
|
||||||
* See {@link org.alfresco.repo.transaction.AlfrescoTransactionSupport#COMMIT_ORDER_NORMAL}
|
|
||||||
* @return custom order or null for the default one
|
|
||||||
*/
|
|
||||||
default Integer getCustomOrder()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import com.fasterxml.uuid.Generators;
|
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.service.cmr.repository.datatype.Duration;
|
import org.alfresco.service.cmr.repository.datatype.Duration;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.safehaus.uuid.UUIDGenerator;
|
||||||
import org.alfresco.util.ParameterCheck;
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -497,7 +497,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.validDuration = validDuration;
|
this.validDuration = validDuration;
|
||||||
this.testDuration = validDuration.divide(2);
|
this.testDuration = validDuration.divide(2);
|
||||||
final String guid = Generators.randomBasedGenerator().generate().toString();
|
final String guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
|
||||||
|
|
||||||
this.ticketId = computeTicketId(expires, expiryDate, userName, guid);
|
this.ticketId = computeTicketId(expires, expiryDate, userName, guid);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Data model classes
|
* Alfresco Data model classes
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -78,28 +78,6 @@ public interface PermissionService
|
|||||||
*/
|
*/
|
||||||
public static final String GUEST_AUTHORITY = "ROLE_GUEST";
|
public static final String GUEST_AUTHORITY = "ROLE_GUEST";
|
||||||
|
|
||||||
/**
|
|
||||||
* The dynamic authority for the Admin service account.
|
|
||||||
*/
|
|
||||||
String ADMIN_SVC_AUTHORITY = "ROLE_ADMIN_SERVICE_ACCOUNT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The dynamic authority for the Collaborator service account.
|
|
||||||
*/
|
|
||||||
String COLLABORATOR_SVC_AUTHORITY = "ROLE_COLLABORATOR_SERVICE_ACCOUNT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The dynamic authority for the Editor service account.
|
|
||||||
*/
|
|
||||||
String EDITOR_SVC_AUTHORITY = "ROLE_EDITOR_SERVICE_ACCOUNT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A convenient set of service account authorities to simplify checks
|
|
||||||
* for whether a given authority is a service account authority or not.
|
|
||||||
*/
|
|
||||||
Set<String> SVC_AUTHORITIES_SET = Set.of(ADMIN_SVC_AUTHORITY, COLLABORATOR_SVC_AUTHORITY,
|
|
||||||
EDITOR_SVC_AUTHORITY);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The permission for all - not defined in the model. Repsected in the code.
|
* The permission for all - not defined in the model. Repsected in the code.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<include>org.alfresco:alfresco-core</include>
|
<include>org.alfresco:alfresco-core</include>
|
||||||
<include>org.alfresco:alfresco-repository</include>
|
<include>org.alfresco:alfresco-repository</include>
|
||||||
<include>org.apache.commons:commons-compress</include>
|
<include>org.apache.commons:commons-compress</include>
|
||||||
<include>com.fasterxml.uuid:java-uuid-generator</include>
|
<include>org.safehaus.jug:jug</include>
|
||||||
<include>org.alfresco.surf:spring-surf-core</include>
|
<include>org.alfresco.surf:spring-surf-core</include>
|
||||||
<include>org.tukaani:xz</include>
|
<include>org.tukaani:xz</include>
|
||||||
<include>org.apache.maven:maven-artifact</include>
|
<include>org.apache.maven:maven-artifact</include>
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.module.tool;
|
package org.alfresco.repo.module.tool;
|
||||||
|
|
||||||
import com.fasterxml.uuid.Generators;
|
|
||||||
import de.schlichtherle.truezip.file.*;
|
import de.schlichtherle.truezip.file.*;
|
||||||
import de.schlichtherle.truezip.fs.FsSyncException;
|
import de.schlichtherle.truezip.fs.FsSyncException;
|
||||||
import de.schlichtherle.truezip.fs.archive.zip.JarDriver;
|
import de.schlichtherle.truezip.fs.archive.zip.JarDriver;
|
||||||
@@ -35,6 +34,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
|||||||
import org.alfresco.repo.module.ModuleVersionNumber;
|
import org.alfresco.repo.module.ModuleVersionNumber;
|
||||||
import org.alfresco.service.cmr.module.ModuleDetails;
|
import org.alfresco.service.cmr.module.ModuleDetails;
|
||||||
import org.alfresco.service.cmr.module.ModuleInstallState;
|
import org.alfresco.service.cmr.module.ModuleInstallState;
|
||||||
|
import org.safehaus.uuid.UUIDGenerator;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -916,7 +916,7 @@ public class ModuleManagementTool implements LogOutput
|
|||||||
*/
|
*/
|
||||||
private static String generateGuid()
|
private static String generateGuid()
|
||||||
{
|
{
|
||||||
return Generators.timeBasedGenerator().generate().toString();
|
return UUIDGenerator.getInstance().generateTimeBasedUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
# Fetch image based on Tomcat 9.0, Java 17 and Rocky Linux 8
|
||||||
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
|
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
|
||||||
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux9@sha256:395664f9d9be0c9f73d3b722a58fd559ee7231609b263dfe19502617652740e3
|
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux8-202306291245
|
||||||
|
|
||||||
# Set default docker_context.
|
# Set default docker_context.
|
||||||
ARG resource_path=target
|
ARG resource_path=target
|
||||||
@@ -13,9 +14,6 @@ ARG USERID=33000
|
|||||||
# Set default environment args
|
# Set default environment args
|
||||||
ARG TOMCAT_DIR=/usr/local/tomcat
|
ARG TOMCAT_DIR=/usr/local/tomcat
|
||||||
|
|
||||||
# Needed for installation but make sure another USER directive is added after
|
|
||||||
# this with a non-root user
|
|
||||||
USER root
|
|
||||||
|
|
||||||
# Create prerequisite to store tools and properties
|
# Create prerequisite to store tools and properties
|
||||||
RUN mkdir -p ${TOMCAT_DIR}/shared/classes/alfresco/extension/mimetypes && \
|
RUN mkdir -p ${TOMCAT_DIR}/shared/classes/alfresco/extension/mimetypes && \
|
||||||
@@ -63,7 +61,13 @@ RUN sed -i -e "s_appender.rolling.fileName\=alfresco.log_appender.rolling.fileNa
|
|||||||
sed -i -e "\$a\grant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/alfresco\/-\" \{\n\ permission\ java.security.AllPermission\;\n\};\ngrant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/_vti_bin\/-\" \{\n\ permission\ java.security.AllPermission\;\n\};\ngrant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/ROOT\/-\" \{\n\ permission org.apache.catalina.security.DeployXmlPermission \"ROOT\";\n\};" ${TOMCAT_DIR}/conf/catalina.policy
|
sed -i -e "\$a\grant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/alfresco\/-\" \{\n\ permission\ java.security.AllPermission\;\n\};\ngrant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/_vti_bin\/-\" \{\n\ permission\ java.security.AllPermission\;\n\};\ngrant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/ROOT\/-\" \{\n\ permission org.apache.catalina.security.DeployXmlPermission \"ROOT\";\n\};" ${TOMCAT_DIR}/conf/catalina.policy
|
||||||
|
|
||||||
# fontconfig is required by Activiti worflow diagram generator
|
# fontconfig is required by Activiti worflow diagram generator
|
||||||
RUN yum install -y fontconfig-2.14.0-2.el9_1 && \
|
# installing pinned dependencies as well
|
||||||
|
RUN yum install -y fontconfig-2.13.1-4.el8 \
|
||||||
|
dejavu-fonts-common-2.35-7.el8 \
|
||||||
|
fontpackages-filesystem-1.44-22.el8 \
|
||||||
|
freetype-2.9.1-9.el8 \
|
||||||
|
libpng-1.6.34-5.el8 \
|
||||||
|
dejavu-sans-fonts-2.35-7.el8 && \
|
||||||
yum clean all
|
yum clean all
|
||||||
|
|
||||||
# The standard configuration is to have all Tomcat files owned by root with group GROUPNAME and whilst owner has read/write privileges,
|
# The standard configuration is to have all Tomcat files owned by root with group GROUPNAME and whilst owner has read/write privileges,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
SOLR6_TAG=2.0.11
|
SOLR6_TAG=2.0.10
|
||||||
POSTGRES_TAG=15.4
|
POSTGRES_TAG=15.4
|
||||||
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>23.4.0.7-SNAPSHOT</version>
|
<version>23.3.0.27-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user