Compare commits

..

38 Commits

Author SHA1 Message Date
Tom Page
e1989877c6 Add precommit for secret scanning, formatting and license header checking. (#2938)
* Add precommit for secret scanning, formatting and license header checking.

* Turn off bash debug logging.

* Skip precommit checks that apply to all files.

There are too many violations to run against all files.

(cherry picked from commit b00e11cb6f)
2024-10-07 14:18:17 +01:00
alfresco-build
05f501c984 [maven-release-plugin][skip ci] prepare for next development iteration 2024-09-05 08:52:17 +00:00
alfresco-build
33c02778cf [maven-release-plugin][skip ci] prepare release 23.1.1.12 2024-09-05 08:52:15 +00:00
Aleksandra Onych
3c591c3249 ACS-8670 Deal with upcoming GitHub Actions deprecations (#2879)
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2024-09-03 15:51:30 +02:00
alfresco-build
ee4cd6bfa5 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-23 11:48:56 +00:00
alfresco-build
38e1b91475 [maven-release-plugin][skip ci] prepare release 23.1.1.11 2024-07-23 11:48:54 +00:00
Tom Page
a8a480b7e9 Merge pull request #2807 from Alfresco/feature/PMD730
[skip tests] Upgrade ya-pmd-scan.

(cherry picked from commit 17152b69fc)
2024-07-23 12:46:18 +01:00
alfresco-build
c8101f8b00 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-22 13:47:49 +00:00
alfresco-build
925eaa9134 [maven-release-plugin][skip ci] prepare release 23.1.1.10 2024-07-22 13:47:47 +00:00
Domenico Sibilio
026509f8ec ACS-8352 Migrate to Docker Compose v2 (#2800)
Co-authored-by: Aleksandra Onych <aleksandra.onych@hyland.com>
2024-07-22 15:07:23 +02:00
alfresco-build
848b9d3d60 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-08 10:51:30 +00:00
alfresco-build
b39ed70093 [maven-release-plugin][skip ci] prepare release 23.1.1.9 2024-07-08 10:51:28 +00:00
Sara
c1d0a78b01 Bump SS/IE to 2.0.11 in 23-1 (#2757) 2024-07-08 09:57:58 +01:00
alfresco-build
93449b8079 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-05 17:03:52 +00:00
alfresco-build
348a6b930d [maven-release-plugin][skip ci] prepare release 23.1.1.8 2024-07-05 17:03:50 +00:00
Piotr Żurek
0373dcd703 ACS-8289 Bump ATS/AIS in ACS 23.1 (#2750) 2024-07-05 17:56:39 +02:00
alfresco-build
09c13a5b7d [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-27 15:44:52 +00:00
alfresco-build
97c13f286a [maven-release-plugin][skip ci] prepare release 23.1.1.7 2024-06-27 15:44:49 +00:00
Sara
1d2ac5e32c Merge pull request #2723 from Alfresco/feature/ACS-8287_Bump_SS-IE_in_23-1
ACS-8287 Bump SS/IE to 2.0.11-A6
2024-06-27 13:12:15 +01:00
Sara Aspery
7c0e25bcde Bump SS/IE to 2.0.11-A6 2024-06-27 10:53:55 +01:00
alfresco-build
6b0c9bf78d [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-19 16:45:27 +00:00
alfresco-build
c29b9bf0f5 [maven-release-plugin][skip ci] prepare release 23.1.1.6 2024-06-19 16:45:25 +00:00
Eva Vasques
e6a0fd7d4e MNT-24321 Transfer Service Exception Handling (#2573) (#2701)
* Mark method deserialize in ExceptionJsonSerializer as deprecated
* Remove usage of jsonErrorSerializer

(cherry picked from commit c31158a113)
2024-06-19 17:09:00 +01:00
alfresco-build
ead570065a [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-27 14:35:18 +00:00
alfresco-build
2ddf72953c [maven-release-plugin][skip ci] prepare release 23.1.1.5 2024-03-27 14:35:15 +00:00
Kacper Magdziarz
d470855c75 [ACS-7322] Propagate ATS and AIS to 23.1 (#2548) 2024-03-27 14:50:36 +01:00
alfresco-build
dcc398a910 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-16 10:14:19 +00:00
alfresco-build
77a007570a [maven-release-plugin][skip ci] prepare release 23.1.1.4 2023-11-16 10:14:17 +00:00
Domenico Sibilio
e795f67ff5 MNT-24063 Bump ActiveMQ to 5.18.3
Co-authored-by: kcichonczyk <88378534+kcichonczyk@users.noreply.github.com>
2023-11-16 10:36:06 +01:00
alfresco-build
ccf5a53cbf [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-07 18:44:01 +00:00
alfresco-build
3d9f50add8 [maven-release-plugin][skip ci] prepare release 23.1.1.3 2023-11-07 18:43:59 +00:00
tiagosalvado10
d4a72aa56c [MNT-23152] Changed the way how facet pivot value is parsed to prevent error and allow pivots to be built (#2290) (#2294)
* [MNT-23152] Changed the way how facet pivot value is parsed to prevent error and allow pivots to be built

(cherry picked from commit 964b09251b)
2023-11-07 14:21:20 +00:00
alfresco-build
e2a2658895 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-07 11:25:16 +00:00
alfresco-build
193386e640 [maven-release-plugin][skip ci] prepare release 23.1.1.2 2023-11-07 11:25:13 +00:00
tiagosalvado10
d3dcfd0b6a [MNT-23478] AsynchronousExtractor - Fix rendition obtaining (#2288) (#2293)
* [MNT-23478] AsynchronousExtractor - Fix rendition obtaining

* [MNT-23478] Only use default options if no rendition is found. PMD scan change.

(cherry picked from commit 3bd3689d80)
2023-11-07 10:41:32 +00:00
alfresco-build
b4241eaf90 [maven-release-plugin][skip ci] prepare for next development iteration 2023-10-31 19:30:28 +00:00
alfresco-build
d14ba74727 [maven-release-plugin][skip ci] prepare release 23.1.1.1 2023-10-31 19:30:24 +00:00
mpichura
e2b4e2c020 Create ServicePack branch release/23.1.N 2023-10-31 19:36:50 +01:00
431 changed files with 4755 additions and 18987 deletions

View File

@@ -52,7 +52,3 @@ updates:
interval: "daily"
time: "22:00"
timezone: Africa/Abidjan
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

File diff suppressed because it is too large Load Diff

View File

@@ -34,12 +34,12 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
- 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@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}
@@ -63,12 +63,12 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
- 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@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}

3
.gitignore vendored
View File

@@ -39,9 +39,6 @@ dependency-reduced-pom.xml
hs_err_pid*
# Development
repository/scripts/hazelcast-init/alfresco-hazelcast-config.xml
# Alfresco runtime
alf_data

14
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: ["--baseline", ".secrets.baseline"]
- repo: local
hooks:
- id: check-format-and-headers
name: Check format and headers and fix if necessary
entry: ./scripts/hooks/check-format-and-headers.sh
language: script
files: ".*.java"
pass_filenames: false

1864
.secrets.baseline Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,52 @@ Thanks for your interest in contributing to this project!
The following is a set of guidelines for contributing to this library. Most of them will make the life of the reviewer easier and therefore decrease the time required for the patch be included in the next version.
The project uses [pre-commit](https://pre-commit.com/) to format code (with [Spotless](https://github.com/diffplug/spotless)), validate license headers and check for secrets (with [detect-secrets](https://github.com/Yelp/detect-secrets)). To install the pre-commit hooks then first install pre-commit and then run:
```shell
pre-commit install
```
When you make a commit then these hooks will run and check the modified files. If it makes changes then you can review them and then `git commit` again to accept the changes.
#### Code Quality
This project uses `spotless` that enforces `alfresco-formatter.xml` to ensure code quality.
To check code-style violations you can use:
```bash
mvn spotless:check
```
To reformat files you can use:
```bash
mvn spotless:apply
```
#### Secret Detection
We are using [detect-secrets](https://github.com/Yelp/detect-secrets) to try to avoid accidentally publishing secret keys.
If you have pre-commit installed then this should run automatically when making a commit. Usually there should be no issues,
but if it finds a potential issue (e.g. a high entropy string) then you will see the following:
```shell
Detect secrets...........................................................Failed
- hook id: detect-secrets
- exit code: 1
ERROR: Potential secrets about to be committed to git repo!
Secret Type: Secret Keyword
Location: test.txt:1
```
If this is a false positive and you actually want to commit the string then run these two commands:
```shell
detect-secrets scan --baseline .secrets.baseline
detect-secrets audit .secrets.baseline
```
This will update the baseline file to include your new code and then allow you to review the detected secret and mark it as a false positive.
Once you are finished then you can add `.secrets.baseline` to the staged changes and you should be able to create a commit.
Because this project forms a part of Alfresco Content Services, the guidelines are hosted in the [Alfresco Social Community](https://hub.alfresco.com/t5/alfresco-content-services-ecm/ct-p/ECM-software) where they can be referenced from multiple projects.
You can report an issue in the ALF project of the [Alfresco issue tracker](http://issues.alfresco.com).

View File

@@ -2,57 +2,38 @@
[![Build Status](https://github.com/Alfresco/alfresco-community-repo/actions/workflows/master_release.yml/badge.svg?branch=master)](https://github.com/Alfresco/alfresco-community-repo/actions/workflows/master_release.yml)
## Table of Contents
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
Alfresco Core is a library packaged as a jar file which contains the following:
* Various helpers and utils
* Canned queries interface and supporting classes
* Generic encryption supporting classes
### Alfresco Data Model
Data Model is a library packaged as a jar file which contains the following:
#### Alfresco Data Model
Data model is a library packaged as a jar file which contains the following:
* Dictionary, Repository and Search Services interfaces
* Models for data types and Dictionary implementation
* Parsers
### Alfresco Repository
#### Alfresco Repository
Repository is a library packaged as a jar file which contains the following:
* DAOs and SQL scripts
* Various Service implementations
* Utility classes
### Alfresco Remote API
#### Alfresco Remote API
Remote API is a library packaged as a jar file which contains the following:
* 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)
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
## Artifacts
#### Artifacts
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:
~~~xml
~~~
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
@@ -83,46 +64,34 @@ The artifacts can be obtained by:
<version>version</version>
<type>war</type>
</dependency>
~~~
and Alfresco maven repository:
~~~xml
~~~
<repository>
<id>alfresco-maven-repo</id>
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
</repository>
~~~
The SNAPSHOT versions of the artifact are not published.
## Setting up and building your development environment
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 or using Docker containers.
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.
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
This project has a branch for each ACS release. For example the code in ACS 6.2.2 is a
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
**`release/7.1.N`** on which we gather unreleased fixes for future service pack releases. They do not indicate
This project has a branch for each ACS release. For example the code in ACS 6.2.1 is a
branch called `releases/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
`releases/7.1.N` on which we gather unreleased fixes for future service pack releases. They do not indicate
that one is planned.
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.
## Contributing guide
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)
### Contributing guide
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.

401
alfresco-formatter.xml Normal file
View File

@@ -0,0 +1,401 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="23">
<profile kind="CodeFormatterProfile" name="Spotless" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="999"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="999"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>23.4.0.1</version>
<version>23.1.1.13-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>23.4.0.1</version>
<version>23.1.1.13-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>23.4.0.1</version>
<version>23.1.1.13-SNAPSHOT</version>
</parent>
<build>
@@ -74,22 +74,6 @@
<artifactId>alfresco-testng</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${dependency.awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
@@ -98,7 +82,7 @@
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.3.6</version>
<version>3.3.2</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
@@ -112,11 +96,11 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<artifactId>bcprov-jdk15to18</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<artifactId>bcpkix-jdk15to18</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -39,7 +39,6 @@ import org.alfresco.rest.rm.community.requests.gscore.GSCoreAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.ActionsExecutionAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.HoldsAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
@@ -49,7 +48,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.UnfiledContainerAPI;
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.model.RepoTestModel;
import org.alfresco.utility.model.UserModel;
@@ -245,24 +243,4 @@ public class RestAPIFactory
{
return getGSCoreAPI(null).usingActionsExecutionsAPI();
}
public HoldsAPI getHoldsAPI()
{
return getGSCoreAPI(null).usingHoldsAPI();
}
public HoldsAPI getHoldsAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingHoldsAPI();
}
public RetentionScheduleAPI getRetentionScheduleAPI()
{
return getGSCoreAPI(null).usingRetentionScheduleAPI();
}
public RetentionScheduleAPI getRetentionScheduleAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingRetentionScheduleAPI();
}
}

View File

@@ -124,7 +124,7 @@ public abstract class BaseAPI
/**
* Helper method to extract the property value for the given nodeRef and property name
*
*
* @param result
* @param nodeRef
* @param propertyName
@@ -152,7 +152,7 @@ public abstract class BaseAPI
return propertyValue;
}
/**
* Helper method to extract property values from request result and put them in map as a list that corresponds to a unique property value.
*

View File

@@ -62,6 +62,7 @@ public class FilePlanComponentFields
public static final String PROPERTIES_DECLASSIFICATION_REVIEW_COMPLETED_BY = "rma:declassificationReviewCompletedBy";
public static final String PROPERTIES_DECLASSIFICATION_REVIEW_COMPLETED_AT = "rma:declassificationReviewCompletedAt";
/** File plan properties */
public static final String PROPERTIES_COMPONENT_ID = "st:componentId";
public static final String PROPERTIES_COUNT = "rma:count";

View File

@@ -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;
}

View File

@@ -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.rest.rm.community.model.hold;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.alfresco.utility.model.TestModel;
/**
* POJO for hold
*
* @author Damian Ujma
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Hold extends TestModel
{
@JsonProperty(required = true)
private String id;
@JsonProperty(required = true)
private String name;
@JsonProperty(required = true)
private String description;
@JsonProperty(required = true)
private String reason;
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Hold hold = (Hold) o;
return Objects.equals(id, hold.id) && Objects.equals(name, hold.name)
&& Objects.equals(description, hold.description) && Objects.equals(reason, hold.reason);
}
@Override
public int hashCode()
{
return Objects.hash(id, name, description, reason);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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>
{
}

View File

@@ -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;
}

View File

@@ -1,52 +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.utility.model.TestModel;
/**
* POJO for hold child
*
* @author Damian Ujma
*/
@Builder
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HoldChild extends TestModel
{
@JsonProperty(required = true)
private String id;
}

View File

@@ -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 HoldChildEntry}
*
* @author Damian Ujma
*/
public class HoldChildCollection extends RestModels<HoldChildEntry, HoldChildCollection>
{
}

View File

@@ -1,52 +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;
/**
* POJO for hold child entry
*
* @author Damian Ujma
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class HoldChildEntry extends RestModels<Hold, HoldChildEntry>
{
@JsonProperty
private HoldChild entry;
}

View File

@@ -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 HoldEntry}
*
* @author Damian Ujma
*/
public class HoldCollection extends RestModels<HoldEntry, HoldCollection>
{
}

View File

@@ -1,52 +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.utility.model.TestModel;
/**
* POJO for hold deletion reason
*
* @author Damian Ujma
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class HoldDeletionReason extends TestModel
{
@JsonProperty
private String reason;
}

View File

@@ -1,52 +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;
/**
* POJO for hold child entry
*
* @author Damian Ujma
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class HoldDeletionReasonEntry extends RestModels<HoldDeletionReason, HoldDeletionReasonEntry>
{
@JsonProperty
private HoldDeletionReason entry;
}

View File

@@ -26,27 +26,31 @@
*/
package org.alfresco.rest.rm.community.model.hold;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
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;
import org.alfresco.utility.model.TestModel;
/**
* POJO for hold entry
*
* @author Damian Ujma
* @author Rodica Sutu
* @since 3.2
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class HoldEntry extends RestModels<Hold, HoldEntry>
@JsonIgnoreProperties (ignoreUnknown = true)
public class HoldEntry extends TestModel
{
@JsonProperty
private Hold entry;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String nodeRef;
}

View File

@@ -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.rest.rm.community.model.hold.v0;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.alfresco.utility.model.TestModel;
/**
* POJO for hold entry
*
* @author Rodica Sutu
* @since 3.2
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties (ignoreUnknown = true)
public class HoldEntry extends TestModel
{
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String nodeRef;
}

View File

@@ -125,7 +125,7 @@ public class RecordProperties extends TestModel
@JsonProperty (required = true, value = PROPERTIES_ORIGINAL_NAME)
private String originalName;
@JsonProperty (PROPERTIES_CLASSIFICATION)
private List<String> classification;

View File

@@ -112,10 +112,10 @@ public class RecordCategoryChildProperties extends TestModel
@JsonProperty (PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE)
private Boolean recordSearchHasDispositionSchedule;
@JsonProperty (PROPERTIES_RECORD_SEARCH_DISPOSITION_PERIOD_EXPRESSION)
private String recordSearchDispositionPeriodExpression;
@JsonProperty (PROPERTIES_RECORD_SEARCH_DISPOSITION_AUTHORITY)
private String recordSearchDispositionAuthority;
@@ -136,7 +136,7 @@ public class RecordCategoryChildProperties extends TestModel
@JsonProperty (PROPERTIES_RECORD_SEARCH_DISPOSITION_EVENTS)
private List<String> recordSearchDispositionEvents;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;

View File

@@ -112,13 +112,13 @@ public class RecordFolderProperties extends TestModel
@JsonProperty (PROPERTIES_CLASSIFICATION)
private List<String> classification;
@JsonProperty (PROPERTIES_DESCRIPTION)
private String description;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
@JsonProperty (PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD)
private String recordSearchVitalRecordReviewPeriod;

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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>
{
}

View File

@@ -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;
}

View File

@@ -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>
{
}

View File

@@ -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;
}

View File

@@ -28,7 +28,7 @@ package org.alfresco.rest.rm.community.model.user;
/**
* Constants for RM user capabilities
*
*
* @author Kristijan Conkas
* @since 2.6
*/

View File

@@ -37,7 +37,6 @@ import org.alfresco.rest.rm.community.requests.gscore.api.ActionsExecutionAPI;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.HoldsAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
@@ -47,7 +46,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.UnfiledContainerAPI;
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
@@ -192,11 +190,4 @@ public class GSCoreAPI extends RMModelRequest
{
return new ActionsExecutionAPI(getRmRestWrapper());
}
public HoldsAPI usingHoldsAPI() { return new HoldsAPI(getRmRestWrapper()); }
public RetentionScheduleAPI usingRetentionScheduleAPI()
{
return new RetentionScheduleAPI(getRmRestWrapper());
}
}

View File

@@ -38,8 +38,6 @@ import static org.springframework.http.HttpMethod.PUT;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
@@ -215,74 +213,4 @@ public class FilePlanAPI extends RMModelRequest
parameters));
}
/**
* Creates a hold.
*
* @param holdModel The hold model
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The created {@link Hold}
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code filePlanId} is not a valid format or {@code filePlanId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code filePlanId}</li>
* <li>{@code filePlanIds} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* </ul>
*/
public Hold createHold(Hold holdModel, String filePlanId, String parameters)
{
mandatoryString("filePlanId", filePlanId);
mandatoryObject("holdModel", holdModel);
return getRmRestWrapper().processModel(Hold.class, requestWithBody(
POST,
toJson(holdModel),
"file-plans/{filePlanId}/holds",
filePlanId,
parameters
));
}
/**
* See {@link #createHold(Hold, String, String)}
*/
public Hold createHold(Hold holdModel, String filePlanId)
{
return createHold(holdModel, filePlanId, EMPTY);
}
/**
* Gets the holds of a file plan.
*
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The {@link HoldCollection} for the given {@code filePlanId}
* @throws RuntimeException for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code filePlanId}</li>
* <li>{@code filePlanId} does not exist</li>
*</ul>
*/
public HoldCollection getHolds(String filePlanId, String parameters)
{
mandatoryString("filePlanId", filePlanId);
return getRmRestWrapper().processModels(HoldCollection.class, simpleRequest(
GET,
"file-plans/{filePlanId}/holds?{parameters}",
filePlanId,
parameters
));
}
/**
* See {@link #getHolds(String, String)}
*/
public HoldCollection getHolds(String filePlanId)
{
return getHolds(filePlanId, EMPTY);
}
}

View File

@@ -1,446 +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 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.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
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.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.HoldChildCollection;
import org.alfresco.rest.rm.community.model.hold.HoldDeletionReason;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* Holds REST API Wrapper
*
* @author Damian Ujma
*/
public class HoldsAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public HoldsAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* Gets a hold.
*
* @param holdId The identifier of a hold
* @param parameters The URL parameters to add
* @return The {@link Hold} for the given {@code holdId}
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code holdId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public Hold getHold(String holdId, String parameters)
{
mandatoryString("holdId", holdId);
return getRmRestWrapper().processModel(Hold.class, simpleRequest(
GET,
"holds/{holdId}?{parameters}",
holdId,
parameters
));
}
/**
* See {@link #getHold(String, String)}
*/
public Hold getHold(String holdId)
{
mandatoryString("holdId", holdId);
return getHold(holdId, EMPTY);
}
/**
* Updates a hold.
*
* @param holdModel The hold model which holds the information
* @param holdId The identifier of the hold
* @param parameters The URL parameters to add
* @throws RuntimeException for the following cases:
* <ul>
* <li>the update request is invalid or {@code holdId} is not a valid format or {@code holdModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public Hold updateHold(Hold holdModel, String holdId, String parameters)
{
mandatoryObject("holdModel", holdModel);
mandatoryString("holdId", holdId);
return getRmRestWrapper().processModel(Hold.class, requestWithBody(
PUT,
toJson(holdModel),
"holds/{holdId}?{parameters}",
holdId,
parameters
));
}
/**
* See {@link #updateHold(Hold, String, String)}
*/
public Hold updateHold(Hold holdModel, String holdId)
{
mandatoryObject("holdModel", holdModel);
mandatoryString("holdId", holdId);
return updateHold(holdModel, holdId, EMPTY);
}
/**
* Deletes a hold.
*
* @param holdId The identifier of a hold
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code holdId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public void deleteHold(String holdId)
{
mandatoryString("holdId", holdId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"holds/{holdId}",
holdId
));
}
/**
* Deletes a hold and stores a reason for deletion in the audit log.
*
* @param reason The reason for hold deletion
* @param holdId The identifier of a hold
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code holdId} is not a valid format or {@code reason} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public HoldDeletionReason deleteHoldWithReason(HoldDeletionReason reason, String holdId)
{
mandatoryObject("reason", reason);
mandatoryString("holdId", holdId);
return getRmRestWrapper().processModel(HoldDeletionReason.class, requestWithBody(
POST,
toJson(reason),
"holds/{holdId}/delete",
holdId
));
}
/**
* Adds the relationship between a child and a parent hold.
*
* @param holdChild The hold child model
* @param holdId The identifier of a hold
* @param parameters The URL parameters to add
* @return The created {@link Hold}
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code holdId} is not a valid format or {@code holdId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public HoldChild addChildToHold(HoldChild holdChild, String holdId, String parameters)
{
mandatoryObject("holdId", holdId);
return getRmRestWrapper().processModel(HoldChild.class, requestWithBody(
POST,
toJson(holdChild),
"holds/{holdId}/children",
holdId,
parameters));
}
/**
* See {@link #addChildToHold(HoldChild, String, String)}
*/
public HoldChild addChildToHold(HoldChild holdChild, String holdId)
{
return addChildToHold(holdChild, holdId, EMPTY);
}
/**
* Gets the children of a hold.
*
* @param holdId The identifier of a hold
* @param parameters The URL parameters to add
* @return The {@link HoldChildCollection} for the given {@code holdId}
* @throws RuntimeException for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
*</ul>
*/
public HoldChildCollection getChildren(String holdId, String parameters)
{
mandatoryString("holdId", holdId);
return getRmRestWrapper().processModels(HoldChildCollection.class, simpleRequest(
GET,
"holds/{holdId}/children",
holdId,
parameters
));
}
/**
* See {@link #getChildren(String, String)}
*/
public HoldChildCollection getChildren(String holdId)
{
return getChildren(holdId, EMPTY);
}
/**
* Deletes the relationship between a child and a parent hold.
*
* @param holdChildId The identifier of hold child
* @param holdId The identifier of a hold
* @param parameters The URL parameters to add
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code holdId} or {@code holdChildId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete children from {@code holdId}</li>
* <li>{@code holdId} does not exist</li>
* </ul>
*/
public void deleteHoldChild(String holdId, String holdChildId, String parameters)
{
mandatoryString("holdId", holdId);
mandatoryString("holdChildId", holdChildId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"holds/{holdId}/children/{holdChildId}",
holdId,
holdChildId,
parameters
));
}
/**
* See {@link #deleteHoldChild(String, String, String)}
*/
public void deleteHoldChild(String holdId, String holdChildId)
{
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);
}
}

View File

@@ -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);
}
}

View File

@@ -36,7 +36,7 @@ import java.util.stream.Collectors;
import org.alfresco.rest.core.v0.APIUtils;
import org.alfresco.rest.core.v0.BaseAPI;
import org.alfresco.rest.rm.community.model.hold.v0.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.HoldEntry;
import org.alfresco.rest.rm.community.util.PojoUtility;
import org.alfresco.utility.model.UserModel;
import org.apache.http.HttpResponse;

View File

@@ -38,7 +38,7 @@ import org.springframework.stereotype.Component;
/**
* The v0 REST API for nodes
*
*
* @author jcule
* @since 2.7EA1
*/
@@ -56,7 +56,7 @@ public class NodeAPI extends BaseAPI
/**
* Get the node metadata using the using the node data webscript: Document List v2 Component
*
*
* @param username
* @param password
* @param nodeId
@@ -70,5 +70,5 @@ public class NodeAPI extends BaseAPI
client.close();
return doGetRequest(username, password, requestURL);
}
}

View File

@@ -143,7 +143,7 @@ public class SearchAPI extends BaseAPI
/**
* Search as a user for nodes on site "rm" matching query, using SearchAPI.RM_DEFAULT_RECORD_FILTERS and sorted
* by sortby and returns the property value for the given nodeRef and property name
*
*
* @param username
* @param password
* @param query
@@ -157,9 +157,9 @@ public class SearchAPI extends BaseAPI
{
String searchFilterParamaters = MessageFormat.format(RM_DEFAULT_NODES_FILTERS, Boolean.toString(includeFolders),
Boolean.toString(includeCategories));
return getItemProperty(rmSearch(username, password, "rm", query, searchFilterParamaters, sortby), nodeRef, propertyName);
return getItemProperty(rmSearch(username, password, "rm", query, searchFilterParamaters, sortby), nodeRef, propertyName);
}
/**
* Generic faceted search.
* @param username
@@ -229,17 +229,17 @@ public class SearchAPI extends BaseAPI
/**
* Helper method to extract list of names from search result.
*
*
* @param searchResult
* @return list of document or record names in search result
* @throws FileNotFoundException
* @throws JsonSyntaxException
* @throws JsonIOException
* @throws FileNotFoundException
* @throws JsonSyntaxException
* @throws JsonIOException
* @throws RuntimeException for malformed search response
*/
/**
* Helper method to extract list of names from search result.
*
*
* @param searchResult
* @return
*/
@@ -247,10 +247,10 @@ public class SearchAPI extends BaseAPI
{
return getPropertyValues(searchResult, "name");
}
/**
* Helper method to extract list of property values from search result for the given nodeRef.
*
*
* @param searchResult
* @param nodeRef
* @param propertyName

View File

@@ -31,18 +31,18 @@ import static java.util.Arrays.asList;
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.audit.AuditEvents.ADD_TO_HOLD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableMap;
@@ -50,13 +50,12 @@ import com.google.common.collect.ImmutableMap;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
@@ -86,6 +85,8 @@ public class AuditAddToHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
@@ -93,22 +94,17 @@ public class AuditAddToHoldTests extends BaseRMRestTest
private RecordCategory recordCategory;
private RecordCategoryChild recordFolder;
private List<AuditEntry> auditEntries;
private final List<String> holdsList = asList(HOLD1, HOLD2);
private List<String> holdsListRef = new ArrayList<>();
private String hold1NodeRef;
private String hold2NodeRef;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditAddToHoldTests()
{
STEP("Create 2 holds.");
hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold2NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(),
getAdminUser().getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
holdsListRef = asList(hold1NodeRef, hold2NodeRef);
STEP("Create a new record category with a record folder.");
@@ -173,8 +169,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add node to hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(nodeId).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD1);
STEP("Check the audit log contains the entry for the add to hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), ADD_TO_HOLD, rmAdmin, nodeName, nodePath,
@@ -196,8 +191,9 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to add the record to a hold by an user with no rights.");
getRestAPIFactory().getHoldsAPI(rmManagerNoReadOnHold).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
assertStatusCode(FORBIDDEN);
holdsAPI.addItemsToHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(recordToBeAdded.getId()),
Collections.singletonList(hold1NodeRef));
STEP("Check the audit log doesn't contain the entry for the unsuccessful add to hold.");
assertTrue("The list of events should not contain Add to Hold entry ",
@@ -219,7 +215,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add record folder to hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(notEmptyRecFolder.getId()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
@@ -243,9 +239,8 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add record to multiple holds.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold2NodeRef);
holdsAPI.addItemsToHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(recordToBeAdded.getId()), holdsList);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
@@ -273,7 +268,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(contentToBeAdded.getNodeRefWithoutVersion()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
STEP("Check that an user with no Read permissions can't see the entry for the add to hold event.");
assertTrue("The list of events should not contain Add to Hold entry ",
@@ -294,7 +289,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(contentToBeAdded.getNodeRefWithoutVersion()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, ADD_TO_HOLD);
@@ -309,8 +304,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditAddToHoldTests()
{
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(holdRef));
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
deleteRecordCategory(recordCategory.getId());

View File

@@ -31,10 +31,9 @@ import static java.util.Arrays.asList;
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.audit.AuditEvents.CREATE_HOLD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
@@ -45,8 +44,8 @@ import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
@@ -74,6 +73,8 @@ public class AuditCreateHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
@@ -101,10 +102,8 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
String hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
String hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1,
HOLD_REASON, HOLD_DESCRIPTION);
holdsListRef.add(hold1NodeRef);
STEP("Check the audit log contains the entry for the created hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), CREATE_HOLD, rmAdmin, HOLD1,
@@ -121,18 +120,13 @@ public class AuditCreateHoldTests extends BaseRMRestTest
public void createHoldEventIsNotAuditedForExistingHold()
{
STEP("Create a new hold.");
String hold2NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
holdsListRef.add(hold2NodeRef);
rmAuditService.clearAuditLog();
STEP("Try to create again the same hold and expect action to fail.");
getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
assertStatusCode(CONFLICT);
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION,
SC_INTERNAL_SERVER_ERROR);
STEP("Check the audit log doesn't contain the entry for the second create hold event.");
assertTrue("The list of events should not contain Create Hold entry ",
@@ -151,17 +145,13 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
String nodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(holdName).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS).getId();
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Get the list of audit entries for the create hold event.");
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD);
STEP("Delete the created hold.");
getRestAPIFactory()
.getHoldsAPI(rmAdmin)
.deleteHold(nodeRef);
holdsAPI.deleteHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName);
STEP("Get again the list of audit entries for the create hold event.");
List<AuditEntry> auditEntriesAfterDelete = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD);
@@ -181,10 +171,8 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
String hold3NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD3).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS).getId();
String hold3NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD3,
HOLD_REASON, HOLD_DESCRIPTION);
holdsListRef.add(hold3NodeRef);
STEP("Check that an user with no Read permissions over the hold can't see the entry for the create hold event");
@@ -195,7 +183,7 @@ public class AuditCreateHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditCreateHoldTests()
{
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef));
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -31,20 +31,18 @@ import static java.util.Arrays.asList;
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.audit.AuditEvents.DELETE_HOLD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertTrue;
import java.util.List;
import java.util.Collections;
import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldDeletionReason;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
@@ -64,13 +62,14 @@ import org.testng.annotations.Test;
public class AuditDeleteHoldTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditDeleteHoldTests.class);
private final String hold = PREFIX + "holdToBeDeleted";
private final String hold2 = PREFIX + "deleteHold";
private final String hold3 = PREFIX + "deleteHoldWithReason";
private final String HOLD = PREFIX + "holdToBeDeleted";
private final String HOLD2 = PREFIX + "deleteHold";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
@@ -80,10 +79,8 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
public void preconditionForAuditDeleteHoldTests()
{
STEP("Create a new hold.");
holdNodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(hold).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD,
HOLD_REASON, HOLD_DESCRIPTION);
STEP("Create 2 users with different permissions for the created hold.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
@@ -102,51 +99,17 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
public void deleteHoldEventIsAudited()
{
STEP("Create a new hold.");
String holdRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(hold2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
String holdRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2,
HOLD_REASON, HOLD_DESCRIPTION);
rmAuditService.clearAuditLog();
STEP("Delete the created hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef);
holdsAPI.deleteHold(rmAdmin, holdRef);
STEP("Check the audit log contains the entry for the deleted hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, hold2,
List.of(ImmutableMap.of("new", "", "previous", hold2, "name", "Hold Name"),
ImmutableMap.of("new", "", "previous", "", "name", "Hold deletion reason")));
}
/**
* Given a hold is deleted with a reason
* When I view the audit log
* Then an entry has been created in the audit log which contains the following:
* name of the hold
* hold deletion reason
* user who deleted the hold
* date the delete occurred
*/
@Test
public void deleteHoldWithReasonEventIsAudited()
{
STEP("Create a new hold.");
String holdRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(hold3).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
String deletionReason = "Test reason";
rmAuditService.clearAuditLog();
STEP("Delete the created hold with a reason.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldWithReason(HoldDeletionReason.builder().reason(deletionReason).build(), holdRef);
STEP("Check the audit log contains the entry for the deleted hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, hold3,
List.of(ImmutableMap.of("new", "", "previous", hold3, "name", "Hold Name"),
ImmutableMap.of("new", "", "previous", deletionReason, "name", "Hold deletion reason")));
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, HOLD2,
Collections.singletonList(ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name")));
}
/**
@@ -160,8 +123,7 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to delete a hold by an user with no Read permissions over the hold.");
getRestAPIFactory().getHoldsAPI(rmManager).deleteHold(holdNodeRef);
assertStatusCode(FORBIDDEN);
holdsAPI.deleteHold(rmManager.getUsername(), rmManager.getPassword(), holdNodeRef, SC_INTERNAL_SERVER_ERROR);
STEP("Check the audit log doesn't contain the entry for the unsuccessful delete hold.");
assertTrue("The list of events should not contain Delete Hold entry ",
@@ -171,7 +133,7 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditDeleteHoldTests()
{
getRestAPIFactory().getHoldsAPI(rmManager).deleteHold(holdNodeRef);
holdsAPI.deleteHold(getAdminUser(), holdNodeRef);
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -25,14 +25,10 @@
* #L%
*/
package org.alfresco.rest.rm.community.audit;
import static java.util.Arrays.asList;
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.base.TestData.*;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.ADD_TO_HOLD;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.REMOVE_FROM_HOLD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
@@ -41,22 +37,20 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.IsNot.not;
import static org.springframework.http.HttpStatus.CREATED;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.*;
import java.util.Collections;
import java.util.List;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.audit.AuditEvents;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.utility.model.FileModel;
@@ -75,6 +69,8 @@ public class AuditHoldsTest extends BaseRMRestTest {
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin;
private RecordCategory recordCategory;
@@ -89,11 +85,8 @@ public class AuditHoldsTest extends BaseRMRestTest {
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
STEP("Create a hold");
hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1, HOLD_REASON,
HOLD_DESCRIPTION);
STEP("Create a collaboration site with a test file.");
publicSite = dataSite.usingAdmin().createPublicRandomSite();
@@ -108,11 +101,9 @@ public class AuditHoldsTest extends BaseRMRestTest {
STEP("Add some items to the hold, then remove them from the hold");
final List<String> itemsList = asList(testFile.getNodeRefWithoutVersion(), recordToBeAdded.getId(), recordFolder2.getId());
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
for(String childId : itemsList)
{
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, childId);
}
final List<String> holdsList = Collections.singletonList(HOLD1);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), recordToBeAdded.getId(), HOLD1);
holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(), itemsList, holdsList);
STEP("Delete the record folder that was held");
getRestAPIFactory().getRecordFolderAPI().deleteRecordFolder(recordFolder2.getId());

View File

@@ -73,7 +73,7 @@ public class AuditLoginEventsTests extends BaseRMRestTest
assertTrue("The list of events is not filtered by " + LOGIN_UNSUCCESSFUL.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(LOGIN_UNSUCCESSFUL.eventDisplayName)));
}
/**
* Given I have tried to login using valid credentials
* When I view the RM audit filtered by Login successful event

View File

@@ -31,18 +31,18 @@ import static java.util.Arrays.asList;
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.audit.AuditEvents.REMOVE_FROM_HOLD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableMap;
@@ -50,13 +50,12 @@ import com.google.common.collect.ImmutableMap;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
@@ -87,6 +86,8 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
@@ -95,11 +96,10 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
private RecordCategoryChild recordFolder, heldRecordFolder;
private Record heldRecord;
private List<AuditEntry> auditEntries;
private final List<String> holdsList = asList(HOLD1, HOLD2, HOLD3);
private List<String> holdsListRef = new ArrayList<>();
private FileModel heldContent;
private String hold1NodeRef;
private String hold2NodeRef;
private String hold3NodeRef;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditRemoveFromHoldTests()
@@ -111,18 +111,10 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite();
STEP("Create new holds.");
hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold2NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold3NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD3).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(),
HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
String hold3NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD3, HOLD_REASON, HOLD_DESCRIPTION);
holdsListRef = asList(hold1NodeRef, hold2NodeRef, hold3NodeRef);
STEP("Create a new record category with a record folder.");
@@ -135,12 +127,9 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
heldRecordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "heldRecFolder");
heldRecord = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
holdsListRef.forEach(holdRef ->
{
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldContent.getNodeRefWithoutVersion()).build(), holdRef);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldRecordFolder.getId()).build(), holdRef);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldRecord.getId()).build(), holdRef);
});
holdsAPI.addItemsToHolds(getAdminUser().getUsername(), getAdminUser().getPassword(),
asList(heldContent.getNodeRefWithoutVersion(), heldRecordFolder.getId(), heldRecord.getId()),
holdsList);
STEP("Create users without rights to remove content from a hold.");
rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite,
@@ -190,7 +179,7 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Remove node from hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold3NodeRef, nodeId);
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD3);
STEP("Check the audit log contains the entry for the remove from hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), REMOVE_FROM_HOLD, rmAdmin, nodeName, nodePath,
@@ -209,8 +198,9 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to remove the record from a hold by an user with no rights.");
getRestAPIFactory().getHoldsAPI(rmManagerNoReadOnHold).deleteHoldChild(hold1NodeRef, heldRecord.getId());
assertStatusCode(FORBIDDEN);
holdsAPI.removeItemsFromHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(heldRecord.getId()),
Collections.singletonList(hold1NodeRef));
STEP("Check the audit log doesn't contain the entry for the unsuccessful remove from hold.");
assertTrue("The list of events should not contain remove from hold entry ",
@@ -230,12 +220,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record");
STEP("Add the record folder to a hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(notEmptyRecFolder.getId()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove record folder from hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, notEmptyRecFolder.getId());
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
@@ -257,8 +247,8 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Remove record folder from multiple holds.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldRecordFolder.getId());
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold2NodeRef, heldRecordFolder.getId());
holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(heldRecordFolder.getId()), asList(HOLD1, HOLD2));
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
@@ -285,12 +275,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldFile.getNodeRefWithoutVersion()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldFile.getNodeRefWithoutVersion());
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
STEP("Check that an user with no Read permissions can't see the entry for the remove from hold event.");
assertTrue("The list of events should not contain Remove from Hold entry ",
@@ -308,12 +298,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldFile.getNodeRefWithoutVersion()).build(), hold1NodeRef);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldFile.getNodeRefWithoutVersion());
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, REMOVE_FROM_HOLD);
@@ -328,7 +318,7 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditRemoveFromHoldTests()
{
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef));
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
deleteRecordCategory(recordCategory.getId());

View File

@@ -60,15 +60,12 @@ import static org.testng.Assert.fail;
import static org.testng.AssertJUnit.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.DataProviderClass;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.fileplan.FilePlanProperties;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryProperties;
@@ -517,97 +514,5 @@ public class FilePlanTests extends BaseRMRestTest
);
}
/**
* <pre>
* Given that a file plan exists
* When I ask the API to create a hold
* Then it is created
* </pre>
*/
@Test
public void createHolds()
{
String holdName = "Hold" + getRandomAlphanumeric();
String holdDescription = "Description" + getRandomAlphanumeric();
String holdReason = "Reason" + getRandomAlphanumeric();
// Create the hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
// Verify the status code
assertStatusCode(CREATED);
assertEquals(createdHold.getName(), holdName);
assertEquals(createdHold.getDescription(), holdDescription);
assertEquals(createdHold.getReason(), holdReason);
assertNotNull(createdHold.getId());
}
@Test
public void listHolds()
{
// Delete all holds
getRestAPIFactory().getFilePlansAPI().getHolds(FILE_PLAN_ALIAS).getEntries().forEach(holdEntry ->
getRestAPIFactory().getHoldsAPI().deleteHold(holdEntry.getEntry().getId()));
// Add holds
List<Hold> filePlanHolds = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_CHILDREN; i++)
{
String holdName = "Hold name " + getRandomAlphanumeric();
String holdDescription = "Hold Description " + getRandomAlphanumeric();
String holdReason = "Reason " + getRandomAlphanumeric();
// Create a hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
assertNotNull(createdHold.getId());
filePlanHolds.add(createdHold);
}
// Get holds of a file plan
HoldCollection holdCollection = getRestAPIFactory().getFilePlansAPI()
.getHolds(FILE_PLAN_ALIAS);
// Check status code
assertStatusCode(OK);
// Check holds against created list
holdCollection.getEntries().forEach(c ->
{
Hold hold = c.getEntry();
String holdId = hold.getId();
assertNotNull(holdId);
logger.info("Checking hold " + holdId);
try
{
// Find this hold in created holds list
Hold createdHold = filePlanHolds.stream()
.filter(child -> child.getId().equals(holdId))
.findFirst()
.orElseThrow();
assertEquals(createdHold.getName(), hold.getName());
assertEquals(createdHold.getDescription(), hold.getDescription());
assertEquals(createdHold.getReason(), hold.getReason());
}
catch (NoSuchElementException e)
{
fail("No child element for " + hold);
}
}
);
}
}

View File

@@ -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()));
}
}

View File

@@ -60,7 +60,7 @@ import org.alfresco.dataprep.CMISUtil;
import org.alfresco.dataprep.ContentActions;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.v0.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.HoldEntry;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;

View File

@@ -1,386 +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.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
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.model.user.UserRoles.ROLE_RM_MANAGER;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertFalse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.dataprep.ContentActions;
import org.alfresco.rest.model.RestNodeAssociationModelCollection;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* V1 API tests for adding content/record folder/records to holds
*
* @author Damian Ujma
*/
public class AddToHoldsV1Tests 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 String INVALID_TYPE_ERROR_MESSAGE = "Only records, record folders or content can be added to a hold.";
private static final String LOCKED_FILE_ERROR_MESSAGE = "Locked content can't be added to a hold.";
private static final String HOLD = "HOLD" + generateTestPrefix(AddToHoldsV1Tests.class);
private String holdNodeRef;
private SiteModel testSite;
private FileModel documentHeld;
private FileModel contentToAddToHold;
private FileModel contentAddToHoldNoPermission;
private Hold hold;
private UserModel userAddHoldPermission;
private final List<UserModel> users = new ArrayList<>();
private final List<String> nodesToBeClean = new ArrayList<>();
@Autowired
private RoleService roleService;
@Autowired
private ContentActions contentActions;
@BeforeClass(alwaysRun = true)
public void preconditionForAddContentToHold()
{
STEP("Create a hold.");
hold = createHold(FILE_PLAN_ALIAS,
Hold.builder().name(HOLD).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), getAdminUser());
holdNodeRef = hold.getId();
STEP("Create test files.");
testSite = dataSite.usingAdmin().createPublicRandomSite();
documentHeld = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
contentToAddToHold = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
contentAddToHoldNoPermission = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Add the content to the hold.");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(documentHeld.getNodeRefWithoutVersion()).build(), hold.getId());
STEP("Create users");
userAddHoldPermission = roleService.createUserWithSiteRoleRMRoleAndPermission(testSite,
UserRole.SiteCollaborator, holdNodeRef, UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
users.add(userAddHoldPermission);
}
/**
* Given a hold that contains at least one active content
* When I use the existing REST API to retrieve the contents of the hold
* Then I should see all the active content on hold
*/
@Test
public void retrieveTheContentOfTheHoldUsingV1API()
{
STEP("Retrieve the list of children from the hold and collect the entries that have the name of the active " +
"content held");
List<String> documentNames = restClient.authenticateUser(getAdminUser()).withCoreAPI()
.usingNode(toContentModel(holdNodeRef))
.listChildren().getEntries().stream()
.map(RestNodeModel::onModel)
.map(RestNodeModel::getName)
.filter(documentName -> documentName.equals(documentHeld.getName()))
.toList();
STEP("Check the list of active content");
assertEquals(documentNames, Set.of(documentHeld.getName()));
}
/**
* Given a hold that contains at least one active content
* When I use the existing REST API to retrieve the holds the content is added
* Then the hold where the content held is returned
*/
@Test
public void retrieveTheHoldWhereTheContentIsAdded()
{
RestNodeAssociationModelCollection holdsEntries = getRestAPIFactory()
.getNodeAPI(documentHeld).usingParams("where=(assocType='rma:frozenContent')").getParents();
Hold retrievedHold = getRestAPIFactory().getHoldsAPI(getAdminUser())
.getHold(holdsEntries.getEntries().get(0).getModel().getId());
assertEquals(retrievedHold, hold, "Holds are not equal");
}
/**
* Valid nodes to be added to hold
*/
@DataProvider(name = "validNodesForAddToHold")
public Object[][] getValidNodesForAddToHold()
{
//create electronic and nonElectronic record in record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
nodesToBeClean.add(recordFolder.getParentId());
Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder.getId(),
getFile
(IMAGE_FILE));
assertStatusCode(CREATED);
Record nonElectronicRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(),
recordFolder.getId());
assertStatusCode(CREATED);
getRestAPIFactory().getRMUserAPI().addUserPermission(recordFolder.getId(), userAddHoldPermission,
PERMISSION_FILING);
RecordCategoryChild folderToHold = createCategoryFolderInFilePlan();
getRestAPIFactory().getRMUserAPI().addUserPermission(folderToHold.getId(), userAddHoldPermission,
PERMISSION_FILING);
nodesToBeClean.add(folderToHold.getParentId());
return new String[][]
{ // record folder
{ folderToHold.getId() },
//electronic record
{ electronicRecord.getId() },
// non electronic record
{ nonElectronicRecord.getId() },
// document from collaboration site
{ contentToAddToHold.getNodeRefWithoutVersion() },
};
}
/**
* Given record folder/record/document not on hold
* And a hold
* And file permission on the hold
* And the appropriate capability to add to hold
* When I use the existing REST API to add the node to the hold
* Then the record folder/record/document is added to the hold
* And the item is frozen
*
* @throws Exception
*/
@Test(dataProvider = "validNodesForAddToHold")
public void addValidNodesToHoldWithAllowedUser(String nodeId) throws Exception
{
STEP("Add node to hold with user with permission.");
getRestAPIFactory().getHoldsAPI(userAddHoldPermission)
.addChildToHold(HoldChild.builder().id(nodeId).build(), hold.getId());
STEP("Check the node is frozen.");
assertTrue(hasAspect(nodeId, FROZEN_ASPECT));
}
/**
* Data provider with user without correct permission to add to hold and the node ref to be added to hold
*
* @return object with user model and the node ref to be added to hold
*/
@DataProvider(name = "userWithoutPermissionForAddToHold")
public Object[][] getUserWithoutPermissionForAddToHold()
{
//create record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
//create a rm manager and grant read permission over the record folder created
UserModel user = roleService.createUserWithRMRoleAndRMNodePermission(ROLE_RM_MANAGER.roleId,
recordFolder.getId(),
PERMISSION_READ_RECORDS);
getRestAPIFactory().getRMUserAPI().addUserPermission(holdNodeRef, user, PERMISSION_FILING);
nodesToBeClean.add(recordFolder.getParentId());
return new Object[][]
{ // user without write permission on the content
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole.SiteConsumer,
holdNodeRef, UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING),
contentAddToHoldNoPermission.getNodeRefWithoutVersion()
},
// user with write permission on the content and without filling permission on a hold
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole
.SiteCollaborator,
holdNodeRef, UserRoles.ROLE_RM_MANAGER, PERMISSION_READ_RECORDS),
contentAddToHoldNoPermission.getNodeRefWithoutVersion()
},
// user with write permission on the content, filling permission on a hold without add to
// hold capability
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole
.SiteCollaborator,
holdNodeRef, UserRoles.ROLE_RM_POWER_USER, PERMISSION_READ_RECORDS),
contentAddToHoldNoPermission.getNodeRefWithoutVersion()
},
//user without write permission on RM record folder
{
user, recordFolder.getId()
},
};
}
/**
* Given a node not on hold
* And a hold
* And user without right permission to add to hold
* When I use the existing REST API to add the node to the hold
* Then the node is not added to the hold
* And the node is not frozen
*
* @throws Exception
*/
@Test(dataProvider = "userWithoutPermissionForAddToHold")
public void addContentToHoldWithUserWithoutHoldPermission(UserModel userModel, String nodeToBeAddedToHold)
throws Exception
{
users.add(userModel);
STEP("Add the node to the hold with user without permission.");
getRestAPIFactory()
.getHoldsAPI(userModel)
.addChildToHold(HoldChild.builder().id(nodeToBeAddedToHold).build(), holdNodeRef);
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(ACCESS_DENIED_ERROR_MESSAGE);
STEP("Check the node is not frozen.");
assertFalse(hasAspect(nodeToBeAddedToHold, FROZEN_ASPECT));
}
/**
* Data provider with invalid node types that can be added to a hold
*/
@DataProvider(name = "invalidNodesForAddToHold")
public Object[][] getInvalidNodesForAddToHold()
{
//create locked file
FileModel contentLocked = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
contentActions.checkOut(getAdminUser().getUsername(), getAdminUser().getPassword(),
testSite.getId(), contentLocked.getName());
RecordCategory category = createRootCategory(getRandomAlphanumeric());
nodesToBeClean.add(category.getId());
return new Object[][]
{ // file plan node id
{ getFilePlan(FILE_PLAN_ALIAS).getId(), SC_BAD_REQUEST, INVALID_TYPE_ERROR_MESSAGE },
//transfer container
{ getTransferContainer(TRANSFERS_ALIAS).getId(), SC_BAD_REQUEST, INVALID_TYPE_ERROR_MESSAGE },
// a record category
{ category.getId(), SC_BAD_REQUEST, INVALID_TYPE_ERROR_MESSAGE },
// unfiled records root
{ getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS).getId(), SC_BAD_REQUEST,
INVALID_TYPE_ERROR_MESSAGE },
// an arbitrary unfiled records folder
{ createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " +
getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId(), SC_BAD_REQUEST,
INVALID_TYPE_ERROR_MESSAGE },
//folder,
{ dataContent.usingAdmin().usingSite(testSite).createFolder().getNodeRef(), SC_BAD_REQUEST,
INVALID_TYPE_ERROR_MESSAGE },
//document locked
{ contentLocked.getNodeRefWithoutVersion(), SC_BAD_REQUEST, LOCKED_FILE_ERROR_MESSAGE }
};
}
/**
* Given a node that is not a document/record/ record folder ( a valid node type to be added to hold)
* And a hold
* And user without right permission to add to hold
* When I use the existing REST API to add the node to the hold
* Then the node is not added to the hold
* And the node is not frozen
*
* @throws Exception
*/
@Test(dataProvider = "invalidNodesForAddToHold")
public void addInvalidNodesToHold(String itemNodeRef, int responseCode, String errorMessage) throws Exception
{
STEP("Add the node to the hold ");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(itemNodeRef).build(), holdNodeRef);
assertStatusCode(HttpStatus.valueOf(responseCode));
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(errorMessage);
STEP("Check node is not frozen.");
assertFalse(hasAspect(itemNodeRef, FROZEN_ASPECT));
}
private Hold createHold(String parentId, Hold hold, UserModel user)
{
FilePlanAPI filePlanAPI = getRestAPIFactory().getFilePlansAPI(user);
return filePlanAPI.createHold(hold, parentId);
}
@AfterClass(alwaysRun = true)
public void cleanUpAddContentToHold()
{
getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(holdNodeRef);
dataSite.usingAdmin().deleteSite(testSite);
users.forEach(user -> getDataUser().usingAdmin().deleteUser(user));
nodesToBeClean.forEach(this::deleteRecordCategory);
}
}

View File

@@ -1,186 +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.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldDeletionReason;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
/**
* This class contains the tests for the Holds CRUD V1 API
*
* @author Damian Ujma
*/
public class HoldsTests extends BaseRMRestTest
{
private final List<String> nodeRefs = new ArrayList<>();
@Test
public void testGetHold()
{
String holdName = "Hold" + getRandomAlphanumeric();
String holdDescription = "Description" + getRandomAlphanumeric();
String holdReason = "Reason" + getRandomAlphanumeric();
// Create the hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
// Get the hold
Hold receivedHold = getRestAPIFactory().getHoldsAPI().getHold(createdHold.getId());
nodeRefs.add(receivedHold.getId());
// Verify the status code
assertStatusCode(OK);
assertEquals(receivedHold.getName(), holdName);
assertEquals(receivedHold.getDescription(), holdDescription);
assertEquals(receivedHold.getReason(), holdReason);
assertNotNull(receivedHold.getId());
}
@Test
public void testUpdateHold()
{
String holdName = "Hold" + getRandomAlphanumeric();
String holdDescription = "Description" + getRandomAlphanumeric();
String holdReason = "Reason" + getRandomAlphanumeric();
// Create the hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
nodeRefs.add(createdHold.getId());
Hold holdModel = Hold.builder()
.name("Updated" + holdName)
.description("Updated" + holdDescription)
.reason("Updated" + holdReason)
.build();
// Update the hold
Hold updatedHold = getRestAPIFactory().getHoldsAPI().updateHold(holdModel, createdHold.getId());
// Verify the status code
assertStatusCode(OK);
assertEquals(updatedHold.getName(), "Updated" + holdName);
assertEquals(updatedHold.getDescription(), "Updated" + holdDescription);
assertEquals(updatedHold.getReason(), "Updated" + holdReason);
assertNotNull(updatedHold.getId());
}
@Test
public void testDeleteHold()
{
String holdName = "Hold" + getRandomAlphanumeric();
String holdDescription = "Description" + getRandomAlphanumeric();
String holdReason = "Reason" + getRandomAlphanumeric();
// Create the hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
nodeRefs.add(createdHold.getId());
// Delete the hold
getRestAPIFactory().getHoldsAPI().deleteHold(createdHold.getId());
// Verify the status code
assertStatusCode(NO_CONTENT);
// Try to get the hold
getRestAPIFactory().getHoldsAPI().getHold(createdHold.getId());
// Verify the status code
assertStatusCode(NOT_FOUND);
}
@Test
public void testDeleteHoldWithReason()
{
String holdName = "Hold" + getRandomAlphanumeric();
String holdDescription = "Description" + getRandomAlphanumeric();
String holdReason = "Reason" + getRandomAlphanumeric();
// Create the hold
Hold hold = Hold.builder()
.name(holdName)
.description(holdDescription)
.reason(holdReason)
.build();
Hold createdHold = getRestAPIFactory().getFilePlansAPI()
.createHold(hold, FILE_PLAN_ALIAS);
nodeRefs.add(createdHold.getId());
// Delete the hold with the reason
getRestAPIFactory().getHoldsAPI()
.deleteHoldWithReason(HoldDeletionReason.builder().reason("Example reason").build(), createdHold.getId());
// Verify the status code
assertStatusCode(OK);
// Try to get the hold
getRestAPIFactory().getHoldsAPI().getHold(createdHold.getId());
// Verify the status code
assertStatusCode(NOT_FOUND);
}
@AfterClass(alwaysRun = true)
public void cleanUpHoldsTests()
{
nodeRefs.forEach(nodeRef -> getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(nodeRef));
}
}

View File

@@ -1,337 +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.fileplancomponents.FilePlanComponentAspects.ASPECTS_VITAL_RECORD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.ASPECTS_VITAL_RECORD_DEFINITION;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertFalse;
import java.io.File;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.core.JsonBodyGenerator;
import org.alfresco.rest.core.v0.BaseAPI.RM_ACTIONS;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.service.DispositionScheduleService;
import org.alfresco.utility.Utility;
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;
/**
* V1 API tests to check actions on frozen content
*
* @author Damian Ujma
*/
public class PreventActionsOnFrozenContentV1Tests extends BaseRMRestTest
{
private static String holdNodeRef;
private static FileModel contentHeld;
private static File updatedFile;
private static FolderModel folderModel;
private static RecordCategoryChild recordFolder;
private static Record recordFrozen;
private static Record recordNotHeld;
private static RecordCategory categoryWithRS;
private Hold hold;
@Autowired
private DispositionScheduleService dispositionScheduleService;
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@BeforeClass(alwaysRun = true)
public void preconditionForPreventActionsOnFrozenContent()
{
String holdOne = "HOLD" + generateTestPrefix(PreventActionsOnFrozenContentV1Tests.class);
STEP("Create a hold.");
hold = createHold(FILE_PLAN_ALIAS,
Hold.builder().name(holdOne).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), getAdminUser());
holdNodeRef = hold.getId();
STEP("Create a test file.");
testSite = dataSite.usingAdmin().createPublicRandomSite();
contentHeld = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Add the file to the hold.");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(contentHeld.getNodeRefWithoutVersion()).build(), hold.getId());
STEP("Get a file resource.");
updatedFile = Utility.getResourceTestDataFile("SampleTextFile_10kb.txt");
STEP("Create a folder withing the test site .");
folderModel = dataContent.usingAdmin().usingSite(testSite)
.createFolder();
STEP("Create a record folder with some records");
recordFolder = createCategoryFolderInFilePlan();
recordFrozen = createElectronicRecord(recordFolder.getId(), getRandomName("elRecordFrozen"));
recordNotHeld = createElectronicRecord(recordFolder.getId(), getRandomName("elRecordNotHeld"));
assertStatusCode(CREATED);
STEP("Add the record to the hold.");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(recordFrozen.getId()).build(), hold.getId());
}
/**
* Given active content on hold
* When I try to edit the properties
* Or perform an action that edits the properties
* Then I am not successful
*/
@Test
public void editPropertiesForContentHeld() throws Exception
{
STEP("Update name property of the held content");
JsonObject nameUpdated = Json.createObjectBuilder().add("name", "HeldNameUpdated").build();
restClient.authenticateUser(getAdminUser()).withCoreAPI().usingNode(contentHeld)
.updateNode(nameUpdated.toString());
STEP("Check the request failed.");
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Frozen content can't be updated.");
}
/*
* Given active content on hold
* When I try to update the content
* Then I am not successful
*/
@Test
public void updateContentForFrozenFile() throws Exception
{
STEP("Update content of the held file");
restClient.authenticateUser(getAdminUser()).withCoreAPI().usingNode(contentHeld).updateNodeContent(updatedFile);
STEP("Check the request failed.");
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
restClient.assertLastError().containsSummary("Frozen content can't be updated.");
}
/*
* Given active content on hold
* When I try to delete the content
* Then I am not successful
*/
@Test
public void deleteFrozenFile() throws Exception
{
STEP("Delete frozen file");
restClient.authenticateUser(getAdminUser()).withCoreAPI().usingNode(contentHeld)
.deleteNode(contentHeld.getNodeRefWithoutVersion());
STEP("Check the request failed.");
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Frozen content can't be deleted.");
}
/**
* Given active content on hold
* When I try to copy the content
* Then I am not successful
*/
@Test
public void copyFrozenFile()
{
STEP("Copy frozen file");
String postBody = JsonBodyGenerator.keyValueJson("targetParentId", folderModel.getNodeRef());
getRestAPIFactory().getNodeAPI(contentHeld).copyNode(postBody);
STEP("Check the request failed.");
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Permission was denied");
}
/**
* Given active content on hold
* When I try to move the content
* Then I am not successful
*/
@Test
public void moveFrozenFile() throws Exception
{
STEP("Move frozen file");
getRestAPIFactory().getNodeAPI(contentHeld).move(createBodyForMoveCopy(folderModel.getNodeRef()));
STEP("Check the request failed.");
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Frozen content can't be moved.");
}
/**
* Given a record folder with a frozen record and another record not held
* When I update the record folder and make the records as vital
* Then I am successful and the records not held are marked as vital
* And the frozen nodes have the vital record search properties updated
*/
@Test
public void updateRecordFolderVitalProperties()
{
STEP("Update the vital record properties for the record folder");
// Create the record folder properties to update
RecordFolder recordFolderToUpdate = RecordFolder.builder()
.properties(RecordFolderProperties.builder()
.vitalRecordIndicator(true)
.reviewPeriod(new ReviewPeriod("month", "1"))
.build())
.build();
// Update the record folder
RecordFolder updatedRecordFolder = getRestAPIFactory().getRecordFolderAPI().updateRecordFolder
(recordFolderToUpdate,
recordFolder.getId());
assertStatusCode(OK);
assertTrue(updatedRecordFolder.getAspectNames().contains(ASPECTS_VITAL_RECORD_DEFINITION));
STEP("Check the frozen record was not marked as vital");
recordFrozen = getRestAPIFactory().getRecordsAPI().getRecord(recordFrozen.getId());
assertFalse(recordFrozen.getAspectNames().contains(ASPECTS_VITAL_RECORD));
assertTrue(recordFrozen.getProperties().getRecordSearchVitalRecordReviewPeriod().contains("month"));
assertTrue(recordFrozen.getProperties().getRecordSearchVitalRecordReviewPeriodExpression().contains("1"));
STEP("Check the record not held was marked as vital");
recordNotHeld = getRestAPIFactory().getRecordsAPI().getRecord(recordNotHeld.getId());
assertTrue(recordNotHeld.getAspectNames().contains(ASPECTS_VITAL_RECORD));
assertNotNull(recordNotHeld.getProperties().getReviewAsOf());
assertTrue(recordNotHeld.getProperties().getRecordSearchVitalRecordReviewPeriod().contains("month"));
assertTrue(recordNotHeld.getProperties().getRecordSearchVitalRecordReviewPeriodExpression().contains("1"));
}
/**
* Given a record folder with a frozen record and another record not held
* When I add a disposition schedule
* Then I am successful
* And the record search disposition schedule properties are updated
*/
@Test
public void createDispositionScheduleOnCategoryWithHeldChildren()
{
STEP("Create a retention schedule on the category with frozen children");
RecordCategory categoryWithRS = getRestAPIFactory().getRecordCategoryAPI()
.getRecordCategory(recordFolder.getParentId());
dispositionScheduleService.createCategoryRetentionSchedule(categoryWithRS.getName(), false);
dispositionScheduleService.addCutOffImmediatelyStep(categoryWithRS.getName());
dispositionScheduleService.addDestroyWithGhostingImmediatelyAfterCutOff(categoryWithRS.getName());
STEP("Check the record folder has a disposition schedule");
RecordFolder folderWithRS = getRestAPIFactory().getRecordFolderAPI().getRecordFolder(recordFolder.getId());
assertNotNull(folderWithRS.getProperties().getRecordSearchDispositionAuthority());
assertNotNull(folderWithRS.getProperties().getRecordSearchDispositionInstructions());
}
/**
* Given a record category with a disposition schedule applied to records
* And the disposition schedule has a retain step immediately and destroy step immediately
* And a complete record added to one hold
* When I execute the retain action
* Then the action is executed
* And the record search disposition schedule properties are updated
*/
@Test
public void retainActionOnFrozenHeldRecords()
{
STEP("Add a category with a disposition schedule.");
categoryWithRS = createRootCategory(getRandomName("CategoryWithRS"));
dispositionScheduleService.createCategoryRetentionSchedule(categoryWithRS.getName(), true);
dispositionScheduleService.addRetainAfterPeriodStep(categoryWithRS.getName(), "immediately");
dispositionScheduleService.addDestroyWithGhostingImmediatelyAfterCutOff(categoryWithRS.getName());
STEP("Create record folder with a record.");
RecordCategoryChild folder = createFolder(categoryWithRS.getId(), getRandomName("RecFolder"));
Record record = createElectronicRecord(folder.getId(), getRandomName("elRecord"));
completeRecord(record.getId());
STEP("Add the record to the hold");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(record.getId()).build(), hold.getId());
STEP("Execute the retain action");
rmRolesAndActionsAPI.executeAction(getAdminUser().getUsername(), getAdminUser().getPassword(), record.getName(),
RM_ACTIONS.END_RETENTION, null, SC_INTERNAL_SERVER_ERROR);
STEP("Check the record search disposition properties");
Record recordUpdated = getRestAPIFactory().getRecordsAPI().getRecord(record.getId());
assertTrue(recordUpdated.getProperties().getRecordSearchDispositionActionName()
.contains(RM_ACTIONS.END_RETENTION.getAction()));
assertTrue(recordUpdated.getProperties().getRecordSearchDispositionPeriod().contains("immediately"));
}
private Hold createHold(String parentId, Hold hold, UserModel user)
{
FilePlanAPI filePlanAPI = getRestAPIFactory().getFilePlansAPI(user);
return filePlanAPI.createHold(hold, parentId);
}
@AfterClass(alwaysRun = true)
public void cleanUpPreventActionsOnFrozenContent()
{
getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(holdNodeRef);
dataSite.usingAdmin().deleteSite(testSite);
deleteRecordCategory(recordFolder.getParentId());
deleteRecordCategory(categoryWithRS.getId());
}
}

View File

@@ -52,7 +52,7 @@ import java.util.Set;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.v0.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.HoldEntry;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserRoles;

View File

@@ -1,374 +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 java.util.Arrays.asList;
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.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
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.model.user.UserRoles.ROLE_RM_MANAGER;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.model.RestNodeAssociationModelCollection;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldChild;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.utils.CoreUtil;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.SiteModel;
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.DataProvider;
import org.testng.annotations.Test;
/**
* V1 API tests for removing content/record folder/record from holds
*
* @author Damian Ujma
*/
public class RemoveFromHoldsV1Tests extends BaseRMRestTest
{
private static final String HOLD_ONE = "HOLD_ONE" + generateTestPrefix(RemoveFromHoldsV1Tests.class);
private static final String HOLD_TWO = "HOLD_TWO" + generateTestPrefix(RemoveFromHoldsV1Tests.class);
private static final String ACCESS_DENIED_ERROR_MESSAGE = "Access Denied. You do not have the appropriate " +
"permissions to perform this operation.";
private SiteModel testSite;
private SiteModel privateSite;
private String holdNodeRefOne;
private FileModel contentHeld;
private FileModel contentAddToManyHolds;
private List<String> holdsListRef = new ArrayList<>();
private final Set<UserModel> usersToBeClean = new HashSet<>();
private final Set<String> nodesToBeClean = new HashSet<>();
@Autowired
private RoleService roleService;
@BeforeClass(alwaysRun = true)
public void preconditionForRemoveContentFromHold()
{
STEP("Create two holds.");
holdNodeRefOne = createHold(FILE_PLAN_ALIAS,
Hold.builder().name(HOLD_ONE).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(),
getAdminUser()).getId();
String holdNodeRefTwo = createHold(FILE_PLAN_ALIAS,
Hold.builder().name(HOLD_TWO).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(),
getAdminUser()).getId();
holdsListRef = asList(holdNodeRefOne, holdNodeRefTwo);
STEP("Create test files.");
testSite = dataSite.usingAdmin().createPublicRandomSite();
privateSite = dataSite.usingAdmin().createPrivateRandomSite();
contentHeld = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
contentAddToManyHolds = dataContent.usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Add content to the holds.");
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(contentHeld.getNodeRefWithoutVersion()).build(), holdNodeRefOne);
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(contentAddToManyHolds.getNodeRefWithoutVersion()).build(),
holdNodeRefOne);
getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(contentAddToManyHolds.getNodeRefWithoutVersion()).build(),
holdNodeRefTwo);
}
/**
* Valid nodes to be removed from hold
*/
@DataProvider(name = "validNodesToRemoveFromHold")
public Object[][] getValidNodesToRemoveFromHold()
{
//create electronic and nonElectronic record in record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
nodesToBeClean.add(recordFolder.getParentId());
Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder.getId(),
getFile
(IMAGE_FILE));
assertStatusCode(CREATED);
Record nonElectronicRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(),
recordFolder.getId());
assertStatusCode(CREATED);
RecordCategoryChild folderToHeld = createCategoryFolderInFilePlan();
nodesToBeClean.add(folderToHeld.getParentId());
Stream.of(electronicRecord.getId(), nonElectronicRecord.getId(), folderToHeld.getId())
.forEach(id -> getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(id).build(), holdNodeRefOne));
return new String[][]
{ // record folder
{ folderToHeld.getId() },
//electronic record
{ electronicRecord.getId() },
// non electronic record
{ nonElectronicRecord.getId() },
// document from collaboration site
{ contentHeld.getNodeRefWithoutVersion() },
};
}
/**
* Given content/record folder/record that is held
* And the corresponding hold
* When I use the existing REST API to remove the node from the hold
* Then the node is removed from the hold
* And is no longer frozen
*/
@Test(dataProvider = "validNodesToRemoveFromHold")
public void removeContentFromHold(String nodeId) throws Exception
{
STEP("Remove node from hold");
getRestAPIFactory()
.getHoldsAPI(getAdminUser()).deleteHoldChild(holdNodeRefOne, nodeId);
STEP("Check the node is not held");
assertFalse(hasAspect(nodeId, FROZEN_ASPECT));
STEP("Check node is not in any hold");
RestNodeAssociationModelCollection holdsEntries = getRestAPIFactory()
.getNodeAPI(CoreUtil.toContentModel(nodeId)).usingParams("where=(assocType='rma:frozenContent')")
.getParents();
assertTrue(holdsEntries.getEntries().isEmpty(), "Content held is still added to a hold.");
}
/**
* Given active content that is held on many holds
* When I use the existing REST API to remove the active content from one hold
* Then the active content is removed from the specific hold
* And is frozen
* And in the other holds
*/
@Test
public void removeContentAddedToManyHolds() throws Exception
{
STEP("Remove content from hold. ");
getRestAPIFactory().getHoldsAPI(getAdminUser())
.deleteHoldChild(holdNodeRefOne, contentAddToManyHolds.getNodeRefWithoutVersion());
STEP("Check the content is held. ");
assertTrue(hasAspect(contentAddToManyHolds.getNodeRefWithoutVersion(), FROZEN_ASPECT));
STEP("Check node is in hold HOLD_TWO. ");
RestNodeAssociationModelCollection holdsEntries = getRestAPIFactory()
.getNodeAPI(CoreUtil.toContentModel(contentAddToManyHolds.getNodeRefWithoutVersion()))
.usingParams("where=(assocType='rma:frozenContent')").getParents();
assertFalse(holdsEntries.getEntries().isEmpty(), "Content held is not held after removing from one hold.");
assertTrue(holdsEntries.getEntries().stream()
.anyMatch(restNodeModel -> restNodeModel.getModel().getName().equals(HOLD_TWO)),
"Content held is not held after removing from one hold.");
}
/**
* Data provider with user without right permission or capability to remove from hold a specific node
*
* @return user model and the node ref to be removed from hold
*/
@DataProvider(name = "userWithoutPermissionForRemoveFromHold")
public Object[][] getUserWithoutPermissionForAddToHold()
{
//create record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
nodesToBeClean.add(recordFolder.getParentId());
UserModel user = roleService.createUserWithRMRole(ROLE_RM_MANAGER.roleId);
getRestAPIFactory().getRMUserAPI().addUserPermission(holdNodeRefOne, user, PERMISSION_FILING);
//create files that will be removed from hold
FileModel contentNoHoldPerm = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
FileModel contentNoHoldCap = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
FileModel privateFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
//add files to hold
asList(recordFolder.getId(), contentNoHoldCap.getNodeRefWithoutVersion(),
contentNoHoldPerm.getNodeRefWithoutVersion(), privateFile.getNodeRefWithoutVersion())
.forEach(id -> getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(id).build(), holdNodeRefOne));
return new Object[][]
{
// user with read permission on the content, with remove from hold capability and without
// filling permission on a hold
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole.SiteCollaborator,
holdNodeRefOne, UserRoles.ROLE_RM_MANAGER, PERMISSION_READ_RECORDS),
contentNoHoldPerm.getNodeRefWithoutVersion()
},
// user with write permission on the content, filling permission on a hold without remove from
// hold capability
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole
.SiteCollaborator,
holdNodeRefOne, UserRoles.ROLE_RM_POWER_USER, PERMISSION_FILING),
contentNoHoldCap.getNodeRefWithoutVersion()
},
//user without read permission on RM record folder
{
user, recordFolder.getId()
},
//user without read permission over the content from the private site
{
user, privateFile.getNodeRefWithoutVersion()
}
};
}
/**
* Given node on hold in a single hold location
* And the user does not have sufficient permissions or capabilities to remove the node from the hold
* When the user tries to remove the node from the hold
* Then it's unsuccessful
*
* @throws Exception
*/
@Test(dataProvider = "userWithoutPermissionForRemoveFromHold")
public void removeFromHoldWithUserWithoutPermission(UserModel userModel, String nodeIdToBeRemoved) throws Exception
{
STEP("Update the list of users to be deleted after running the tests");
usersToBeClean.add(userModel);
STEP("Remove node from hold with user without right permission or capability");
getRestAPIFactory().getHoldsAPI(userModel).deleteHoldChild(holdNodeRefOne, nodeIdToBeRemoved);
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary(ACCESS_DENIED_ERROR_MESSAGE);
STEP("Check node is frozen.");
assertTrue(hasAspect(nodeIdToBeRemoved, FROZEN_ASPECT));
}
/**
* Data provider with user with right permission or capability to remove from hold a specific node
*
* @return user model and the node ref to be removed from hold
*/
@DataProvider(name = "userWithPermissionForRemoveFromHold")
public Object[][] getUserWithPermissionForAddToHold()
{
//create record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
nodesToBeClean.add(recordFolder.getParentId());
UserModel user = roleService.createUserWithRMRoleAndRMNodePermission(ROLE_RM_MANAGER.roleId,
recordFolder.getId(),
PERMISSION_READ_RECORDS);
getRestAPIFactory().getRMUserAPI().addUserPermission(holdNodeRefOne, user, PERMISSION_FILING);
//create file that will be removed from hold
FileModel contentPermission = dataContent.usingAdmin().usingSite(testSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
//add files to hold
asList(recordFolder.getId(), contentPermission.getNodeRefWithoutVersion())
.forEach(id -> getRestAPIFactory()
.getHoldsAPI(getAdminUser())
.addChildToHold(HoldChild.builder().id(id).build(), holdNodeRefOne));
return new Object[][]
{
// user with write permission on the content
{
roleService.createUserWithSiteRoleRMRoleAndPermission(testSite, UserRole.SiteConsumer,
holdNodeRefOne, UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING),
contentPermission.getNodeRefWithoutVersion()
},
//user with read permission on RM record folder
{
user, recordFolder.getId()
},
};
}
@Test(dataProvider = "userWithPermissionForRemoveFromHold")
public void removeFromHoldWithUserWithPermission(UserModel userModel, String nodeIdToBeRemoved) throws Exception
{
STEP("Update the list of users to be deleted after running the tests");
usersToBeClean.add(userModel);
STEP("Remove node from hold with user with right permission and capability");
getRestAPIFactory().getHoldsAPI(userModel).deleteHoldChild(holdNodeRefOne, nodeIdToBeRemoved);
STEP("Check node is not frozen.");
assertFalse(hasAspect(nodeIdToBeRemoved, FROZEN_ASPECT));
}
private Hold createHold(String parentId, Hold hold, UserModel user)
{
FilePlanAPI filePlanAPI = getRestAPIFactory().getFilePlansAPI(user);
return filePlanAPI.createHold(hold, parentId);
}
@AfterClass(alwaysRun = true)
public void cleanUpRemoveContentFromHold()
{
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(holdRef));
dataSite.usingAdmin().deleteSite(testSite);
dataSite.usingAdmin().deleteSite(privateSite);
usersToBeClean.forEach(user -> getDataUser().usingAdmin().deleteUser(user));
nodesToBeClean.forEach(this::deleteRecordCategory);
}
}

View File

@@ -62,7 +62,6 @@ import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
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.utils.AlfrescoRetryAnalyzer;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.model.UserModel;
@@ -290,11 +289,10 @@ public class UpdateRecordsTests extends BaseRMRestTest
* </pre>
*/
@Test
(
dataProvider = "completeRecords",
description = "Complete records can't be updated",
retryAnalyzer = AlfrescoRetryAnalyzer.class
)
(
dataProvider = "completeRecords",
description = "Complete records can't be updated"
)
@AlfrescoTest(jira="RM-4362")
@Bug (id = "APPS-132")
public void completeRecordsCantBeUpdated(String electronicRecordId, String nonElectronicRecordId)

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -1,44 +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.utils;
import org.testng.ITestResult;
import org.testng.util.RetryAnalyzerCount;
public class AlfrescoRetryAnalyzer extends RetryAnalyzerCount
{
public AlfrescoRetryAnalyzer() {
super();
setCount(3);
}
@Override
public boolean retryMethod(ITestResult result)
{
return true;
}
}

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -45,9 +45,9 @@ serverHealth.showTenants=false
# testManagement.username=<username>
# testManagement.apiKey=<api-key>
# 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.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.enabled=false
@@ -72,7 +72,7 @@ reports.path=./target/reports
#
# MySQL:
# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
#
#
# PostgreSQL:
# db.url = jdbc:postgresql://<your-DB-IP>:3306/alfresco
#

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>23.4.0.1</version>
<version>23.1.1.13-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -139,26 +139,3 @@ content.metadata.async.extract.6.enabled=false
# Max number of entries returned in Record search view
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

View File

@@ -31,11 +31,6 @@
<cm:description>Configuration information for the Records Management application.</cm:description>
</view:properties>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<view:associations>
<cm:contains>

View File

@@ -33,7 +33,7 @@ function main()
{
// Log debug message
logger.log("Record " + node.name + " has been superseded. Sending notification");
// Send notification
rmService.sendSupersededNotification(node);
}

View File

@@ -125,7 +125,7 @@
parent="declarativeCapability">
<property name="name" value="DeleteRecordFolder"/>
<property name="private" value="true"/>
<property name="permission" value="DeleteRecords"/>
<property name="permission" value="CreateModifyDestroyFolders"/>
<property name="kinds">
<list>
<value>RECORD_FOLDER</value>

View File

@@ -538,11 +538,6 @@
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="rma:holdDeletionReason">
<title>Hold Deletion Reason</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
</properties>
<associations>

View File

@@ -89,9 +89,6 @@
<!-- Import RM Audit -->
<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 resource="classpath:alfresco/module/org_alfresco_module_rm/query/rm-query-context.xml" />

View File

@@ -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>

View File

@@ -31,7 +31,6 @@
<property name="personService" ref="PersonService"/>
<property name="dispositionService" ref="DispositionService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
</bean>
<bean id="searchTypesFactory" class="org.alfresco.rm.rest.api.impl.SearchTypesFactory">
@@ -70,40 +69,7 @@
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.fileplans.FilePlanHoldsRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="holdService" ref="HoldService" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.holds.HoldsEntityResource" >
<property name="holdService" ref="HoldService" />
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<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 class="org.alfresco.rm.rest.api.holds.HoldsChildrenRelation">
<property name="holdService" ref="HoldService" />
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="transactionService" ref="transactionService" />
<property name="permissionService" ref="PermissionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.unfiledcontainers.UnfiledContainerEntityResource">
<bean class="org.alfresco.rm.rest.api.unfiledcontainers.UnfiledContainerEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
@@ -148,20 +114,6 @@
<property name="transactionService" ref="transactionService" />
</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">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />

View File

@@ -1614,8 +1614,6 @@
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.createHold=RM_CAP.0.rma:filePlanComponent.CreateHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHoldReason=RM.Read.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.setHoldReason=RM_CAP.0.rma:filePlanComponent.EditHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.setHoldDeletionReason=RM_CAP.0.rma:filePlanComponent.EditHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.updateHold=RM_CAP.0.rma:filePlanComponent.EditHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.deleteHold=RM_CAP.0.rma:filePlanComponent.DeleteHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHold=RM_CAP.0.rma:filePlanComponent.AddToHold
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHolds=RM_ALLOW

View File

@@ -99,10 +99,10 @@ function main()
{
version = versionHistory[i];
p = getPerson(version.creator);
recordNodeRef = version.getVersionProperty("recordNodeRef");
isRecordedVersionDestroyed = version.getVersionProperty("RecordedVersionDestroyed");
versions[versions.length] =
{
nodeRef: version.node.nodeRef.toString(),

View File

@@ -26,19 +26,19 @@
*/
/**
* Delete the rm constraint list
*/
*/
function main()
{
// Get the shortname
var shortName = url.extension;
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
caveatConfig.deleteConstraintList(shortName);
// Pass the constraint name to the template
model.constraintName = shortName;
}

View File

@@ -26,15 +26,15 @@
*/
/**
* Get the detail of the rm constraint
*/
*/
function main()
{
// Get the shortname
var shortName = url.extension;
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
// Pass the constraint detail to the template

View File

@@ -26,14 +26,14 @@
*/
/**
* List the names of the rm constraints
*/
*/
function main()
{
var wel = true;
var withEmptyLists = args["withEmptyLists"];
// Pass the information to the template
if (withEmptyLists != null && withEmptyLists === 'false')
{
{
model.constraints = caveatConfig.constraintsWithoutEmptyList;
}
else

View File

@@ -26,15 +26,15 @@
*/
/**
* Get the detail of the rm constraint
*/
*/
function main()
{
var urlElements = url.extension.split("/");
var shortName = urlElements[0];
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
// Pass the constraint detail to the template

View File

@@ -26,33 +26,33 @@
*/
/**
* Update the details of a value in an rm constraint
*/
*/
function main()
{
var urlElements = url.extension.split("/");
var shortName = urlElements[0];
var values = null;
if (json.has("values"))
{
values = json.getJSONArray("values");
}
if (values == null)
{
status.setCode(status.STATUS_BAD_REQUEST, "Values missing");
return;
}
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
constraint.updateValues(values);
constraint.updateValues(values);
model.constraint = caveatConfig.getConstraint(shortName);
model.constraintName = shortName;
model.constraintName = shortName;
}
else
{

View File

@@ -26,13 +26,13 @@
*/
/**
* Delete the rm constraint list
*/
*/
function main()
{
var urlElements = url.extension.split("/");
var shortName = urlElements[0];
var authorityName = urlElements[1];
if (shortName == null)
{
status.setCode(status.STATUS_BAD_REQUEST, "shortName missing");
@@ -43,16 +43,16 @@ function main()
status.setCode(status.STATUS_BAD_REQUEST, "value missing");
return;
}
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
caveatConfig.deleteRMConstraintListValue(shortName, valueName);
var constraint = caveatConfig.getConstraint(shortName);
// Pass the constraint name to the template
model.constraint = constraint;
}

View File

@@ -26,28 +26,28 @@
*/
/**
* Get the detail of the rm constraint
*/
*/
function main()
{
var urlElements = url.extension.split("/");
var shortName = decodeURIComponent(urlElements[0]);
var valueName = decodeURIComponent(urlElements[2])
// Get the constraint
var constraint = caveatConfig.getConstraint(shortName);
if (constraint != null)
{
// Pass the constraint detail to the template
var value = constraint.getValue(valueName);
if(value == null)
{
// Return 404
status.setCode(404, "Constraint List: " + shortName + " value: " + valueName + "does not exist");
return;
}
model.value = value;
model.constraint = constraint;
}

View File

@@ -114,7 +114,7 @@ function getRecordSeries(seriesNode)
// Create Record Series object
var recordSerie = {
parentPath: "/",
name: seriesNode.name,
name: seriesNode.name,
identifier: seriesNode.properties["rma:identifier"],
description: seriesNode.properties["description"]
};
@@ -154,7 +154,7 @@ function getRecordCategory(categoryNode, parentPath)
name: categoryNode.name,
identifier: categoryNode.properties["rma:identifier"],
vitalRecordIndicator: categoryNode.properties["vitalRecordIndicator"],
dispositionAuthority: categoryNode.properties["dispositionAuthority"],
dispositionAuthority: categoryNode.properties["dispositionAuthority"],
recordFolders: [],
dispositionActions: []
};

View File

@@ -36,12 +36,12 @@ function main()
status.setCode(status.STATUS_NOT_FOUND, "Site not found: '" + siteId + "'");
return null;
}
var searchNode = siteNode.getContainer("Saved Searches");
if (searchNode != null)
{
var kids, ssNode;
if (bPublic == null || bPublic == "true")
{
// public searches are in the root of the folder
@@ -56,7 +56,7 @@ function main()
kids = userNode.children;
}
}
if (kids)
{
for (var i = 0, ii = kids.length; i < ii; i++)
@@ -73,7 +73,7 @@ function main()
}
}
}
model.savedSearches = savedSearches;
}

View File

@@ -40,7 +40,7 @@ function main()
status.setCode(status.STATUS_BAD_REQUEST, "nodeRef: '" + nodeRef + "' is not of type 'rma:transfer'");
return null;
}
model.transfer = transfer;
}

View File

@@ -33,7 +33,7 @@
/**
* Live Search Component
*
*
* Takes the following object as Input:
* params
* {
@@ -41,7 +41,7 @@
* term: search terms
* maxResults: maximum results to return
* };
*
*
* Outputs:
* items - Array of objects containing the search results
*/
@@ -53,7 +53,7 @@ const SURF_CONFIG_QNAMEPATH = "/cm:surf-config/";
/**
* Returns site information data structure.
* { shortName: siteId, title: title }
*
*
* Caches the data to avoid repeatedly querying the repository.
*/
var siteDataCache = {};
@@ -134,13 +134,13 @@ function getDocumentItem(container, node) {
}
}
}
return item;
}
/**
* Splits the qname path to a node.
*
*
* Returns container meta object containing the following properties:
* siteId
* containerId
@@ -151,7 +151,7 @@ function splitQNamePath(node) {
siteId: null,
containerId: null
};
if (path.match("^"+SITES_SPACE_QNAME_PATH) == SITES_SPACE_QNAME_PATH)
{
var tmp = path.substring(SITES_SPACE_QNAME_PATH.length),
@@ -167,13 +167,13 @@ function splitQNamePath(node) {
// strip container id from the path
var containerId = tmp.substring(0, pos);
containerId = containerId.substring(containerId.indexOf(":") + 1);
container.siteId = siteId;
container.containerId = containerId;
}
}
}
return container;
}
@@ -197,36 +197,36 @@ function liveSearch(params) {
/**
* Return Document Search results with the given search terms.
*
*
* "AND" is the default operator unless configured otherwise, OR, AND and NOT are also supported -
* as is any other valid fts-alfresco elements such as "quoted terms" and (bracket terms) and also
* propname:propvalue syntax.
*
*
* @param params Object containing search parameters - see API description above
*/
function getDocResults(params) {
// ensure a TYPE is specified
var ftsQuery = params.term + ' AND +TYPE:"cm:content"';
// site constraint
if (params.siteId !== null)
{
// use SITE syntax to restrict to specific site
ftsQuery += ' AND SITE:"' + params.siteId + '"';
}
// root node - generally used for overridden Repository root in Share
if (params.rootNode !== null)
{
ftsQuery = 'PATH:"' + rootNode.qnamePath + '//*" AND (' + ftsQuery + ')';
}
// main query construction
ftsQuery = '(' + ftsQuery + ') AND -TYPE:"cm:thumbnail" AND -TYPE:"cm:failedThumbnail" AND -TYPE:"cm:rating" AND -TYPE:"fm:post" AND -ASPECT:"sys:hidden" AND -ASPECT:"rma:savedSearch" AND -cm:creator:system';
if (logger.isLoggingEnabled())
logger.log("LiveQuery:\r\n" + ftsQuery);
// get default fts operator from the config
//
// TODO: common search lib - for both live and standard e.g. to get values like this...
@@ -237,7 +237,7 @@ function getDocResults(params) {
{
operator = cf.toString();
}
// perform fts-alfresco language query
var queryDef = {
query: ftsQuery,
@@ -254,10 +254,10 @@ function getDocResults(params) {
var rs = search.queryResultSet(queryDef);
nodes = rs.nodes,
results = [];
if (logger.isLoggingEnabled())
logger.log("Processing resultset of length: " + nodes.length);
for (var i=0, item; i<nodes.length && i<params.maxResults; i++)
{
// For each node we extract the site/container qname path and then
@@ -279,13 +279,13 @@ function getDocResults(params) {
}
}
}
return buildResults(results, params, rs.meta.hasMore);
}
/**
* Return Site Search results with the given search terms.
*
*
* @param params Object containing search parameters - see API description above
*/
function getSiteResults(params) {
@@ -297,7 +297,7 @@ function getSiteResults(params) {
/**
* Return People Search results with the given search terms.
*
*
* @param params Object containing search parameters - see API description above
*/
function getPeopleResults(params) {

View File

@@ -41,8 +41,6 @@ services:
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
-Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
-DlocalTransform.core-aio.url=http://transform-core-aio:8090/
-Drm.hold.bulk.maxItems=5
-Drm.hold.bulk.batchSize=2
"
ports:
- 8080:8080

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>23.4.0.1</version>
<version>23.1.1.13-SNAPSHOT</version>
</parent>
<properties>
@@ -84,11 +84,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
@@ -155,12 +150,6 @@
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${dependency.awaitility.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -27,7 +27,6 @@
package org.alfresco.module.org_alfresco_module_rm.audit.event;
import static org.alfresco.module.org_alfresco_module_rm.audit.event.HoldUtils.HOLD_DELETION_REASON;
import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.EVERY_EVENT;
import java.io.Serializable;
@@ -78,8 +77,6 @@ public class DeleteHoldAuditEvent extends AuditEvent implements NodeServicePolic
public void beforeDeleteNode(NodeRef holdNodeRef)
{
Map<QName, Serializable> auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService);
auditProperties.put(HOLD_DELETION_REASON, nodeService.getProperty(holdNodeRef, PROP_HOLD_DELETION_REASON));
recordsManagementAuditService.auditEvent(holdNodeRef, getName(), auditProperties, null, true, false);
}
}

View File

@@ -47,7 +47,6 @@ class HoldUtils
{
/** A QName to display for the hold name. */
public static final QName HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name");
public static final QName HOLD_DELETION_REASON = QName.createQName(RecordsManagementModel.RM_URI, "Hold deletion reason");
/** A QName to display for the hold node ref. */
public static final QName HOLD_NODEREF = QName.createQName(RecordsManagementModel.RM_URI, "Hold NodeRef");

View File

@@ -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;
}
}

View File

@@ -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)
{
}

View File

@@ -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);
}

View File

@@ -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");
}
}
}

View File

@@ -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)
{
}

View File

@@ -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();
}

View File

@@ -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
}
}

Some files were not shown because too many files have changed in this diff Show More