Compare commits

..

410 Commits

Author SHA1 Message Date
alfresco-build
dee3674494 [maven-release-plugin][skip ci] prepare release 23.3.0.67 2024-07-10 09:41:24 +00:00
dependabot[bot]
91b91e3dee Bump org.projectlombok:lombok from 1.18.30 to 1.18.34 (#2729)
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.30 to 1.18.34.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.30...v1.18.34)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:43:54 +02:00
dependabot[bot]
c085d42531 Bump org.codehaus.groovy:groovy from 3.0.19 to 3.0.22 (#2733)
Bumps [org.codehaus.groovy:groovy](https://github.com/apache/groovy) from 3.0.19 to 3.0.22.
- [Commits](https://github.com/apache/groovy/commits)

---
updated-dependencies:
- dependency-name: org.codehaus.groovy:groovy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:08:02 +02:00
dependabot[bot]
d0323836ad Bump org.codehaus.cargo:cargo-maven3-plugin from 1.10.9 to 1.10.14 (#2735)
Bumps org.codehaus.cargo:cargo-maven3-plugin from 1.10.9 to 1.10.14.

---
updated-dependencies:
- dependency-name: org.codehaus.cargo:cargo-maven3-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:07:35 +02:00
dependabot[bot]
628d299980 Bump org.apache.httpcomponents.core5:httpcore5 from 5.2.3 to 5.2.5 (#2736)
Bumps [org.apache.httpcomponents.core5:httpcore5](https://github.com/apache/httpcomponents-core) from 5.2.3 to 5.2.5.
- [Changelog](https://github.com/apache/httpcomponents-core/blob/rel/v5.2.5/RELEASE_NOTES.txt)
- [Commits](https://github.com/apache/httpcomponents-core/compare/rel/v5.2.3...rel/v5.2.5)

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents.core5:httpcore5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:06:59 +02:00
dependabot[bot]
b532ba9d54 Bump org.springframework.security:spring-security-bom (#2698)
Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/spring-projects/spring-security/releases)
- [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc)
- [Commits](https://github.com/spring-projects/spring-security/compare/6.3.0...6.3.1)

---
updated-dependencies:
- dependency-name: org.springframework.security:spring-security-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:05:29 +02:00
dependabot[bot]
195f5b1a8c Bump org.assertj:assertj-core from 3.24.2 to 3.26.3 (#2769)
Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.24.2 to 3.26.3.
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.24.2...assertj-build-3.26.3)

---
updated-dependencies:
- dependency-name: org.assertj:assertj-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 09:04:41 +02:00
alfresco-build
c8718ca722 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-07 00:11:08 +00:00
alfresco-build
9a48b09f32 [maven-release-plugin][skip ci] prepare release 23.3.0.66 2024-07-07 00:11:06 +00:00
Alfresco CI User
3421bcb532 [force] Force release for 2024-07-07. 2024-07-07 00:03:55 +00:00
alfresco-build
e3175e9a98 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-04 16:22:54 +00:00
alfresco-build
f5c71e6098 [maven-release-plugin][skip ci] prepare release 23.3.0.65 2024-07-04 16:22:52 +00:00
Sara
725ef34ccb Merge pull request #2738 from Alfresco/feature/ACS-8294_Bump_SS-IE_to_2.0.11
ACS-8294 Bump SS/IE to 2.0.11
2024-07-04 16:44:24 +01:00
Sara Aspery
b7224b3d20 Bump SS/IE to 2.0.11 2024-07-04 13:51:50 +01:00
alfresco-build
24c6abedb5 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-04 11:22:18 +00:00
alfresco-build
bf2f123aa7 [maven-release-plugin][skip ci] prepare release 23.3.0.64 2024-07-04 11:22:16 +00:00
Piotr Żurek
0e90fe9710 ACS-8289 Bump ATS (#2737) 2024-07-04 12:34:53 +02:00
alfresco-build
638058629d [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-03 13:38:48 +00:00
alfresco-build
0e7660be83 [maven-release-plugin][skip ci] prepare release 23.3.0.63 2024-07-03 13:38:45 +00:00
SathishK-T
35b4ad5dbe [APPS-2905][APPS-2906][APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's (#2732)
* [APPS-2907][APPS-2909] Validation Changes in Retention Schedule V1 API

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

* [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-07-03 18:32:42 +05:30
alfresco-build
90b91b87ef [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-30 00:06:31 +00:00
alfresco-build
bfce7cf3ad [maven-release-plugin][skip ci] prepare release 23.3.0.62 2024-06-30 00:06:29 +00:00
Alfresco CI User
03a261c4c5 [force] Force release for 2024-06-30. 2024-06-30 00:03:41 +00:00
alfresco-build
4b3558ff12 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-28 12:32:43 +00:00
alfresco-build
4355add778 [maven-release-plugin][skip ci] prepare release 23.3.0.61 2024-06-28 12:32:41 +00:00
SathishK-T
92fbaf29d4 [APPS-2838][APPS-2839] POST and GET API implementation for the Retention Schedule Steps (#2721)
* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

* [APPS-2838][APPS-2839] Fixed Junit Testcases

* [APPS-2838][APPS-2839] Retention Schedule Step POST and GET API

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
Co-authored-by: suneet-gupta <suneet.gupta@hyland.com>
2024-06-28 17:26:17 +05:30
alfresco-build
8e15dba3eb [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-27 04:39:04 +00:00
alfresco-build
2206479e06 [maven-release-plugin][skip ci] prepare release 23.3.0.60 2024-06-27 04:39:02 +00:00
Suneet Gupta
abeaff52e8 [APPS-2019] Add Undeletable and Unmovable Aspects to Data Dictionary and its Level 1 sub-folders (#2705)
* [force] Force release for 2024-06-09.

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder

* [APPS-2019] [ags] [tas] Added Integration Test Cases

* [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary

* [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary

* Added Undeletable and Unmovable Aspects to Data Dictionary Folder

* [APPS-2019] Updated Integration Test Cases

* [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary

* [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

* [APPS-2019] [ags] [tas] Addressed review comments

---------

Co-authored-by: Alfresco CI User <build@alfresco.com>
2024-06-27 10:05:57 +05:30
alfresco-build
76be8d2bec [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-26 13:28:59 +00:00
alfresco-build
ce27304eae [maven-release-plugin][skip ci] prepare release 23.3.0.59 2024-06-26 13:28:56 +00:00
Damian Ujma
060cf3aa3c ACS-8048 Fix HXIAM access token validation issues (#2706)
* ACS-8047: WIP - Fixed HXIAM access token validation issues.

* ACS-8048 Accept at+jwt token + make signature algorithm configurable

* ACS-8048 Accept multiple signature algorithms

* ACS-8048 Fix PMD issue

* ACS-8048 Log using the default signature algorithm

* ACS-8048 Refactor

---------

Co-authored-by: Jamal Kaabi-Mofrad <jamal.kaabimofrad@alfresco.com>
2024-06-26 13:47:08 +02:00
SathishK-T
f1fdf72c5b [APPS-2836][APPS-2837] Retention Schedule POST and GET API (#2704)
* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

* [APPS-2836][APPS-2837] POST and GET API for Retention Schedule

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-06-26 16:48:25 +05:30
alfresco-build
b580a52459 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-25 14:45:09 +00:00
alfresco-build
d13da0cdfa [maven-release-plugin][skip ci] prepare release 23.3.0.58 2024-06-25 14:45:07 +00:00
SathishK-T
ca236d9814 [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs (#2672)
* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

* [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-06-25 19:34:58 +05:30
alfresco-build
8398a5dca0 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-23 00:06:44 +00:00
alfresco-build
52731727c6 [maven-release-plugin][skip ci] prepare release 23.3.0.57 2024-06-23 00:06:42 +00:00
Alfresco CI User
2f45231149 [force] Force release for 2024-06-23. 2024-06-23 00:03:45 +00:00
alfresco-build
447d0c4f56 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-19 11:19:32 +00:00
alfresco-build
5e920054f4 [maven-release-plugin][skip ci] prepare release 23.3.0.56 2024-06-19 11:19:30 +00:00
Damian Ujma
2f66f068a6 ACS-7556 Bulk update in Legal Holds (#2692)
* ACS-7557 Add Legal Holds Bulk v1 API (#2624)

* ACS-7557 Add Legal Holds Bulk v1 API

* ACS-7557 Improve v1 API

* ACS-7557 Replace processId with bulkStatusId

* ACS-7587 Implement v1 Bulk API to add items to a hold (#2656)

* ACS-7557 Add bulk API design

* ACS-7557 Fix 

* ACS-7557 Add permissions checks 

* ACS-7557 Add IT tests

* ACS-7557 Add comments + logging

* ACS-7557 Refactor

* ACS-7557 Reimplement task container

* ACS-7557 Refactor code

* ACS-7587 Remove merge leftovers

* ACS-7587 Refactor 

* ACS-7587 Tests 

* ACS-7587 Change DefaultHoldBulkMonitor

* ACS-7587 Reimplement BulkStatusUpdater

* ACS-7587 Fix PMD issues

* ACS-7587 Fix PMD isues

* ACS-7587 Refactor

* ACS-7587 Add test files alternately

* ACS-7587 Refactor code

* ACS-7587 Improve search query

* ACS-7587 Fix PMD issues

* ACS-7587 Fix PMD issue

* ACS-7587 Fix intermittent failure

* ACS7587 Fix intermittent failure (#2681)

* ACS-7587 Implement bulk cancellations (#2683)
2024-06-19 12:44:07 +02:00
alfresco-build
2461b75f61 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-19 10:27:46 +00:00
alfresco-build
96231517bd [maven-release-plugin][skip ci] prepare release 23.3.0.55 2024-06-19 10:27:44 +00:00
mikolajbrzezinski
b73b8df892 ACS-6931 Re-enable Veracode SAST Scan (#2690)
ACS-6931 Re-enable Veracode SAST Scan
2024-06-19 11:51:40 +02:00
alfresco-build
08e49c98dd [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-18 07:43:10 +00:00
alfresco-build
ba50617181 [maven-release-plugin][skip ci] prepare release 23.3.0.54 2024-06-18 07:43:08 +00:00
Sara
0d621badd7 Merge pull request #2696 from Alfresco/feature/MNT-24205_Bump_ATS_to_4.1.3-A2
MNT-24205 Bump t-core to 5.1.3-A3 and t-service to 4.1.3-A2
2024-06-18 08:07:03 +01:00
alfresco-build
661ddce806 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-17 14:37:53 +00:00
alfresco-build
aa8b0256e1 [maven-release-plugin][skip ci] prepare release 23.3.0.53 2024-06-17 14:37:50 +00:00
tiagosalvado10
8990581cc1 MNT-24205 Bump t-core to 5.1.3-A3 and t-service to 4.1.3-A2 2024-06-17 14:56:44 +01:00
Kacper Magdziarz
04d76a182a Bump SS/IE to 2.0.11-A6 (#2694) 2024-06-17 15:20:02 +02:00
alfresco-build
27fbf633df [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-17 11:22:54 +00:00
alfresco-build
358ca8dc9e [maven-release-plugin][skip ci] prepare release 23.3.0.52 2024-06-17 11:22:51 +00:00
rrajoria
9a25862cc9 Update Aos alpha version 2024-06-17 16:05:53 +05:30
alfresco-build
ac7e58ddc5 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-16 00:06:38 +00:00
alfresco-build
6bcaa1be04 [maven-release-plugin][skip ci] prepare release 23.3.0.51 2024-06-16 00:06:36 +00:00
Alfresco CI User
a1bf0f5480 [force] Force release for 2024-06-16. 2024-06-16 00:03:32 +00:00
alfresco-build
2c3d5dd297 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-09 00:07:41 +00:00
alfresco-build
6b32d96f08 [maven-release-plugin][skip ci] prepare release 23.3.0.50 2024-06-09 00:07:38 +00:00
Alfresco CI User
69dd388133 [force] Force release for 2024-06-09. 2024-06-09 00:04:05 +00:00
alfresco-build
29106d307f [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-07 11:35:11 +00:00
alfresco-build
ef8b3578df [maven-release-plugin][skip ci] prepare release 23.3.0.49 2024-06-07 11:35:08 +00:00
Domenico Sibilio
dc5128b447 ACS-8114 Bump TAS utility to 5.0.1 (#2684) 2024-06-07 12:58:40 +02:00
alfresco-build
741ac97c3b [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-06 12:07:03 +00:00
alfresco-build
3f5cb68250 [maven-release-plugin][skip ci] prepare release 23.3.0.48 2024-06-06 12:07:00 +00:00
dependabot[bot]
fdb4f9e338 Bump org.springframework.security:spring-security-bom from 6.2.2 to 6.3.0 (#2658)
updated-dependencies:
- dependency-name: org.springframework.security:spring-security-bom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-06 13:29:18 +02:00
alfresco-build
f3f3a1db4b [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-05 16:18:58 +00:00
alfresco-build
eb922e1c95 [maven-release-plugin][skip ci] prepare release 23.3.0.47 2024-06-05 16:18:55 +00:00
Domenico Sibilio
46da34fabd ACS-8071 Bump bouncycastle to 1.78.1 (#2682) 2024-06-05 17:42:17 +02:00
alfresco-build
7dee8314fb [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-04 08:47:09 +00:00
alfresco-build
f888f8244e [maven-release-plugin][skip ci] prepare release 23.3.0.46 2024-06-04 08:47:07 +00:00
Kacper Magdziarz
8e3eeb9dd7 [ACS-5648] Add header 'X-Alfresco-Retry-Needed' indicating that recovery mode is on and client should retry later (#2670)
* [ACS-5648] Add header'X-Alfresco-Retry-Needed' indicating that recovery mode is on and client should retry later

* [ACS-5648] Bump ATS to 4.1.3-A1
2024-06-04 10:11:40 +02:00
alfresco-build
012d2f37c7 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-03 18:42:01 +00:00
alfresco-build
f5f73162bd [maven-release-plugin][skip ci] prepare release 23.3.0.45 2024-06-03 18:41:58 +00:00
Piotr Żurek
e7a83f2641 ACS-8077 Bump Netty and Camel (#2678) 2024-06-03 19:56:14 +02:00
alfresco-build
2a300f9b7c [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-03 11:00:19 +00:00
alfresco-build
ac0ed124aa [maven-release-plugin][skip ci] prepare release 23.3.0.44 2024-06-03 11:00:17 +00:00
Tom Page
cee2da9700 Merge pull request #2661 from Alfresco/feature/PRODENG-276_implement_service_accounts
PRODENG-276: Implement service accounts
2024-06-03 11:24:12 +01:00
alfresco-build
2bc914b649 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-02 00:06:43 +00:00
alfresco-build
dcd381923e [maven-release-plugin][skip ci] prepare release 23.3.0.43 2024-06-02 00:06:41 +00:00
Alfresco CI User
bcf5d1b2c0 [force] Force release for 2024-06-02. 2024-06-02 00:03:31 +00:00
Jamal Kaabi-Mofrad
89dd6f7b35 PRODENG-276: Addressed minor comments from peer review. 2024-05-31 14:49:44 +01:00
Jamal Kaabi-Mofrad
c82e8d652a PRODENG-276: Resolved peer review comments. 2024-05-30 17:29:04 +01:00
Jamal Kaabi-Mofrad
a9a911e77f PRODENG-276: Resolved PMD issues. 2024-05-30 17:06:24 +01:00
Jamal Kaabi-Mofrad
e59bb3261c PRODENG-276: Fixed test failures. 2024-05-30 15:57:46 +01:00
alfresco-build
dbcb54369a [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-27 14:44:21 +00:00
alfresco-build
b50a022e48 [maven-release-plugin][skip ci] prepare release 23.3.0.42 2024-05-27 14:44:18 +00:00
Domenico Sibilio
799db5f212 ACS-7569 Test with Keycloak 24.0.3 (#2663) 2024-05-27 15:57:08 +02:00
alfresco-build
975976db18 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-26 00:06:33 +00:00
alfresco-build
809fa28023 [maven-release-plugin][skip ci] prepare release 23.3.0.41 2024-05-26 00:06:31 +00:00
Alfresco CI User
d28359c168 [force] Force release for 2024-05-26. 2024-05-26 00:03:40 +00:00
Jamal Kaabi-Mofrad
d999558b33 PRODENG-276: Cleanup - Fixed inconsistent spacing issues. 2024-05-24 16:04:49 +01:00
Jamal Kaabi-Mofrad
897bfa8410 PRODENG-276: Implemented three distinct service account roles with varying access levels. 2024-05-24 15:54:10 +01:00
alfresco-build
a3b13ed8de [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-20 08:04:40 +00:00
alfresco-build
ea66b9e4f3 [maven-release-plugin][skip ci] prepare release 23.3.0.40 2024-05-20 08:04:38 +00:00
Kacper Magdziarz
0a5827e37c [ACS-7896] Bump AIS/ATS 5.1.2/4.1.2 (#2655) 2024-05-20 09:17:01 +02:00
alfresco-build
c01d1f8c3c [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-19 00:07:13 +00:00
alfresco-build
3895ce6584 [maven-release-plugin][skip ci] prepare release 23.3.0.39 2024-05-19 00:07:11 +00:00
Alfresco CI User
d01f9eb27b [force] Force release for 2024-05-19. 2024-05-19 00:03:26 +00:00
alfresco-build
325dfd285b [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-17 09:51:21 +00:00
alfresco-build
d907461972 [maven-release-plugin][skip ci] prepare release 23.3.0.38 2024-05-17 09:51:18 +00:00
SathishK-T
01a2587555 [MNT-24195] Added fix for ags capability issue (#2648)
* [MNT-24195] added fix for ags capability issue

* [MNT-24195] Build Issue Resolved

* [MNT-24195] Removed unused import

* [MNT-24195] Build issue changes

* [MNT-24195]  added fix for ags capability issue

* [MNT-24195] Added fix for ags capability issue

* [MNT-24195] Fix for Review Comment

* [MNT-24195] Fix for Review Comment

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-05-17 14:41:46 +05:30
alfresco-build
8b45d19b00 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-14 14:54:41 +00:00
alfresco-build
0b4b1dac44 [maven-release-plugin][skip ci] prepare release 23.3.0.37 2024-05-14 14:54:38 +00:00
Damian Ujma
f8becd3523 ACS-6309 Fix AGS Integration Tests (PostgreSQL) (#2643) 2024-05-14 16:19:01 +02:00
alfresco-build
781b56f06d [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-12 00:07:23 +00:00
alfresco-build
92656a68a9 [maven-release-plugin][skip ci] prepare release 23.3.0.36 2024-05-12 00:07:20 +00:00
Alfresco CI User
99838a73e3 [force] Force release for 2024-05-12. 2024-05-12 00:03:49 +00:00
alfresco-build
723156a86a [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-10 09:30:29 +00:00
alfresco-build
3f6692a63b [maven-release-plugin][skip ci] prepare release 23.3.0.35 2024-05-10 09:30:27 +00:00
kcichonczyk
32e72f204a [ACS-7895] Bump ATS (#2638) 2024-05-10 10:54:28 +02:00
alfresco-build
f5868e7f45 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-09 12:34:32 +00:00
alfresco-build
fd015de2c8 [maven-release-plugin][skip ci] prepare release 23.3.0.34 2024-05-09 12:34:30 +00:00
Tom Page
ec2494f2b5 Merge pull request #2634 from Alfresco/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2024-05-09 12:58:49 +01:00
alfresco-build
afc7e73352 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-08 16:53:59 +00:00
alfresco-build
3519fd6a71 [maven-release-plugin][skip ci] prepare release 23.3.0.33 2024-05-08 16:53:57 +00:00
dependabot[bot]
5e43f3d4ab Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-08 16:14:50 +00:00
Tom Page
337d0b8f8f Merge pull request #2630 from Alfresco/feature/GHADependabot
Add GHA to Dependabot scanning.
2024-05-08 17:13:48 +01:00
Tom Page
3c7593265d Add GHA to Dependabot scanning. 2024-05-08 14:52:01 +01:00
alfresco-build
5dcecb7f19 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-05 00:07:19 +00:00
alfresco-build
0617a441d3 [maven-release-plugin][skip ci] prepare release 23.3.0.32 2024-05-05 00:07:16 +00:00
Alfresco CI User
d9abdc23d5 [force] Force release for 2024-05-05. 2024-05-05 00:03:35 +00:00
alfresco-build
f132ec0a91 [maven-release-plugin][skip ci] prepare for next development iteration 2024-05-02 08:00:53 +00:00
alfresco-build
1797781ce8 [maven-release-plugin][skip ci] prepare release 23.3.0.31 2024-05-02 08:00:51 +00:00
Manish Kumar
88c1c849ed Merge pull request #2440 from fawhgb/rm-fileplan-caching-issue
Fixes the caching issue by returning a copy of the set instead of the Set
2024-05-02 12:53:50 +05:30
alfresco-build
c4ac7621c2 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-30 10:08:30 +00:00
alfresco-build
bf7432deb1 [maven-release-plugin][skip ci] prepare release 23.3.0.30 2024-04-30 10:08:28 +00:00
dependabot[bot]
6f74667a5c Bump commons-codec:commons-codec from 1.16.0 to 1.17.0 (#2614)
Bumps [commons-codec:commons-codec](https://github.com/apache/commons-codec) from 1.16.0 to 1.17.0.
- [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.16.0...rel/commons-codec-1.17.0)

---
updated-dependencies:
- dependency-name: commons-codec:commons-codec
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-30 11:32:53 +02:00
alfresco-build
1e1508b74e [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-29 11:29:50 +00:00
alfresco-build
da8ffa08a0 [maven-release-plugin][skip ci] prepare release 23.3.0.29 2024-04-29 11:29:48 +00:00
dependabot[bot]
277dbd1054 Bump org.springframework:spring-web from 6.0.17 to 6.0.19 (#2612)
Bumps [org.springframework:spring-web](https://github.com/spring-projects/spring-framework) from 6.0.17 to 6.0.19.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.17...v6.0.19)

---
updated-dependencies:
- dependency-name: org.springframework:spring-web
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-29 12:43:14 +02:00
dependabot[bot]
43cfa0d872 Bump org.messaginghub:pooled-jms from 3.1.2 to 3.1.6 (#2611)
Bumps [org.messaginghub:pooled-jms](https://github.com/messaginghub/pooled-jms) from 3.1.2 to 3.1.6.
- [Commits](https://github.com/messaginghub/pooled-jms/compare/3.1.2...3.1.6)

---
updated-dependencies:
- dependency-name: org.messaginghub:pooled-jms
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-29 12:39:44 +02:00
alfresco-build
1325ec5718 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-28 00:07:07 +00:00
alfresco-build
ecde2b5b60 [maven-release-plugin][skip ci] prepare release 23.3.0.28 2024-04-28 00:07:05 +00:00
Alfresco CI User
a9f75638c6 [force] Force release for 2024-04-28. 2024-04-28 00:04:18 +00:00
alfresco-build
a80b996f7e [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-21 00:06:44 +00:00
alfresco-build
05aa6b4cf6 [maven-release-plugin][skip ci] prepare release 23.3.0.27 2024-04-21 00:06:42 +00:00
Alfresco CI User
50b1d3a52e [force] Force release for 2024-04-21. 2024-04-21 00:03:37 +00:00
alfresco-build
38b763c635 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-15 12:36:56 +00:00
alfresco-build
762b6ce607 [maven-release-plugin][skip ci] prepare release 23.3.0.26 2024-04-15 12:36:53 +00:00
Aleksandra Onych
0d89010ae6 [ACS-6776] add comment to json-path dependency (#2588) 2024-04-15 14:01:04 +02:00
Piotr Żurek
b744f267c1 ACS-7483 Bump ATS (#2589) 2024-04-15 13:59:59 +02:00
alfresco-build
e840726a7d [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-15 07:57:48 +00:00
alfresco-build
c53683df85 [maven-release-plugin][skip ci] prepare release 23.3.0.25 2024-04-15 07:57:45 +00:00
Alfresco CI User
d9e58483ff [force] Force release for 2024-04-14. 2024-04-14 00:07:14 +00:00
alfresco-build
9e81472d06 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-12 13:29:27 +00:00
alfresco-build
3e9cdc6b77 [maven-release-plugin][skip ci] prepare release 23.3.0.24 2024-04-12 13:29:25 +00:00
Domenico Sibilio
e8ac8c2602 ACS-7481 Bump IE/SS to 2.0.10 (#2585) 2024-04-12 14:50:41 +02:00
alfresco-build
eea58f4ba3 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-10 11:37:55 +00:00
alfresco-build
a95fa4a83d [maven-release-plugin][skip ci] prepare release 23.3.0.23 2024-04-10 11:37:52 +00:00
Aleksandra Onych
0b74d283e2 [ACS-6935] Update tika version to 2.9.2 (#2578) 2024-04-10 13:03:10 +02:00
alfresco-build
052e21e62d [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-10 08:52:46 +00:00
alfresco-build
26f49e80e9 [maven-release-plugin][skip ci] prepare release 23.3.0.22 2024-04-10 08:52:43 +00:00
Eva Vasques
c31158a113 MNT-24321 Transfer Service Exception Handling (#2573)
* Mark method deserialize in ExceptionJsonSerializer as deprecated
* Remove usage of jsonErrorSerializer
2024-04-10 09:15:25 +01:00
alfresco-build
2b4fc52203 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-07 00:06:32 +00:00
alfresco-build
6222e1dfde [maven-release-plugin][skip ci] prepare release 23.3.0.21 2024-04-07 00:06:30 +00:00
Alfresco CI User
077c48dea9 [force] Force release for 2024-04-07. 2024-04-07 00:03:33 +00:00
alfresco-build
1a0b8d8dee [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-05 15:39:32 +00:00
alfresco-build
66d007e703 [maven-release-plugin][skip ci] prepare release 23.3.0.20 2024-04-05 15:39:29 +00:00
Domenico Sibilio
81a4c5bac0 ACS-6961 Bump IE/SS to 2.0.10-A1 (#2571) 2024-04-05 14:09:59 +02:00
alfresco-build
018157c808 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-04 13:19:11 +00:00
alfresco-build
8db97184f2 [maven-release-plugin][skip ci] prepare release 23.3.0.19 2024-04-04 13:19:09 +00:00
Piotr Żurek
84948e051a ACS-7467 Fix grep escaping (#2567) 2024-04-04 14:43:31 +02:00
alfresco-build
8c20a3271e [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-04 10:33:26 +00:00
alfresco-build
48c7abcfbe [maven-release-plugin][skip ci] prepare release 23.3.0.18 2024-04-04 10:33:24 +00:00
Damian Ujma
53d77f8d71 ACS-6917 Implement the Legal Holds v1 API (#2566)
---------

Co-authored-by: Tom Page <tpage-alfresco@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2024-04-04 11:46:56 +02:00
alfresco-build
e8e747347a [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-03 13:45:11 +00:00
alfresco-build
fee244cb08 [maven-release-plugin][skip ci] prepare release 23.3.0.17 2024-04-03 13:45:09 +00:00
Piotr Żurek
2bec2bd1c4 ACS-7467 Migrate to Docker Compose V2 (#2560) 2024-04-03 15:08:10 +02:00
Piotr Żurek
1cd8098f52 ACS-7313 Bump ATS in ACS 23.3 (#2559) 2024-04-03 14:49:38 +02:00
alfresco-build
30afcaa033 [maven-release-plugin][skip ci] prepare for next development iteration 2024-04-03 08:49:21 +00:00
alfresco-build
bdf1a57630 [maven-release-plugin][skip ci] prepare release 23.3.0.16 2024-04-03 08:49:19 +00:00
Wojtek Świętoń
2723817832 ACS-6309 Integration with Report Portal (#2445) 2024-04-03 09:46:01 +02:00
alfresco-build
22acb2abe7 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-31 00:07:05 +00:00
alfresco-build
3c616152a1 [maven-release-plugin][skip ci] prepare release 23.3.0.15 2024-03-31 00:07:03 +00:00
Alfresco CI User
8cfdc613cb [force] Force release for 2024-03-31. 2024-03-31 00:04:13 +00:00
alfresco-build
f1919934b2 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-29 09:20:56 +00:00
alfresco-build
e9da60dac3 [maven-release-plugin][skip ci] prepare release 23.3.0.14 2024-03-29 09:20:53 +00:00
kcichonczyk
0597b0997f [ACS-7320] ATS/AIS version bump to java11 compatible 2024-03-29 09:45:52 +01:00
alfresco-build
6dbe30e8f7 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-27 14:27:38 +00:00
alfresco-build
d978b1cd68 [maven-release-plugin][skip ci] prepare release 23.3.0.13 2024-03-27 14:27:35 +00:00
Piotr Żurek
dce356fe74 MNT-23210 Fix audit min-max query (#2545) 2024-03-27 14:49:35 +01:00
alfresco-build
f965165894 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-24 00:06:39 +00:00
alfresco-build
2ac44c24a8 [maven-release-plugin][skip ci] prepare release 23.3.0.12 2024-03-24 00:06:37 +00:00
Alfresco CI User
a0dc5a0d70 [force] Force release for 2024-03-24. 2024-03-24 00:04:10 +00:00
alfresco-build
af94063bbb [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-18 16:00:10 +00:00
alfresco-build
87b91b6cae [maven-release-plugin][skip ci] prepare release 23.3.0.11 2024-03-18 16:00:08 +00:00
mohit-singh4
6bdcaa9b10 [APPS-2576] fix for Security Web Vulnerability (#2516) 2024-03-18 20:54:04 +05:30
Maciej Pichura
86070d881c ACS-6884: Bump api-explorer version to 23.2.0 (GA) (#2480)
* ACS-6884: Bump api-explorer version to 23.2.0 (GA)

* Bump org.springframework.security:spring-security-bom (#2453)

Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 6.1.4 to 6.2.2.
- [Release notes](https://github.com/spring-projects/spring-security/releases)
- [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc)
- [Commits](https://github.com/spring-projects/spring-security/compare/6.1.4...6.2.2)

---
updated-dependencies:
- dependency-name: org.springframework.security:spring-security-bom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* ACS-6931 Temporarily turn off SAST Scan (#2489)

ACS-6931 Temporarily turn off SAST Scan

* [maven-release-plugin][skip ci] prepare release 23.3.0.7

* [maven-release-plugin][skip ci] prepare for next development iteration

* [force] Force release for 2024-03-10.

* [maven-release-plugin][skip ci] prepare release 23.3.0.8

* [maven-release-plugin][skip ci] prepare for next development iteration

* MNT-24250: bump xalan version (#2497)

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* bump xalan

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: 2.7.3 official

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco

* [maven-release-plugin][skip ci] prepare release 23.3.0.9

* [maven-release-plugin][skip ci] prepare for next development iteration

* [force] Force release for 2024-03-17.

* [maven-release-plugin][skip ci] prepare release 23.3.0.10

* [maven-release-plugin][skip ci] prepare for next development iteration

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: mikolajbrzezinski <86791239+mikolajbrzezinski@users.noreply.github.com>
Co-authored-by: alfresco-build <8039454+alfresco-build@users.noreply.github.com>
Co-authored-by: Alfresco CI User <build@alfresco.com>
Co-authored-by: Paweł Rainer <62990104+Pawel-608@users.noreply.github.com>
2024-03-18 11:54:56 +01:00
alfresco-build
a82199967c [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-17 00:06:51 +00:00
alfresco-build
f09266c081 [maven-release-plugin][skip ci] prepare release 23.3.0.10 2024-03-17 00:06:49 +00:00
Alfresco CI User
563f65825f [force] Force release for 2024-03-17. 2024-03-17 00:04:08 +00:00
alfresco-build
8bedeedfd5 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-14 10:11:22 +00:00
alfresco-build
a73cf6a71d [maven-release-plugin][skip ci] prepare release 23.3.0.9 2024-03-14 10:11:19 +00:00
Paweł Rainer
1bdd6c022c MNT-24250: bump xalan version (#2497)
* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* bump xalan

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: bump xalan version

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: alfresco.3

* MNT-24250: 2.7.3 official

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco.3

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco

* MNT-24250: 2.7.3-alfresco
2024-03-14 10:34:09 +01:00
alfresco-build
1b553dbcaf [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-10 00:06:19 +00:00
alfresco-build
5a3b4e1a0d [maven-release-plugin][skip ci] prepare release 23.3.0.8 2024-03-10 00:06:17 +00:00
Alfresco CI User
1a0156b1e5 [force] Force release for 2024-03-10. 2024-03-10 00:03:35 +00:00
alfresco-build
6ac9248262 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-06 12:46:46 +00:00
alfresco-build
70290c8f23 [maven-release-plugin][skip ci] prepare release 23.3.0.7 2024-03-06 12:46:43 +00:00
mikolajbrzezinski
7d135b9356 ACS-6931 Temporarily turn off SAST Scan (#2489)
ACS-6931 Temporarily turn off SAST Scan
2024-03-06 13:11:31 +01:00
dependabot[bot]
df4629b801 Bump org.springframework.security:spring-security-bom (#2453)
Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 6.1.4 to 6.2.2.
- [Release notes](https://github.com/spring-projects/spring-security/releases)
- [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc)
- [Commits](https://github.com/spring-projects/spring-security/compare/6.1.4...6.2.2)

---
updated-dependencies:
- dependency-name: org.springframework.security:spring-security-bom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-05 12:02:56 +01:00
alfresco-build
df6f656b95 [maven-release-plugin][skip ci] prepare for next development iteration 2024-03-03 00:05:44 +00:00
alfresco-build
f27718c43b [maven-release-plugin][skip ci] prepare release 23.3.0.6 2024-03-03 00:05:42 +00:00
Alfresco CI User
cbf0aaaaa4 [force] Force release for 2024-03-03. 2024-03-03 00:03:20 +00:00
alfresco-build
2da78a94ad [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-26 08:21:03 +00:00
alfresco-build
3325e08d57 [maven-release-plugin][skip ci] prepare release 23.3.0.5 2024-02-26 08:21:01 +00:00
rrajoria
985205e78e Update google drive and aos GA Version 2024-02-26 13:16:08 +05:30
alfresco-build
5fd5e75bd2 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-25 00:06:12 +00:00
alfresco-build
279bc15aac [maven-release-plugin][skip ci] prepare release 23.3.0.4 2024-02-25 00:06:10 +00:00
Alfresco CI User
a3283b4521 [force] Force release for 2024-02-25. 2024-02-25 00:03:36 +00:00
alfresco-build
e09c9118b2 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-23 07:45:42 +00:00
alfresco-build
330256438b [maven-release-plugin][skip ci] prepare release 23.3.0.3 2024-02-23 07:45:40 +00:00
Kacper Magdziarz
2214f16e6e [ACS-6773] Propagate ATS-4.1.0 (#2469) 2024-02-23 08:10:12 +01:00
alfresco-build
2237a45e76 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-21 11:20:16 +00:00
alfresco-build
f71a003904 [maven-release-plugin][skip ci] prepare release 23.3.0.2 2024-02-21 11:20:13 +00:00
dependabot[bot]
10d55824f8 Bump org.apache.commons:commons-compress from 1.25.0 to 1.26.0 (#2454)
Bumps org.apache.commons:commons-compress from 1.25.0 to 1.26.0.

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-compress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-21 11:36:18 +01:00
alfresco-build
69f8bda762 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-20 13:01:23 +00:00
alfresco-build
d8de1ba353 [maven-release-plugin][skip ci] prepare release 23.3.0.1 2024-02-20 13:01:21 +00:00
Damian Ujma
d4d8718f16 ACS-6601 Bump AOS to 3.0.0-A1 (#2459) 2024-02-20 13:17:35 +01:00
Krystian Dabrowski
859492ae1e ACS-6113: Fix secondary parents to never be set to null (#2460) 2024-02-20 12:47:28 +01:00
mpichura
6c08a60ce5 Updating master branch to 23.3.0 after 23.2.0 ACS release [skip ci] 2024-02-19 16:34:39 +01:00
alfresco-build
9cdc916189 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-19 06:44:58 +00:00
alfresco-build
8272347b71 [maven-release-plugin][skip ci] prepare release 23.2.0.51 2024-02-19 06:44:54 +00:00
rrajoria
cde7f0bba1 Update GoogleDrive Version 4.1.0-A1 2024-02-19 11:36:56 +05:30
alfresco-build
959678eb70 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-18 00:06:37 +00:00
alfresco-build
cf7bb499dc [maven-release-plugin][skip ci] prepare release 23.2.0.50 2024-02-18 00:06:34 +00:00
Alfresco CI User
a915a4246c [force] Force release for 2024-02-18. 2024-02-18 00:03:31 +00:00
Tom Page
89b5fa9e90 Merge pull request #2441 from AFaust/bugfix/nodesmetadata-childassoc-param-handling
Map includeChildAssociations request parameter
2024-02-15 10:37:45 +00:00
alfresco-build
03744ff5d5 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-15 08:53:33 +00:00
alfresco-build
965add646c [maven-release-plugin][skip ci] prepare release 23.2.0.49 2024-02-15 08:53:31 +00:00
Kacper Magdziarz
1c93cc7ca4 [ACS-6772] Propagate ATS-4.1.0-A1 (#2451) 2024-02-15 09:17:17 +01:00
alfresco-build
0564b27ece [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-14 10:38:03 +00:00
alfresco-build
b98fdf4ca9 [maven-release-plugin][skip ci] prepare release 23.2.0.48 2024-02-14 10:38:00 +00:00
mstrankowski
1aff1eab1e Update json-path to 2.9.0 2024-02-14 10:54:27 +01:00
alfresco-build
c3b82354c1 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-13 19:06:29 +00:00
alfresco-build
04215f84a6 [maven-release-plugin][skip ci] prepare release 23.2.0.47 2024-02-13 19:06:26 +00:00
MichalKinas
e6e05c8890 Merge pull request #2446 from Alfresco/feature/mkinas-ACS-5506-exception-fix
[ACS-5506] Fix string to node ref cast exception
2024-02-13 19:29:26 +01:00
alfresco-build
af69c12be3 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-13 18:23:24 +00:00
alfresco-build
eaf07ef88e [maven-release-plugin][skip ci] prepare release 23.2.0.46 2024-02-13 18:23:21 +00:00
Damian Ujma
c4714b19eb ACS-6601 Implement Repository OIDC Compliance (#2447)
* ACS-6677 Enhance OIDC Configuration Flexibility (#2426)

* ACS-6603 Implement OIDC Compliance (#2442)

* ACS-6677 Enhance OIDC Configuration Flexibility

* ACS-6677 Revert changing http header

* ACS-6677 Add unit test to suite

* ACS-6677 Rename var

* ACS-6677 Fix PMD issues

* ACS-6677 Fix PMD issues

* ACS-6677 Improve code

* ACS-6677 Fix compatibility

* ACS-6677 Add JwtAudienceValidator

* ACS-6677 Change domain

* ACS-6603 Oidc compliance

* ACS-6603 Add Auth0 test

* ACS-6603 Reformat

* ACS-6603 Enable User Info Endpoint test + Refactor

* ACS-6603 Change test condition

* ACS-6603 Add state parameter + reformat stream

* ACS-6603 Use enum type
2024-02-13 18:43:44 +01:00
MichalKinas
e3407e5a53 ACS-5506 Move NodeRef check to decide method 2024-02-13 13:22:51 +01:00
MichalKinas
8d978d6527 ACS-5506 Fix string to node ref cast exception 2024-02-13 11:33:20 +01:00
alfresco-build
de6b062f3e [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-11 00:06:10 +00:00
alfresco-build
98231782f6 [maven-release-plugin][skip ci] prepare release 23.2.0.45 2024-02-11 00:06:07 +00:00
Alfresco CI User
b4146744d2 [force] Force release for 2024-02-11. 2024-02-11 00:03:35 +00:00
alfresco-build
f9f3248229 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-08 13:10:27 +00:00
alfresco-build
9297fa5cf4 [maven-release-plugin][skip ci] prepare release 23.2.0.44 2024-02-08 13:10:25 +00:00
MichalKinas
3d1cc0924d Merge pull request #2035 from Alfresco/feature/ACS-5506-be-handling-a-description-of-the-group-and-flag-for-subgroups
ACS-5506 Add description and hasSubgroups to groups API
2024-02-08 13:35:24 +01:00
AFaust
3b574c56dc Map includeChildAssociations request parameter 2024-02-08 13:26:38 +01:00
MichalKinas
f737c3ef3c ACS-5506 Test fix 2024-02-08 11:39:17 +01:00
MichalKinas
5e85b8149b ACS-5506 Cleanup and test fixes 2024-02-08 11:12:30 +01:00
Simon Wagner
440e31fcdb Fixes the caching issue by returning a copy of the set instead of the set inside the cache. 2024-02-08 09:17:10 +01:00
MichalKinas
11030f52fa ACS-5506 Add temporary logging 2024-02-06 21:15:14 +01:00
MichalKinas
c537166f68 ACS-5506 Add temporary logging 2024-02-06 20:36:42 +01:00
alfresco-build
448d2c9c2f [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-06 12:32:33 +00:00
alfresco-build
dd5703a51a [maven-release-plugin][skip ci] prepare release 23.2.0.43 2024-02-06 12:32:31 +00:00
MichalKinas
cfc0916c84 ACS-5506 Unit tests fixes 2024-02-06 13:04:31 +01:00
tiagosalvado10
71b69529c6 [MNT-24072] Retain users/groups (who are already exist and are part of AUTH.ALF zone) so parent associations can be created (#2414)
* [MNT-24072] Retain existent users and groups so parent associations can be created

* [MNT-24072] Using person/authority 'exists' methods instead

* [MNT-24072] Added code to rezone users/groups (who already exist and are part of AUTH.ALF zone) that have parent associations to create

* [MNT-24072] PMD scan changes

* [MNT-24072] Added a validation to prevent an authority from being added to zones where already is
2024-02-06 11:58:23 +00:00
MichalKinas
9ffe27f028 ACS-5506 Update properties correctly 2024-02-06 11:39:45 +01:00
alfresco-build
47a636997c [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-06 09:46:23 +00:00
alfresco-build
c97df2dbaa [maven-release-plugin][skip ci] prepare release 23.2.0.42 2024-02-06 09:46:21 +00:00
Manish Kumar
2734dcb107 Merge pull request #2429 from Alfresco/fix/ACS-6444-clientInjection
updated swagger-ui version to 4.1.3
2024-02-06 14:41:31 +05:30
MichalKinas
197acb3a7b ACS-5506 Add allowed methods 2024-02-05 12:55:37 +01:00
Manish Kumar
91019185d8 updated swagger-ui version to 4.1.3 2024-02-05 14:58:04 +05:30
alfresco-build
fb0c64b664 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-04 00:06:20 +00:00
alfresco-build
5f568179bd [maven-release-plugin][skip ci] prepare release 23.2.0.41 2024-02-04 00:06:18 +00:00
Alfresco CI User
0396bbebbc [force] Force release for 2024-02-04. 2024-02-04 00:03:36 +00:00
MichalKinas
12d1ecdefa ACS-5506 CR fixes applied 2024-02-02 18:22:14 +01:00
alfresco-build
ebdc62a421 [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-02 13:51:52 +00:00
alfresco-build
aea34e8149 [maven-release-plugin][skip ci] prepare release 23.2.0.40 2024-02-02 13:51:50 +00:00
Tom Page
6a5f378ce1 ACS-6113 Upgrade acs-events-model. 2024-02-02 13:15:15 +00:00
alfresco-build
e1de1c627d [maven-release-plugin][skip ci] prepare for next development iteration 2024-02-01 10:01:02 +00:00
alfresco-build
0209c8fc84 [maven-release-plugin][skip ci] prepare release 23.2.0.39 2024-02-01 10:01:00 +00:00
Domenico Sibilio
bb0c3ea207 ACS-6653 Bump Tika, POI, bouncycastle, commons-compress, xmlbeans (#2422)
* ACS-6653 Bump Tika, POI, commons-compress

* ACS-6653 Bump bouncycastle to jdk18on 1.77

* ACS-6653 Bump xmlbeans to 5.2.0
2024-02-01 10:23:08 +01:00
MichalKinas
605c3a6ccd ACS-5506 Add missing annotations, hasSubgroups not required 2024-01-31 00:51:45 +01:00
MichalKinas
d3c7342f05 ACS-5506 Description handling rework 2024-01-31 00:08:26 +01:00
alfresco-build
0eb7abb95b [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-30 16:07:40 +00:00
alfresco-build
a7925d54a6 [maven-release-plugin][skip ci] prepare release 23.2.0.38 2024-01-30 16:07:37 +00:00
Eva Vasques
dbd7ce1f48 MNT-24094 - error message logged in the logs when a webscript fails is not helpful as it should indicate what webscript triggers the error (#2421)
* Add WebScriptRequest to the methods that call the render exception so we can log more info on the request when an error occurs.
* Add request uri, user ans status code to the logging
* Always log on exception but only show stack trace on debug or on internal server exception
2024-01-30 15:32:41 +00:00
MichalKinas
ecfeb77fb0 ACS-5506 Add PMD fixes 2024-01-30 15:26:39 +01:00
MichalKinas
1f72faa90c ACS-5506 Add proper exception handling 2024-01-30 15:26:39 +01:00
MichalKinas
925a4f4a6a ACS-5506 Add properties to authority service 2024-01-30 15:26:39 +01:00
MichalKinas
4f4f7cc02f ACS-5506 Tests cleanup 2024-01-30 15:26:39 +01:00
MichalKinas
ef9d724ee9 ACS-5506 PMD fixes 2024-01-30 15:26:39 +01:00
MichalKinas
71cbb9e1ef ACS-5506 Tests cleanup 2024-01-30 15:26:39 +01:00
MichalKinas
effb697261 ACS-5506 Tests fixes 2024-01-30 15:26:39 +01:00
MichalKinas
0b753c23c2 ACS-5506 Tests cleanup 2024-01-30 15:26:39 +01:00
MichalKinas
05f0df1b2f ACS-5506 Proper Group serialization 2024-01-30 15:26:39 +01:00
MichalKinas
7a8cf67c2e ACS-5506 Test fixes 2024-01-30 15:26:39 +01:00
MichalKinas
da7f1877fd ACS-5506 Fix saving properties 2024-01-30 15:26:39 +01:00
MichalKinas
9a11075f41 ACS-5506 Proper description storage 2024-01-30 15:26:39 +01:00
MichalKinas
4d22931dfe ACS-5506 Correct Nodes bean 2024-01-30 15:26:39 +01:00
MichalKinas
d9fe82a2d2 ACS-5506 Add description and hasSubgroups to groups API 2024-01-30 15:26:39 +01:00
alfresco-build
60e42b4090 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-28 00:06:18 +00:00
alfresco-build
824886ecdd [maven-release-plugin][skip ci] prepare release 23.2.0.37 2024-01-28 00:06:16 +00:00
Alfresco CI User
e2f0ebb015 [force] Force release for 2024-01-28. 2024-01-28 00:03:40 +00:00
alfresco-build
6872c3d683 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-25 11:43:58 +00:00
alfresco-build
4d8a9e35b7 [maven-release-plugin][skip ci] prepare release 23.2.0.36 2024-01-25 11:43:56 +00:00
Domenico Sibilio
0cea265153 ACS-6650 Avoid running SAST scan on DependaBot PRs (#2418)
Skipping SAST scan on DependaBot PRs as it won't provide any additional insights and requires sharing more secrets with DependaBot than we're willing to.
2024-01-25 12:08:04 +01:00
alfresco-build
1ef7b5bea9 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-23 12:14:57 +00:00
alfresco-build
0a9aac7332 [maven-release-plugin][skip ci] prepare release 23.2.0.35 2024-01-23 12:14:55 +00:00
mikolajbrzezinski
12e1506d01 ACS-6304 Add retry mechanism to completeRecordsCantBeUpdated test (#2405)
ACS-6304 Add retry mechanism to completeRecordsCantBeUpdated test
2024-01-23 12:39:21 +01:00
alfresco-build
2c5a745b50 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-21 00:07:04 +00:00
alfresco-build
dd5f2a76ab [maven-release-plugin][skip ci] prepare release 23.2.0.34 2024-01-21 00:07:01 +00:00
Alfresco CI User
e7bd28180c [force] Force release for 2024-01-21. 2024-01-21 00:03:48 +00:00
alfresco-build
5bb8a621bf [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-18 10:19:34 +00:00
alfresco-build
28ed202c78 [maven-release-plugin][skip ci] prepare release 23.2.0.33 2024-01-18 10:19:31 +00:00
Eva Vasques
d62423f378 [MNT-24085] - Fixed ACL Updater job is updating the cm:modifier details (#2406)
* Disabled audibled and versionable behaviour on add and remove pending acl aspect and properties
* Added validations to the unit test to assert modification date is not changed
2024-01-18 09:36:30 +00:00
alfresco-build
fc7b2f9fbf [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-14 00:06:30 +00:00
alfresco-build
df93094d67 [maven-release-plugin][skip ci] prepare release 23.2.0.32 2024-01-14 00:06:27 +00:00
Alfresco CI User
e1db33ac7a [force] Force release for 2024-01-14. 2024-01-14 00:03:45 +00:00
alfresco-build
c319370d4e [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-07 00:06:52 +00:00
alfresco-build
5bfff49d5e [maven-release-plugin][skip ci] prepare release 23.2.0.31 2024-01-07 00:06:49 +00:00
Alfresco CI User
74d017c371 [force] Force release for 2024-01-07. 2024-01-07 00:03:57 +00:00
alfresco-build
c35de7aed3 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-04 16:29:12 +00:00
alfresco-build
29d7f8d298 [maven-release-plugin][skip ci] prepare release 23.2.0.30 2024-01-04 16:29:10 +00:00
mstrankowski
20b0e3cf18 [skip tests] The difference of having/not having json-path library loaded here is only shown on the acs-packaging level, all the tests up to that point were green. I suspect that the issue stems from AIS amp 2024-01-04 17:25:21 +01:00
mstrankowski
fb6dcac85e Revert "Remove json-path dependency from repository module as it seems to only be used in test modules (#2397)"
This reverts commit 687b44b98a.
2024-01-04 17:22:18 +01:00
alfresco-build
98b9bf34ff [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-04 10:41:56 +00:00
alfresco-build
57da5fbdcd [maven-release-plugin][skip ci] prepare release 23.2.0.29 2024-01-04 10:41:53 +00:00
Marcin Strankowski
687b44b98a Remove json-path dependency from repository module as it seems to only be used in test modules (#2397) 2024-01-04 11:06:51 +01:00
alfresco-build
c83434a3f2 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-03 17:26:01 +00:00
alfresco-build
6b030b489b [maven-release-plugin][skip ci] prepare release 23.2.0.28 2024-01-03 17:25:59 +00:00
Maciej Pichura
835aba686b ACS-6406: Bumping down version.schema to 19100 for ACS 23.2 (#2396) 2024-01-03 17:51:01 +01:00
alfresco-build
58f7699c05 [maven-release-plugin][skip ci] prepare for next development iteration 2024-01-02 17:22:36 +00:00
alfresco-build
de7ef52037 [maven-release-plugin][skip ci] prepare release 23.2.0.27 2024-01-02 17:22:34 +00:00
Suneet Gupta
eb5fd63839 [APPS-2544] updated license header for AGS (#2395) 2024-01-02 21:44:20 +05:30
alfresco-build
62399e7017 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-31 00:06:27 +00:00
alfresco-build
383c6f0a1d [maven-release-plugin][skip ci] prepare release 23.2.0.26 2023-12-31 00:06:24 +00:00
Alfresco CI User
af1df82dd9 [force] Force release for 2023-12-31. 2023-12-31 00:03:49 +00:00
alfresco-build
028ff60748 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-24 00:06:42 +00:00
alfresco-build
2b2fdba3b7 [maven-release-plugin][skip ci] prepare release 23.2.0.25 2023-12-24 00:06:39 +00:00
Alfresco CI User
f16a193b61 [force] Force release for 2023-12-24. 2023-12-24 00:03:24 +00:00
alfresco-build
873119f56e [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-21 11:06:01 +00:00
alfresco-build
2c41c0ead1 [maven-release-plugin][skip ci] prepare release 23.2.0.24 2023-12-21 11:05:59 +00:00
dependabot[bot]
c957f40a78 Bump org.springframework:spring-webmvc from 6.0.12 to 6.0.14 (#2346)
Bumps [org.springframework:spring-webmvc](https://github.com/spring-projects/spring-framework) from 6.0.12 to 6.0.14.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.12...v6.0.14)

---
updated-dependencies:
- dependency-name: org.springframework:spring-webmvc
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-21 11:30:11 +01:00
alfresco-build
f8a8b5c8f3 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-19 13:20:05 +00:00
alfresco-build
773d9ca9d9 [maven-release-plugin][skip ci] prepare release 23.2.0.23 2023-12-19 13:20:03 +00:00
Maciej Pichura
1af0b72257 ACS-6402: Add tests covering module compatibility check for new ACS versioning schema (#2379)
* ACS-6402: Add tests covering module compatibility check for new ACS versioning schema.

* ACS-6402: Ignoring false PMD issues.
2023-12-19 13:45:07 +01:00
alfresco-build
158fb067d0 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-17 00:06:29 +00:00
alfresco-build
016c212c65 [maven-release-plugin][skip ci] prepare release 23.2.0.22 2023-12-17 00:06:26 +00:00
Alfresco CI User
c1bd8e71c4 [force] Force release for 2023-12-17. 2023-12-17 00:03:20 +00:00
alfresco-build
f68446b3e5 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-14 11:06:04 +00:00
alfresco-build
9b26c66dec [maven-release-plugin][skip ci] prepare release 23.2.0.21 2023-12-14 11:06:01 +00:00
Damian Ujma
06c35ea379 MNT-23880 Integrate the Alfresco Admin Console with the IDS (#2362)
* MNT-23880 Integrate IDS with the Admin Console

* MNT-23880 Remove diamond expressions

* MNT-23880 Refactor

* MNT-23880 Move requesting authentication

* MNT-23880 Fix comment

* MNT-23880 Check if AdminConsoleAuthenticator is active

* MNT-23880 Fix DefaultAdminConsoleAuthenticator + PMD issues

* MNT-23880 Fix PMD issues

* MNT-23880 Refactor

* MNT-23880 Refactor RemoteUserAuthenticatorFactory
2023-12-14 11:30:53 +01:00
alfresco-build
5580609010 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-13 12:23:44 +00:00
alfresco-build
e16a3759ad [maven-release-plugin][skip ci] prepare release 23.2.0.20 2023-12-13 12:23:41 +00:00
Domenico Sibilio
9cce8d54d8 ACS-5925 Switch from IDS 2.0.0 to Keycloak 21.1.2 (#2369) 2023-12-13 12:48:47 +01:00
alfresco-build
856bf011c5 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-13 10:34:12 +00:00
alfresco-build
d46fc62cdb [maven-release-plugin][skip ci] prepare release 23.2.0.19 2023-12-13 10:34:09 +00:00
mikolajbrzezinski
eff41eef12 ACS-6304 Implement SAST Pipeline Scan (#2304)
ACS-6304 Implement SAST Pipeline Scan
2023-12-13 10:57:43 +01:00
alfresco-build
3d0185574d [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-10 00:06:22 +00:00
alfresco-build
5664b5de78 [maven-release-plugin][skip ci] prepare release 23.2.0.18 2023-12-10 00:06:19 +00:00
Alfresco CI User
82f44122bc [force] Force release for 2023-12-10. 2023-12-10 00:03:41 +00:00
alfresco-build
6c3740c2a6 [maven-release-plugin][skip ci] prepare for next development iteration 2023-12-03 00:06:05 +00:00
alfresco-build
ecdbf41291 [maven-release-plugin][skip ci] prepare release 23.2.0.17 2023-12-03 00:06:03 +00:00
Alfresco CI User
6abf01e083 [force] Force release for 2023-12-03. 2023-12-03 00:03:30 +00:00
alfresco-build
7671d3b7bc [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-30 12:27:33 +00:00
alfresco-build
a8a6b565a7 [maven-release-plugin][skip ci] prepare release 23.2.0.16 2023-11-30 12:27:30 +00:00
Damian Ujma
a660109b73 ACS-6303 Add seamless ACS JIT user provisioning (#2336)
* ACS-6303 Implement JIT User Provisioning

* ACS-6303 Fix AuthenticationsTest

* ACS-6303 Add IT test

* ACS-6303 Fix syntax

* ACS-6303 Revert local change

* ACS-6303 Update IDS version

* ACS-6303 Fix JITProvisioning IT test execution

* ACS-6303 Add new IT scenario

* ACS-6303 Remove AppContext05TestSuite-setup.sh + optimize calling UserInfoEndpoint

* ACS-6303 Fix PMD issues

* ACS-6303 Fix property name

* ACS-6303 Change getUserInfo return type

* Apply suggestions from code review

Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>

* ACS-6303 Move var declaration + use lambda+diamond operator

* ACS-6303 Add a small optimisation

---------

Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2023-11-30 12:50:24 +01:00
alfresco-build
11cc7fd2cb [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-26 00:06:04 +00:00
alfresco-build
fe356c6135 [maven-release-plugin][skip ci] prepare release 23.2.0.15 2023-11-26 00:06:01 +00:00
Alfresco CI User
8b75f4f961 [force] Force release for 2023-11-26. 2023-11-26 00:03:28 +00:00
alfresco-build
db9d6cc08c [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-20 15:54:34 +00:00
alfresco-build
975503bf88 [maven-release-plugin][skip ci] prepare release 23.2.0.14 2023-11-20 15:54:32 +00:00
Domenico Sibilio
9f4ec29f9c ACS-6329 Move generate-hazelcast-config.py to community-repo (#2328) 2023-11-20 16:20:08 +01:00
alfresco-build
5490228d71 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-19 00:06:19 +00:00
alfresco-build
408800ba89 [maven-release-plugin][skip ci] prepare release 23.2.0.13 2023-11-19 00:06:16 +00:00
Alfresco CI User
773dd1d3e5 [force] Force release for 2023-11-19. 2023-11-19 00:03:26 +00:00
Kacper Magdziarz
0d8b6ef853 [ACS-6234] Fix: GetProcessesCoreTests::getProcessesOrderedByIdDESC test keeps failing (#2325) 2023-11-17 15:02:14 +01:00
Tom Page
63ef313ad5 ACS-5993 Add classpath support to PMD. (#2301) 2023-11-17 11:42:33 +00:00
alfresco-build
a63cfecbcc [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-17 11:18:14 +00:00
alfresco-build
d8e71ad38a [maven-release-plugin][skip ci] prepare release 23.2.0.12 2023-11-17 11:18:11 +00:00
Marcin Strankowski
d6bf9a5748 Extend waiting script to work with mtls tests (#2321) 2023-11-17 10:59:28 +01:00
alfresco-build
75a3e03dfa [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-16 19:12:20 +00:00
alfresco-build
e0239cd48f [maven-release-plugin][skip ci] prepare release 23.2.0.11 2023-11-16 19:12:17 +00:00
kcichonczyk
a490b8d437 bump ATS version (#2313) 2023-11-16 19:35:17 +01:00
alfresco-build
1c1a2183a3 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-16 10:01:00 +00:00
alfresco-build
0f0c143c6f [maven-release-plugin][skip ci] prepare release 23.2.0.10 2023-11-16 10:00:57 +00:00
kcichonczyk
9d41373752 [PRODSEC-7375] activemq version bump, fixing CVE-2023-46604 2023-11-14 15:01:53 +01:00
alfresco-build
5d4471bbb3 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-14 12:33:49 +00:00
alfresco-build
8451df09a8 [maven-release-plugin][skip ci] prepare release 23.2.0.9 2023-11-14 12:33:46 +00:00
dependabot[bot]
935fcf1c16 Bump org.apache.santuario:xmlsec from 3.0.2 to 3.0.3 in /remote-api (#2269)
Bumps org.apache.santuario:xmlsec from 3.0.2 to 3.0.3.

---
updated-dependencies:
- dependency-name: org.apache.santuario:xmlsec
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 12:33:13 +01:00
alfresco-build
f4a1cb5726 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-13 10:07:12 +00:00
alfresco-build
7d8cc58063 [maven-release-plugin][skip ci] prepare release 23.2.0.8 2023-11-13 10:07:09 +00:00
kcichonczyk
2005aa0754 [ACS-6179] replace deprecated tag 2023-11-13 10:24:18 +01:00
alfresco-build
c4b5da9452 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-12 00:06:50 +00:00
alfresco-build
c2bba964cb [maven-release-plugin][skip ci] prepare release 23.2.0.7 2023-11-12 00:06:48 +00:00
Alfresco CI User
4b42ecf000 [force] Force release for 2023-11-12. 2023-11-12 00:03:20 +00:00
alfresco-build
b042fbb3ca [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-08 16:15:44 +00:00
alfresco-build
617eb7bb93 [maven-release-plugin][skip ci] prepare release 23.2.0.6 2023-11-08 16:15:41 +00:00
Eva Vasques
a3ccafb035 MNT-23927 Handle JsonMappingException and JsonGenerationException (#2289)
* Throw JSON exceptions as IO exceptions to be properly handled
* Log null prop keys
* Fix test to have the mocked response different than null
2023-11-08 14:58:08 +00:00
alfresco-build
6065c6feec [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-08 13:22:17 +00:00
alfresco-build
4cacbf3829 [maven-release-plugin][skip ci] prepare release 23.2.0.5 2023-11-08 13:22:14 +00:00
Alfresco Build
19840563e4 ACS-6188 Remove usage of deprecated constructors (#2295)
* Apply org.openrewrite.staticanalysis.PrimitiveWrapperClassConstructorToValueOf recipe

* ACS-6188 Update copyright headers

* ACS-6188 Update copyright header

* ACS-6188 Clean-up

---------

Co-authored-by: dsibilio <24280982+dsibilio@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2023-11-08 13:05:00 +01:00
alfresco-build
a386dacce1 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-06 13:50:30 +00:00
alfresco-build
4f9ee4e522 [maven-release-plugin][skip ci] prepare release 23.2.0.4 2023-11-06 13:50:27 +00:00
tiagosalvado10
3bd3689d80 [MNT-23478] AsynchronousExtractor - Fix rendition obtaining (#2288)
* [MNT-23478] AsynchronousExtractor - Fix rendition obtaining

* [MNT-23478] Only use default options if no rendition is found. PMD scan change.
2023-11-06 13:06:52 +00:00
alfresco-build
7bf3611e9a [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-06 12:03:33 +00:00
alfresco-build
506a2b8e61 [maven-release-plugin][skip ci] prepare release 23.2.0.3 2023-11-06 12:03:30 +00:00
tiagosalvado10
964b09251b [MNT-23152] Changed the way how facet pivot value is parsed to prevent error and allow pivots to be built (#2290)
* [MNT-23152] Changed the way how facet pivot value is parsed to prevent error and allow pivots to be built
2023-11-06 10:56:51 +00:00
alfresco-build
78a996a663 [maven-release-plugin][skip ci] prepare for next development iteration 2023-11-05 00:05:58 +00:00
alfresco-build
0fa5d00c8b [maven-release-plugin][skip ci] prepare release 23.2.0.2 2023-11-05 00:05:56 +00:00
Alfresco CI User
79c316a05f [force] Force release for 2023-11-05. 2023-11-05 00:03:19 +00:00
alfresco-build
d7e0402733 [maven-release-plugin][skip ci] prepare for next development iteration 2023-10-31 19:31:39 +00:00
alfresco-build
40bd7b6ad3 [maven-release-plugin][skip ci] prepare release 23.2.0.1 2023-10-31 19:31:36 +00:00
mpichura
93bee49246 Update Master branch to 23.2.0 2023-10-31 19:37:12 +01:00
alfresco-build
8d51e9885a [maven-release-plugin][skip ci] prepare for next development iteration 2023-10-30 18:33:51 +00:00
386 changed files with 17797 additions and 4368 deletions

View File

@@ -52,3 +52,7 @@ 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@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
- 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
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
with:
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@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
- 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
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.0.0
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v1.35.2
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}

3
.gitignore vendored
View File

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

View File

@@ -1,14 +0,0 @@
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

File diff suppressed because it is too large Load Diff

View File

@@ -3,52 +3,6 @@ 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

@@ -1,401 +0,0 @@
<?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.1.1.13-SNAPSHOT</version>
<version>23.3.0.67</version>
</parent>
<modules>

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>23.1.1.13-SNAPSHOT</version>
<version>23.3.0.67</version>
</parent>
<build>
@@ -74,6 +74,22 @@
<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>
@@ -96,11 +112,11 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15to18</artifactId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -39,6 +39,7 @@ 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;
@@ -48,6 +49,7 @@ 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;
@@ -243,4 +245,24 @@ 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,7 +62,6 @@ 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

@@ -0,0 +1,41 @@
/*-
* #%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

@@ -0,0 +1,83 @@
/*-
* #%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

@@ -0,0 +1,59 @@
/*
* #%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

@@ -0,0 +1,50 @@
/*
* #%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

@@ -0,0 +1,67 @@
/*
* #%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

@@ -0,0 +1,38 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,46 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,52 @@
/*-
* #%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

@@ -0,0 +1,38 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,52 @@
/*-
* #%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

@@ -0,0 +1,38 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,52 @@
/*-
* #%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

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

View File

@@ -0,0 +1,56 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,58 @@
/*
* #%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

@@ -0,0 +1,50 @@
/*
* #%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

@@ -0,0 +1,32 @@
/*
* #%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

@@ -0,0 +1,37 @@
/*
* #%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

@@ -0,0 +1,33 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,38 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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,6 +37,7 @@ 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;
@@ -46,6 +47,7 @@ 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
@@ -190,4 +192,11 @@ 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,6 +38,8 @@ 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;
@@ -213,4 +215,74 @@ 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

@@ -0,0 +1,446 @@
/*
* #%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

@@ -0,0 +1,198 @@
/*
* #%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.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.v0.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.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.FORBIDDEN;
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,12 +50,13 @@ 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;
@@ -85,8 +86,6 @@ public class AuditAddToHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
@@ -94,17 +93,22 @@ 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 = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(),
getAdminUser().getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
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();
holdsListRef = asList(hold1NodeRef, hold2NodeRef);
STEP("Create a new record category with a record folder.");
@@ -169,7 +173,8 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add node to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(nodeId).build(), hold1NodeRef);
STEP("Check the audit log contains the entry for the add to hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), ADD_TO_HOLD, rmAdmin, nodeName, nodePath,
@@ -191,9 +196,8 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to add the record to a hold by an user with no rights.");
holdsAPI.addItemsToHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(recordToBeAdded.getId()),
Collections.singletonList(hold1NodeRef));
getRestAPIFactory().getHoldsAPI(rmManagerNoReadOnHold).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
assertStatusCode(FORBIDDEN);
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 ",
@@ -215,7 +219,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add record folder to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(notEmptyRecFolder.getId()).build(), hold1NodeRef);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
@@ -239,8 +243,9 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add record to multiple holds.");
holdsAPI.addItemsToHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(recordToBeAdded.getId()), holdsList);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold2NodeRef);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
@@ -268,7 +273,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(contentToBeAdded.getNodeRefWithoutVersion()).build(), hold1NodeRef);
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 ",
@@ -289,7 +294,7 @@ public class AuditAddToHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(contentToBeAdded.getNodeRefWithoutVersion()).build(), hold1NodeRef);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, ADD_TO_HOLD);
@@ -304,7 +309,8 @@ public class AuditAddToHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditAddToHoldTests()
{
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(getAdminUser()).deleteHold(holdRef));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
deleteRecordCategory(recordCategory.getId());

View File

@@ -31,9 +31,10 @@ 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.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
@@ -44,8 +45,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;
@@ -73,8 +74,6 @@ public class AuditCreateHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
@@ -102,8 +101,10 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
String hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1,
HOLD_REASON, HOLD_DESCRIPTION);
String hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
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,
@@ -120,13 +121,18 @@ public class AuditCreateHoldTests extends BaseRMRestTest
public void createHoldEventIsNotAuditedForExistingHold()
{
STEP("Create a new hold.");
String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
String hold2NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
holdsListRef.add(hold2NodeRef);
rmAuditService.clearAuditLog();
STEP("Try to create again the same hold and expect action to fail.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION,
SC_INTERNAL_SERVER_ERROR);
getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS);
assertStatusCode(CONFLICT);
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 ",
@@ -145,13 +151,17 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName, HOLD_REASON, HOLD_DESCRIPTION);
String nodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(holdName).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS).getId();
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.");
holdsAPI.deleteHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName);
getRestAPIFactory()
.getHoldsAPI(rmAdmin)
.deleteHold(nodeRef);
STEP("Get again the list of audit entries for the create hold event.");
List<AuditEntry> auditEntriesAfterDelete = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD);
@@ -171,8 +181,10 @@ public class AuditCreateHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
String hold3NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD3,
HOLD_REASON, HOLD_DESCRIPTION);
String hold3NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD3).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS).getId();
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");
@@ -183,7 +195,7 @@ public class AuditCreateHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditCreateHoldTests()
{
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef));
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -31,18 +31,20 @@ 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.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import java.util.List;
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;
@@ -62,14 +64,13 @@ 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 hold = PREFIX + "holdToBeDeleted";
private final String hold2 = PREFIX + "deleteHold";
private final String hold3 = PREFIX + "deleteHoldWithReason";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
@@ -79,8 +80,10 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
public void preconditionForAuditDeleteHoldTests()
{
STEP("Create a new hold.");
holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD,
HOLD_REASON, HOLD_DESCRIPTION);
holdNodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(hold).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
STEP("Create 2 users with different permissions for the created hold.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
@@ -99,17 +102,51 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
public void deleteHoldEventIsAudited()
{
STEP("Create a new hold.");
String holdRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2,
HOLD_REASON, HOLD_DESCRIPTION);
String holdRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(hold2).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
rmAuditService.clearAuditLog();
STEP("Delete the created hold.");
holdsAPI.deleteHold(rmAdmin, holdRef);
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef);
STEP("Check the audit log contains the entry for the deleted hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, HOLD2,
Collections.singletonList(ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name")));
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")));
}
/**
@@ -123,7 +160,8 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to delete a hold by an user with no Read permissions over the hold.");
holdsAPI.deleteHold(rmManager.getUsername(), rmManager.getPassword(), holdNodeRef, SC_INTERNAL_SERVER_ERROR);
getRestAPIFactory().getHoldsAPI(rmManager).deleteHold(holdNodeRef);
assertStatusCode(FORBIDDEN);
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 ",
@@ -133,7 +171,7 @@ public class AuditDeleteHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditDeleteHoldTests()
{
holdsAPI.deleteHold(getAdminUser(), holdNodeRef);
getRestAPIFactory().getHoldsAPI(rmManager).deleteHold(holdNodeRef);
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -25,10 +25,14 @@
* #L%
*/
package org.alfresco.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.*;
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.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;
@@ -37,20 +41,22 @@ 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.*;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
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;
@@ -69,8 +75,6 @@ public class AuditHoldsTest extends BaseRMRestTest {
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin;
private RecordCategory recordCategory;
@@ -85,8 +89,11 @@ public class AuditHoldsTest extends BaseRMRestTest {
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
STEP("Create a hold");
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1, HOLD_REASON,
HOLD_DESCRIPTION);
hold1NodeRef = getRestAPIFactory()
.getFilePlansAPI(rmAdmin)
.createHold(Hold.builder().name(HOLD1).description(HOLD_DESCRIPTION).reason(HOLD_REASON).build(), FILE_PLAN_ALIAS)
.getId();
STEP("Create a collaboration site with a test file.");
publicSite = dataSite.usingAdmin().createPublicRandomSite();
@@ -101,9 +108,11 @@ 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());
final List<String> holdsList = Collections.singletonList(HOLD1);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), recordToBeAdded.getId(), HOLD1);
holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(), itemsList, holdsList);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(recordToBeAdded.getId()).build(), hold1NodeRef);
for(String childId : itemsList)
{
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, childId);
}
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.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.FORBIDDEN;
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,12 +50,13 @@ 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,8 +87,6 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
@@ -96,10 +95,11 @@ 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,10 +111,18 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite();
STEP("Create new holds.");
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);
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();
holdsListRef = asList(hold1NodeRef, hold2NodeRef, hold3NodeRef);
STEP("Create a new record category with a record folder.");
@@ -127,9 +135,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
heldRecordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "heldRecFolder");
heldRecord = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
holdsAPI.addItemsToHolds(getAdminUser().getUsername(), getAdminUser().getPassword(),
asList(heldContent.getNodeRefWithoutVersion(), heldRecordFolder.getId(), heldRecord.getId()),
holdsList);
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);
});
STEP("Create users without rights to remove content from a hold.");
rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite,
@@ -179,7 +190,7 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Remove node from hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD3);
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold3NodeRef, nodeId);
STEP("Check the audit log contains the entry for the remove from hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), REMOVE_FROM_HOLD, rmAdmin, nodeName, nodePath,
@@ -198,9 +209,8 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Try to remove the record from a hold by an user with no rights.");
holdsAPI.removeItemsFromHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(heldRecord.getId()),
Collections.singletonList(hold1NodeRef));
getRestAPIFactory().getHoldsAPI(rmManagerNoReadOnHold).deleteHoldChild(hold1NodeRef, heldRecord.getId());
assertStatusCode(FORBIDDEN);
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 ",
@@ -220,12 +230,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record");
STEP("Add the record folder to a hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(notEmptyRecFolder.getId()).build(), hold1NodeRef);
rmAuditService.clearAuditLog();
STEP("Remove record folder from hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, notEmptyRecFolder.getId());
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
@@ -247,8 +257,8 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
rmAuditService.clearAuditLog();
STEP("Remove record folder from multiple holds.");
holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(heldRecordFolder.getId()), asList(HOLD1, HOLD2));
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldRecordFolder.getId());
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold2NodeRef, heldRecordFolder.getId());
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
@@ -275,12 +285,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldFile.getNodeRefWithoutVersion()).build(), hold1NodeRef);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldFile.getNodeRefWithoutVersion());
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 ",
@@ -298,12 +308,12 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).addChildToHold(HoldChild.builder().id(heldFile.getNodeRefWithoutVersion()).build(), hold1NodeRef);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHoldChild(hold1NodeRef, heldFile.getNodeRefWithoutVersion());
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, REMOVE_FROM_HOLD);
@@ -318,7 +328,7 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
@AfterClass (alwaysRun = true)
public void cleanUpAuditRemoveFromHoldTests()
{
holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef));
holdsListRef.forEach(holdRef -> getRestAPIFactory().getHoldsAPI(rmAdmin).deleteHold(holdRef));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
deleteRecordCategory(recordCategory.getId());

View File

@@ -60,12 +60,15 @@ 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;
@@ -514,5 +517,97 @@ 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

@@ -0,0 +1,614 @@
/*
* #%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.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.v0.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

@@ -0,0 +1,386 @@
/*-
* #%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

@@ -0,0 +1,186 @@
/*-
* #%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

@@ -0,0 +1,337 @@
/*-
* #%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.HoldEntry;
import org.alfresco.rest.rm.community.model.hold.v0.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

@@ -0,0 +1,374 @@
/*-
* #%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,6 +62,7 @@ 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;
@@ -289,10 +290,11 @@ public class UpdateRecordsTests extends BaseRMRestTest
* </pre>
*/
@Test
(
dataProvider = "completeRecords",
description = "Complete records can't be updated"
)
(
dataProvider = "completeRecords",
description = "Complete records can't be updated",
retryAnalyzer = AlfrescoRetryAnalyzer.class
)
@AlfrescoTest(jira="RM-4362")
@Bug (id = "APPS-132")
public void completeRecordsCantBeUpdated(String electronicRecordId, String nonElectronicRecordId)

View File

@@ -0,0 +1,377 @@
/*-
* #%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

@@ -0,0 +1,270 @@
/*-
* #%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

@@ -0,0 +1,44 @@
/*
* #%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

@@ -0,0 +1 @@
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.1.1.13-SNAPSHOT</version>
<version>23.3.0.67</version>
</parent>
<modules>

View File

@@ -139,3 +139,26 @@ 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,6 +31,11 @@
<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

@@ -538,6 +538,11 @@
<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,6 +89,9 @@
<!-- 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

@@ -0,0 +1,59 @@
<?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,6 +31,7 @@
<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">
@@ -69,7 +70,40 @@
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.unfiledcontainers.UnfiledContainerEntityResource">
<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">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
@@ -114,6 +148,20 @@
<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,6 +1614,8 @@
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,6 +41,8 @@ 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.1.1.13-SNAPSHOT</version>
<version>23.3.0.67</version>
</parent>
<properties>
@@ -84,6 +84,11 @@
<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>
@@ -150,6 +155,12 @@
<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,6 +27,7 @@
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;
@@ -77,6 +78,8 @@ 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,6 +47,7 @@ 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

@@ -0,0 +1,265 @@
/*
* #%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

@@ -0,0 +1,34 @@
/*
* #%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

@@ -0,0 +1,83 @@
/*
* #%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

@@ -0,0 +1,46 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <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

@@ -0,0 +1,37 @@
/*
* #%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

@@ -0,0 +1,40 @@
/*
* #%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

@@ -0,0 +1,165 @@
/*
* #%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
}
}

View File

@@ -0,0 +1,54 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
import java.util.List;
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkMonitor;
/**
* An interface for monitoring the progress of a bulk hold operation
*/
public interface HoldBulkMonitor extends BulkMonitor<HoldBulkStatus>
{
/**
* Get the bulk statuses with process details for a hold
*
* @param holdId the hold id
* @return the bulk statuses with process details
*/
List<HoldBulkStatusAndProcessDetails> getBulkStatusesWithProcessDetails(String holdId);
/**
* Get the bulk status with process details
*
* @param holdId the hold id
* @param bulkStatusId the bulk status id
* @return the bulk status with process details
*/
HoldBulkStatusAndProcessDetails getBulkStatusWithProcessDetails(String holdId, String bulkStatusId);
}

View File

@@ -0,0 +1,38 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.bulk.hold;
import java.io.Serializable;
import org.alfresco.module.org_alfresco_module_rm.bulk.BulkOperation;
/**
* A simple immutable POJO to hold the details of a bulk process
*/
public record HoldBulkProcessDetails(String bulkStatusId, String creatorInstance, BulkOperation bulkOperation) implements Serializable
{
}

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