Compare commits

..

300 Commits

Author SHA1 Message Date
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
295 changed files with 9484 additions and 3690 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.35</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.35</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.35</version>
</parent>
<build>
@@ -74,6 +74,16 @@
<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.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
@@ -96,11 +106,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;
@@ -243,4 +244,14 @@ public class RestAPIFactory
{
return getGSCoreAPI(null).usingActionsExecutionsAPI();
}
public HoldsAPI getHoldsAPI()
{
return getGSCoreAPI(null).usingHoldsAPI();
}
public HoldsAPI getHoldsAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingHoldsAPI();
}
}

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,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,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 HoldChildEntry 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

@@ -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;
@@ -190,4 +191,6 @@ public class GSCoreAPI extends RMModelRequest
{
return new ActionsExecutionAPI(getRmRestWrapper());
}
public HoldsAPI usingHoldsAPI() { return new HoldsAPI(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,290 @@
/*
* #%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.Hold;
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);
}
}

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

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

@@ -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.35</version>
</parent>
<modules>

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.11
SOLR6_TAG=2.0.10
POSTGRES_TAG=15.4
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8

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

@@ -69,7 +69,32 @@
<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" />
</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" />

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

@@ -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.35</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>

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

@@ -219,7 +219,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
}
else
{
return rmContainerCacheManager.get(storeRef);
return new HashSet<>(rmContainerCacheManager.get(storeRef));
}
return results;

View File

@@ -111,6 +111,24 @@ public interface HoldService
*/
void setHoldReason(NodeRef hold, String reason);
/**
* Sets the reason for the hold deletion
*
* @param hold The {@link NodeRef} of the hold
* @param reason {@link String} The reason for the hold
*/
void setHoldDeletionReason(NodeRef hold, String reason);
/**
* Updates a hold with the given name, reason and description
*
* @param hold The {@link NodeRef} of the hold
* @param name {@link String} The name of the hold
* @param reason {@link String} The reason of the hold
* @param description {@link String} The description of the hold
*/
void updateHold(NodeRef hold, String name, String reason, String description);
/**
* Deletes the hold
*

View File

@@ -29,6 +29,7 @@ package org.alfresco.module.org_alfresco_module_rm.hold;
import static org.alfresco.model.ContentModel.ASPECT_LOCKABLE;
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
import static org.alfresco.model.ContentModel.PROP_DESCRIPTION;
import static org.alfresco.model.ContentModel.PROP_NAME;
import java.io.Serializable;
@@ -458,11 +459,11 @@ public class HoldServiceImpl extends ServiceBaseImpl
// create map of properties
Map<QName, Serializable> properties = new HashMap<>(3);
properties.put(ContentModel.PROP_NAME, name);
properties.put(PROP_NAME, name);
properties.put(PROP_HOLD_REASON, reason);
if (description != null && !description.isEmpty())
{
properties.put(ContentModel.PROP_DESCRIPTION, description);
properties.put(PROP_DESCRIPTION, description);
}
// create assoc name
@@ -512,6 +513,39 @@ public class HoldServiceImpl extends ServiceBaseImpl
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#setHoldDeletionReason(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
@Override
public void setHoldDeletionReason(NodeRef hold, String reason)
{
ParameterCheck.mandatory("hold", hold);
ParameterCheck.mandatory("reason", reason);
if (nodeService.exists(hold) && isHold(hold))
{
nodeService.setProperty(hold, PROP_HOLD_DELETION_REASON, reason);
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#updateHold(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String, java.lang.String) (org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void updateHold(NodeRef hold, String name, String reason, String description)
{
ParameterCheck.mandatory("hold", hold);
ParameterCheck.mandatory("name", name);
ParameterCheck.mandatory("reason", reason);
if (nodeService.exists(hold) && isHold(hold))
{
nodeService.setProperty(hold, PROP_NAME, name);
nodeService.setProperty(hold, PROP_HOLD_REASON, reason);
nodeService.setProperty(hold, PROP_DESCRIPTION, description);
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#deleteHold(org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -563,7 +597,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
if (permissionService.hasPermission(nodeRef, permission) == AccessStatus.DENIED)
{
heldNames.add((String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME));
heldNames.add((String) nodeService.getProperty(nodeRef, PROP_NAME));
}
}
catch (AccessDeniedException ade)
@@ -630,7 +664,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
{
if (!isHold(hold))
{
final String holdName = (String) nodeService.getProperty(hold, ContentModel.PROP_NAME);
final String holdName = (String) nodeService.getProperty(hold, PROP_NAME);
throw new IntegrityException(I18NUtil.getMessage("rm.hold.not-hold", holdName), null);
}
@@ -688,7 +722,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
{
if (!isRecordFolder(nodeRef) && !instanceOf(nodeRef, ContentModel.TYPE_CONTENT))
{
final String nodeName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
final String nodeName = (String) nodeService.getProperty(nodeRef, PROP_NAME);
throw new IntegrityException(I18NUtil.getMessage("rm.hold.add-to-hold-invalid-type", nodeName), null);
}
@@ -795,7 +829,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
{
if (!isHold(hold))
{
final String holdName = (String) nodeService.getProperty(hold, ContentModel.PROP_NAME);
final String holdName = (String) nodeService.getProperty(hold, PROP_NAME);
throw new IntegrityException(I18NUtil.getMessage("rm.hold.not-hold", holdName), null);
}

View File

@@ -35,6 +35,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Roy Wetherall
*/
@SuppressWarnings("PMD.ConstantsInInterface")
@AlfrescoPublicApi
public interface RecordsManagementModel extends RecordsManagementCustomModel
{
@@ -200,6 +201,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
// Hold type
QName TYPE_HOLD = QName.createQName(RM_URI, "hold");
QName PROP_HOLD_REASON = QName.createQName(RM_URI, "holdReason");
QName PROP_HOLD_DELETION_REASON = QName.createQName(RM_URI, "holdDeletionReason");
//since 3.2
@Deprecated
QName ASSOC_FROZEN_RECORDS = QName.createQName(RM_URI, "frozenRecords");

View File

@@ -0,0 +1,155 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.fileplans;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.HoldModel;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.transaction.TransactionService;
import org.springframework.beans.factory.InitializingBean;
/**
* File plan holds relation
*
* @author Damian Ujma
*/
@RelationshipResource(name = "holds", entityResource = FilePlanEntityResource.class, title = "Holds in a file plan")
public class FilePlanHoldsRelation implements
RelationshipResourceAction.Create<HoldModel>,
RelationshipResourceAction.Read<HoldModel>,
InitializingBean
{
private FilePlanComponentsApiUtils apiUtils;
private ApiNodesModelFactory nodesModelFactory;
private HoldService holdService;
private FileFolderService fileFolderService;
private TransactionService transactionService;
@Override
public void afterPropertiesSet() throws Exception
{
mandatory("apiUtils", this.apiUtils);
mandatory("nodesModelFactory", this.nodesModelFactory);
mandatory("holdService", this.holdService);
mandatory("fileFolderService", this.fileFolderService);
mandatory("transactionService", this.transactionService);
}
@Override
@WebApiDescription(title = "Return a paged list of holds for the file plan identified by 'filePlanId'")
public CollectionWithPagingInfo<HoldModel> readAll(String filePlanId, Parameters parameters)
{
checkNotBlank("filePlanId", filePlanId);
mandatory("parameters", parameters);
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, RecordsManagementModel.TYPE_FILE_PLAN);
List<NodeRef> holds = holdService.getHolds(parentNodeRef);
List<HoldModel> page = holds.stream()
.map(hold -> fileFolderService.getFileInfo(hold))
.map(nodesModelFactory::createHoldModel)
.skip(parameters.getPaging().getSkipCount())
.limit(parameters.getPaging().getMaxItems())
.collect(Collectors.toCollection(LinkedList::new));
int totalItems = holds.size();
boolean hasMore = parameters.getPaging().getSkipCount() + parameters.getPaging().getMaxItems() < totalItems;
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, hasMore, totalItems);
}
@Override
@WebApiDescription(title = "Create one (or more) holds in a file plan identified by 'filePlanId'")
public List<HoldModel> create(String filePlanId, List<HoldModel> holds, Parameters parameters)
{
checkNotBlank("filePlanId", filePlanId);
mandatory("holds", holds);
mandatory("parameters", parameters);
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, RecordsManagementModel.TYPE_FILE_PLAN);
RetryingTransactionCallback<List<NodeRef>> callback = () -> {
List<NodeRef> createdNodes = new LinkedList<>();
for (HoldModel nodeInfo : holds)
{
NodeRef newNodeRef = holdService.createHold(parentNodeRef, nodeInfo.name(), nodeInfo.reason(),
nodeInfo.description());
createdNodes.add(newNodeRef);
}
return createdNodes;
};
List<NodeRef> createdNodes = transactionService.getRetryingTransactionHelper()
.doInTransaction(callback, false, true);
return createdNodes.stream()
.map(hold -> fileFolderService.getFileInfo(hold))
.map(nodesModelFactory::createHoldModel)
.collect(Collectors.toCollection(LinkedList::new));
}
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setHoldService(HoldService holdService)
{
this.holdService = holdService;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
}

View File

@@ -0,0 +1,207 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.holds;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.integrity.IntegrityException;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.HoldChild;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.transaction.TransactionService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Hold children relation
*
* @author Damian Ujma
*/
@RelationshipResource(name = "children", entityResource = HoldsEntityResource.class, title = "Children of a hold")
public class HoldsChildrenRelation implements
RelationshipResourceAction.Create<HoldChild>,
RelationshipResourceAction.Read<HoldChild>,
RelationshipResourceAction.Delete,
InitializingBean
{
private HoldService holdService;
private FilePlanComponentsApiUtils apiUtils;
private ApiNodesModelFactory nodesModelFactory;
private TransactionService transactionService;
private FileFolderService fileFolderService;
private PermissionService permissionService;
@Override
public void afterPropertiesSet() throws Exception
{
mandatory("holdService", holdService);
mandatory("apiUtils", apiUtils);
mandatory("nodesModelFactory", nodesModelFactory);
mandatory("transactionService", transactionService);
mandatory("fileFolderService", fileFolderService);
}
@Override
@WebApiDescription(title = "Add one (or more) children as children of a hold identified by 'holdId'")
public List<HoldChild> create(String holdId, List<HoldChild> children, Parameters parameters)
{
// validate parameters
checkNotBlank("holdId", holdId);
mandatory("children", children);
mandatory("parameters", parameters);
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
RetryingTransactionCallback<List<NodeRef>> callback = () -> {
List<NodeRef> createdNodes = children.stream()
.map(holdChild -> new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, holdChild.id()))
.collect(Collectors.toList());
try
{
holdService.addToHold(parentNodeRef, createdNodes);
}
catch (IntegrityException exception)
{
// Throw 400 Bad Request when a node with id 'holdId' is not a hold or a child cannot be added to a hold
throw new InvalidArgumentException(exception.getMsgId()).initCause(exception);
}
return createdNodes;
};
List<NodeRef> nodeInfos = transactionService.getRetryingTransactionHelper()
.doInTransaction(callback, false, true);
return nodeInfos.stream()
.map(nodeRef -> new HoldChild(nodeRef.getId()))
.collect(Collectors.toCollection(LinkedList::new));
}
@Override
@WebApiDescription(title = "Return a paged list of hold children for the hold identified by 'holdId'")
public CollectionWithPagingInfo<HoldChild> readAll(String holdId, Parameters parameters)
{
checkNotBlank("holdId", holdId);
mandatory("parameters", parameters);
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
List<NodeRef> children = holdService.getHeld(parentNodeRef);
List<HoldChild> page = children.stream()
.map(NodeRef::getId)
.map(HoldChild::new)
.skip(parameters.getPaging().getSkipCount())
.limit(parameters.getPaging().getMaxItems())
.collect(Collectors.toCollection(LinkedList::new));
int totalItems = children.size();
boolean hasMore = parameters.getPaging().getSkipCount() + parameters.getPaging().getMaxItems() < totalItems;
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, hasMore, totalItems);
}
@Override
@WebApiDescription(title = "Remove a child from a hold", description = "Remove a child with id 'childId' from a hold with id 'holdId'")
public void delete(String holdId, String childId, Parameters parameters)
{
checkNotBlank("holdId", holdId);
checkNotBlank("childId", childId);
mandatory("parameters", parameters);
NodeRef nodeRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
NodeRef childRef = apiUtils.lookupByPlaceholder(childId);
if (permissionService.hasReadPermission(childRef) == AccessStatus.DENIED)
{
throw new PermissionDeniedException(I18NUtil.getMessage("permissions.err_access_denied"));
}
RetryingTransactionCallback<List<NodeRef>> callback = () -> {
try
{
holdService.removeFromHold(nodeRef, childRef);
}
catch (IntegrityException exception)
{
// Throw 400 Bad Request when a node with id 'holdId' is not a hold
throw new InvalidArgumentException(exception.getMsgId()).initCause(exception);
}
return null;
};
transactionService.getRetryingTransactionHelper().doInTransaction(callback, false, true);
}
public void setHoldService(HoldService holdService)
{
this.holdService = holdService;
}
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
}

View File

@@ -0,0 +1,184 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.holds;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.rest.framework.Operation;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.HoldDeletionReason;
import org.alfresco.rm.rest.api.model.HoldModel;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
/**
* Hold entity resource
*
* @author Damian Ujma
*/
@EntityResource(name = "holds", title = "Holds")
public class HoldsEntityResource implements
EntityResourceAction.ReadById<HoldModel>,
EntityResourceAction.Update<HoldModel>,
EntityResourceAction.Delete,
InitializingBean
{
private FilePlanComponentsApiUtils apiUtils;
private FileFolderService fileFolderService;
private ApiNodesModelFactory nodesModelFactory;
private HoldService holdService;
private TransactionService transactionService;
@Override
public void afterPropertiesSet() throws Exception
{
mandatory("nodesModelFactory", nodesModelFactory);
mandatory("apiUtils", apiUtils);
mandatory("fileFolderService", fileFolderService);
mandatory("holdService", holdService);
mandatory("transactionService", transactionService);
}
@Override
@WebApiDescription(title = "Get hold information", description = "Get information for a hold with id 'holdId'")
@WebApiParam(name = "holdId", title = "The hold id")
public HoldModel readById(String holdId, Parameters parameters)
{
checkNotBlank("holdId", holdId);
mandatory("parameters", parameters);
NodeRef hold = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
FileInfo info = fileFolderService.getFileInfo(hold);
return nodesModelFactory.createHoldModel(info);
}
@Override
@WebApiDescription(title = "Update a hold", description = "Updates a hold with id 'holdId'")
public HoldModel update(String holdId, HoldModel holdModel, Parameters parameters)
{
checkNotBlank("holdId", holdId);
mandatory("holdModel", holdModel);
mandatory("holdModel.name", holdModel.name());
mandatory("holdModel.reason", holdModel.reason());
mandatory("parameters", parameters);
NodeRef nodeRef = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
RetryingTransactionCallback<Void> callback = () -> {
holdService.updateHold(nodeRef, holdModel.name(), holdModel.reason(), holdModel.description());
return null;
};
transactionService.getRetryingTransactionHelper().doInTransaction(callback, false, true);
RetryingTransactionCallback<FileInfo> readCallback = () -> fileFolderService.getFileInfo(nodeRef);
FileInfo info = transactionService.getRetryingTransactionHelper().doInTransaction(readCallback, false, true);
return nodesModelFactory.createHoldModel(info);
}
@Override
@WebApiDescription(title = "Delete hold", description = "Deletes a hold with id 'holdId'")
public void delete(String holdId, Parameters parameters)
{
checkNotBlank("holdId", holdId);
mandatory("parameters", parameters);
NodeRef hold = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
RetryingTransactionCallback<Void> callback = () -> {
holdService.deleteHold(hold);
return null;
};
transactionService.getRetryingTransactionHelper().doInTransaction(callback, false, true);
}
@Operation("delete")
@WebApiDescription(title = "Delete hold with a reason",
successStatus = HttpServletResponse.SC_OK)
public HoldDeletionReason deleteHoldWithReason(String holdId, HoldDeletionReason reason, Parameters parameters,
WithResponse withResponse)
{
checkNotBlank("holdId", holdId);
mandatory("reason", reason);
mandatory("parameters", parameters);
NodeRef hold = apiUtils.lookupAndValidateNodeType(holdId, RecordsManagementModel.TYPE_HOLD);
String deletionReason = reason.reason();
RetryingTransactionCallback<Void> callback = () -> {
if (StringUtils.isNotBlank(deletionReason))
{
holdService.setHoldDeletionReason(hold, deletionReason);
}
holdService.deleteHold(hold);
return null;
};
transactionService.getRetryingTransactionHelper().doInTransaction(callback, false, true);
return reason;
}
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setHoldService(HoldService holdService)
{
this.holdService = holdService;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
}

View File

@@ -0,0 +1,36 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/**
* Package info that defines the Information Governance Holds REST API
*
* @author Damian Ujma
*/
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
package org.alfresco.rm.rest.api.holds;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.WebApi;

View File

@@ -47,6 +47,7 @@ import org.alfresco.rest.api.model.UserInfo;
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.FilePlan;
import org.alfresco.rm.rest.api.model.HoldModel;
import org.alfresco.rm.rest.api.model.RMNode;
import org.alfresco.rm.rest.api.model.Record;
import org.alfresco.rm.rest.api.model.RecordCategory;
@@ -637,6 +638,21 @@ public class ApiNodesModelFactory
}
}
/**
* Creates an object of type HoldModel
*
* @param info info of the hold
* @return HoldModel object
*/
public HoldModel createHoldModel(FileInfo info)
{
return new HoldModel(info.getNodeRef().getId(),
(String) info.getProperties().get(ContentModel.PROP_NAME),
(String) info.getProperties().get(ContentModel.PROP_DESCRIPTION),
(String) info.getProperties().get(RecordsManagementModel.PROP_HOLD_REASON));
}
/**
* Creates an object of type FilePlan
*

View File

@@ -0,0 +1,36 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
/**
* Hold Child POJO for use in the v1 REST API.
*
* @author Damian Ujma
*/
public record HoldChild(String id)
{
}

View File

@@ -0,0 +1,36 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
/**
* Hold Deletion Reason POJO for use in the v1 REST API.
*
* @author Damian Ujma
*/
public record HoldDeletionReason(String reason)
{
}

View File

@@ -0,0 +1,36 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
/**
* Hold POJO for use in the v1 REST API.
*
* @author Damian Ujma
*/
public record HoldModel(String id, String name, String description, String reason)
{
}

View File

@@ -139,7 +139,7 @@ public class JSONConversionComponentTest extends BaseRMTestCase
Serializable value = stringValue;
if (type.equals("boolean"))
{
value = new Boolean(stringValue);
value = Boolean.valueOf(stringValue);
}
return value;
}

View File

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

View File

@@ -4,8 +4,8 @@
# Version label
version.major=23
version.minor=1
version.revision=1
version.minor=3
version.revision=0
version.label=
# Edition label

View File

@@ -87,6 +87,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
/** test values */
private static final String HOLD_NAME = "holdname";
private static final String HOLD_REASON = "holdreason";
private static final String HOLD_DELETION_REASON = "holddeletionreason";
private static final String HOLD_DESCRIPTION = "holddescription";
private static final String GENERIC_ERROR_MSG = "any error message text";
@@ -173,7 +174,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
}
@Test (expected=AlfrescoRuntimeException.class)
public void getHold()
public void testGetHold()
{
// setup node service interactions
when(mockedNodeService.getChildByName(eq(holdContainer), eq(ContentModel.ASSOC_CONTAINS), anyString())).thenReturn(null)
@@ -194,19 +195,19 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
}
@Test (expected=RuntimeException.class)
public void getHeldNotAHold()
public void testGetHeldNotAHold()
{
holdService.getHeld(recordFolder);
}
@Test
public void getHeldNoResults()
public void testGetHeldNoResults()
{
assertTrue(holdService.getHeld(hold).isEmpty());
}
@Test
public void getHeldWithResults()
public void testGetHeldWithResults()
{
// setup record folder in hold
List<ChildAssociationRef> holds = new ArrayList<>(2);
@@ -259,7 +260,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
}
@Test
public void getHoldReason()
public void testGetHoldReason()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
@@ -306,6 +307,80 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
verify(mockedNodeService).setProperty(hold, PROP_HOLD_REASON, HOLD_REASON);
}
@Test
public void setHoldDeletionReasonForNodeDoesNotExist()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(false);
// node does not exist
holdService.setHoldDeletionReason(hold, HOLD_DELETION_REASON);
verify(mockedNodeService, never()).setProperty(hold, PROP_HOLD_DELETION_REASON, HOLD_DELETION_REASON);
}
@Test
public void setHoldDeletionReasonForNodeIsNotAHold()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(true);
// node isn't a hold
holdService.setHoldDeletionReason(recordFolder, HOLD_DELETION_REASON);
verify(mockedNodeService, never()).setProperty(hold, PROP_HOLD_DELETION_REASON, HOLD_DELETION_REASON);
}
@Test
public void setHoldDeletionReason()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(true);
// set hold deletion reason
holdService.setHoldDeletionReason(hold, HOLD_DELETION_REASON);
verify(mockedNodeService).setProperty(hold, PROP_HOLD_DELETION_REASON, HOLD_DELETION_REASON);
}
@Test
public void updateHoldThatDoesNotExist()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(false);
// node does not exist
holdService.updateHold(hold, HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION);
verify(mockedNodeService, never()).setProperty(any(NodeRef.class), any(QName.class), any(String.class));
}
@Test
public void updateHoldThatIsNotAHold()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(true);
// node isn't a hold
holdService.updateHold(recordFolder, HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION);
verify(mockedNodeService, never()).setProperty(any(NodeRef.class), any(QName.class), any(String.class));
}
@Test
public void updateHold()
{
// setup node service interactions
when(mockedNodeService.exists(hold))
.thenReturn(true);
// update hold
holdService.updateHold(hold, HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION);
verify(mockedNodeService).setProperty(hold, ContentModel.PROP_NAME, HOLD_NAME);
verify(mockedNodeService).setProperty(hold, ContentModel.PROP_DESCRIPTION, HOLD_DESCRIPTION);
verify(mockedNodeService).setProperty(hold, PROP_HOLD_REASON, HOLD_REASON);
}
@Test (expected=AlfrescoRuntimeException.class)
public void deleteHoldNotAHold()
{

View File

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

View File

@@ -7,7 +7,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.35</version>
</parent>
<build>

View File

@@ -38,6 +38,8 @@ tags:
description: Retrieve and manage unfiled records containers
- name: unfiled-record-folders
description: Retrieve and manage unfiled record folders
- name: holds
description: Retrieve and manage holds
paths:
## GS sites
@@ -418,6 +420,124 @@ paths:
description: New name clashes with an existing node in the current parent container
'422':
description: Model integrity exception, including node name with invalid characters
'/file-plans/{filePlanId}/holds':
get:
tags:
- file-plans
summary: Get all holds in a file plan
description: |
Returns a list of holds.
operationId: getHolds
parameters:
- $ref: '#/parameters/filePlanIdWithAliasParam'
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/HoldPaging'
'401':
description: Authentication failed
'403':
description: Current user does not have permission to read **filePlanId**
'404':
description: "**filePlanId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
post:
tags:
- file-plans
summary: Create holds for a file plan
description: |
Creates a new hold.
You must specify at least a **name** and a **reason** property.
**Note:** You can create more than one hold by specifying a list of holds in the JSON body.
For example, the following JSON body creates two holds:
```JSON
[
{
"name":"Hold1",
"description": "Description1",
"reason": "Reason1"
},
{
"name":"Hold2",
"description": "Description2",
"reason": "Reason2"
}
]
```
If you specify a list as input, then a paginated list rather than an entry is returned in the response body. For example:
```JSON
{
"list": {
"pagination": {
"count": 2,
"hasMoreItems": false,
"totalItems": 2,
"skipCount": 0,
"maxItems": 100
},
"entries": [
{
"entry": {
...
}
},
{
"entry": {
...
}
}
]
}
}
```
operationId: addHold
parameters:
- $ref: '#/parameters/filePlanIdWithAliasParam'
- in: body
name: nodeBodyCreate
description: The node information to create.
required: true
schema:
$ref: '#/definitions/HoldCreateBodyModel'
consumes:
- application/json
produces:
- application/json
responses:
'201':
description: Successful response
schema:
$ref: '#/definitions/HoldModelEntry'
'400':
description: |
Invalid parameter: **filePlanId** is not a valid format or **HoldCreateBodyModel** is not valid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to create a hold
'404':
description: |
**filePlanId** does not exist
'409':
description: A hold with the name **name** already exists
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
## Unfiled records containers
'/unfiled-containers/{unfiledContainerId}':
get:
@@ -2092,6 +2212,289 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
## Holds
'/holds/{holdId}':
get:
tags:
- holds
summary: Get a hold
description: |
Gets information for hold with id **holdId**.
operationId: getHold
parameters:
- $ref: '#/parameters/holdIdParam'
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/HoldModelEntry'
'400':
description: |
Invalid parameter: **holdId** is not a valid format
'401':
description: Authentication failed
'403':
description: Current user does not have permission to read **holdId**
'404':
description: "**holdId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
put:
tags:
- holds
summary: Update a hold
description: |
Updates the hold with id **holdId**. For example, you can rename a hold:
```JSON
{
"name":"My new name",
"description":"Existing description",
"reason":"Existing reason"
}
```
operationId: updateHold
parameters:
- $ref: '#/parameters/holdIdParam'
- in: body
name: holdBodyUpdate
description: The hold information to update.
required: true
schema:
$ref: '#/definitions/HoldCreateBodyModel'
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/HoldModelEntry'
'400':
description: |
Invalid parameter: the update request is invalid or **holdId** is not a valid format or **holdBodyUpdate** is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to update **holdId**
'404':
description: "**holdId** does not exist"
'409':
description: Updated name clashes with an existing node in the current parent folder
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
delete:
tags:
- holds
summary: Delete a hold
description: |
Deletes the hold with id **holdId**.
operationId: deleteHold
parameters:
- $ref: '#/parameters/holdIdParam'
produces:
- application/json
responses:
'204':
description: Successful response
'400':
description: |
Invalid parameter: **holdId** is not a valid format
'401':
description: Authentication failed
'403':
description: Current user does not have permission to delete **holdId**
'404':
description: "**holdId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/holds/{holdId}/delete':
post:
tags:
- holds
summary: Delete a hold with a reason
description: |
Deletes the hold with id **holdId** and stores a reason for deletion in the audit log.
A **reason** must be specified in the request body.
operationId: deleteHoldWithReason
parameters:
- $ref: '#/parameters/holdIdParam'
- in: body
name: holdDeletionReason
description: Reason for deletion.
required: true
schema:
$ref: '#/definitions/HoldDeletionReason'
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/HoldDeletionReasonEntry'
'400':
description: |
Invalid parameter: **holdId** is not a valid format
'401':
description: Authentication failed
'403':
description: Current user does not have permission to update or delete **holdId**
'404':
description: "**holdId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/holds/{holdId}/children':
post:
tags:
- holds
summary: Add children to a hold
description: |
Add a child of a hold with id **holdId**.
You must specify the child **id**.
The API returns a 201 Created if the child is already a child of the hold.
**Note:** You can add more than one child by specifying a list of children in the JSON body.
For example, the following JSON body adds two children:
```JSON
[
{
"id":"a7c10f46-b85b-4de5-af1c-930056b736a7"
},
{
"id":"e0d79b71-be2b-4ce7-a846-a7c50cba20fb"
}
]
```
If you specify a list as input, then a paginated list rather than an entry is returned in the response body. For example:
```JSON
{
"list": {
"pagination": {
"count": 2,
"hasMoreItems": false,
"totalItems": 2,
"skipCount": 0,
"maxItems": 100
},
"entries": [
{
"entry": {
...
}
},
{
"entry": {
...
}
}
]
}
}
```
operationId: addChildToHold
parameters:
- $ref: '#/parameters/holdIdParam'
- in: body
name: nodeId
description: The node id.
required: true
schema:
$ref: '#/definitions/HoldChild'
consumes:
- application/json
produces:
- application/json
responses:
'201':
description: Successful response
schema:
$ref: '#/definitions/HoldChildEntry'
'400':
description: |
Invalid parameter: **holdId** is not a valid format or **HoldChild** is not valid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to add items to the hold
'404':
description: |
**holdId** does not exist
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
tags:
- holds
summary: Get children of a hold
description: |
Returns a list of children of a hold with id **holdId**.
operationId: getHoldChildren
parameters:
- $ref: '#/parameters/holdIdParam'
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/HoldChildPaging'
'401':
description: Authentication failed
'403':
description: Current user does not have permission to read **holdId**
'404':
description: "**holdId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/holds/{holdId}/children/{holdChildId}':
delete:
tags:
- holds
summary: Delete a child of a hold
description: |
Deletes the relationship between a child with id **holdChildId** and a parent hold with id **holdId**.
operationId: removeHoldChild
parameters:
- $ref: '#/parameters/holdIdParam'
- $ref: '#/parameters/holdChildIdParam'
produces:
- application/json
responses:
'204':
description: Successful response
'400':
description: |
Invalid parameter: **holdChildId** or **holdId** is not a valid format
'401':
description: Authentication failed
'403':
description: Current user does not have permission to delete **holdChildId**
'404':
description: " **holdChildId** or **holdId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
parameters:
## File plans
@@ -2175,7 +2578,7 @@ parameters:
description: Also include **source** (in addition to **entries**) with folder information on the parent node the specified parent **unfiledContainerId**
required: false
type: boolean
## Unfiled record folders
## Unfiled record folders
unfiledRecordFolderIdParam:
name: unfiledRecordFolderId
in: path
@@ -2446,6 +2849,19 @@ parameters:
items:
type: string
collectionFormat: csv
# Holds
holdIdParam:
name: holdId
in: path
description: The identifier of a hold.
required: true
type: string
holdChildIdParam:
name: holdChildId
in: path
description: The identifier of a child of a hold.
required: true
type: string
## Record
recordIdParam:
name: recordId
@@ -3519,6 +3935,89 @@ definitions:
properties:
association:
$ref: '#/definitions/ChildAssociationInfo'
## Holds
HoldModelEntry:
type: object
required:
- entry
properties:
entry:
$ref: '#/definitions/HoldModel'
HoldModel:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
reason:
type: string
HoldCreateBodyModel:
type: object
required:
- name
- reason
properties:
name:
type: string
description:
type: string
reason:
type: string
HoldPaging:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/HoldModelEntry'
HoldChild:
type: object
required:
- id
properties:
id:
type: string
HoldChildEntry:
type: object
required:
- entry
properties:
entry:
$ref: '#/definitions/HoldChild'
HoldChildPaging:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/HoldChildEntry'
HoldDeletionReasonEntry:
type: object
required:
- entry
properties:
entry:
$ref: '#/definitions/HoldDeletionReason'
HoldDeletionReason:
type: object
required:
- reason
properties:
reason:
type: string
##
RequestBodyFile:
type: object

View File

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

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>23.1.1.13-SNAPSHOT</version>
<version>23.3.0.35</version>
</parent>
<properties>
@@ -70,6 +70,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>

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.1.1.13-SNAPSHOT</version>
<version>23.3.0.35</version>
</parent>
<dependencies>
@@ -126,6 +126,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.mockito</groupId>
<artifactId>mockito-core</artifactId>
@@ -158,6 +163,13 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skipCoreTests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>

View File

@@ -0,0 +1,59 @@
/*
* #%L
* Alfresco Repository
* %%
* 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;
import org.junit.experimental.categories.Categories;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Categories.class)
@Suite.SuiteClasses({
org.alfresco.config.SystemPropertiesSetterBeanTest.class,
org.alfresco.encryption.AlfrescoKeyStoreTest.class,
org.alfresco.encryption.EncryptingOutputStreamTest.class,
org.alfresco.error.AlfrescoRuntimeExceptionTest.class,
org.alfresco.query.CannedQueryTest.class,
org.alfresco.util.BridgeTableTest.class,
org.alfresco.util.CachingDateFormatTest.class,
org.alfresco.util.DynamicallySizedThreadPoolExecutorTest.class,
org.alfresco.util.EqualsHelperTest.class,
org.alfresco.util.GuidTest.class,
org.alfresco.util.ISO8601DateFormatTest.class,
org.alfresco.util.LogAdapterTest.class,
org.alfresco.util.LogTeeTest.class,
org.alfresco.util.PathMapperTest.class,
org.alfresco.util.TempFileProviderTest.class,
org.alfresco.util.VersionNumberTest.class,
org.alfresco.util.collections.CollectionUtilsTest.class,
org.alfresco.util.exec.ExecParameterTokenizerTest.class,
org.alfresco.util.exec.RuntimeExecBeansTest.class,
org.alfresco.util.exec.RuntimeExecTest.class,
org.alfresco.util.random.NormalDistributionHelperTest.class,
org.alfresco.util.shard.ExplicitShardingPolicyTest.class,
org.alfresco.util.transaction.SpringAwareUserTransactionTest.class
})
public class AllCoreUnitTestSuite {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
* Copyright (C) 2005-2023 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -55,11 +55,11 @@ public class CannedQueryTest extends TestCase
RESULTS_TWO = new ArrayList<Long>(10);
for (int i = 0; i < 10; i++)
{
RESULTS_TWO.add(new Long(i));
RESULTS_TWO.add(Long.valueOf(i));
}
ANTI_RESULTS = new HashSet<Object>();
ANTI_RESULTS.add("ONE_5");
ANTI_RESULTS.add(new Long(5));
ANTI_RESULTS.add(Long.valueOf(5));
}
@SuppressWarnings("rawtypes")

View File

@@ -25,6 +25,7 @@ import junit.framework.TestCase;
*
* @author Roy Wetherall
*/
@SuppressWarnings({"PMD.DetachedTestCase", "PMD.JUnit4TestShouldUseTestAnnotation"})
public class VersionNumberTest extends TestCase
{
public void testCreate()
@@ -136,4 +137,36 @@ public class VersionNumberTest extends TestCase
assertEquals(-1, version8.compareTo(version9));
assertEquals(-1, version9.compareTo(version10));
}
public void testCompareNewSchema() {
// module min/max repo version is 23, actual ACS version is 23.1.0 which is greater than module
VersionNumber repoVersionMin = new VersionNumber("23");
VersionNumber repoVerisionActual = new VersionNumber("23.1.0");
assertEquals(1, repoVerisionActual.compareTo(repoVersionMin));
// module min/max repo version is 23.2, actual ACS version is 23.1.1 which is lower than module
repoVersionMin = new VersionNumber("23.2");
repoVerisionActual = new VersionNumber("23.1.1");
assertEquals(-1, repoVerisionActual.compareTo(repoVersionMin));
// module min/max repo version is 7.4, actual ACS version is 23.1.0 which is greater than module
repoVersionMin = new VersionNumber("7.4");
repoVerisionActual = new VersionNumber("23.1.0");
assertEquals(1, repoVerisionActual.compareTo(repoVersionMin));
// module min/max repo version is 24, actual ACS version is 24.1.0 which is greater than module
repoVersionMin = new VersionNumber("24");
repoVerisionActual = new VersionNumber("24.1.0");
assertEquals(1, repoVerisionActual.compareTo(repoVersionMin));
// module min/max repo version is 24, actual ACS version is 23.2.0 which is lower than module
repoVersionMin = new VersionNumber("24");
repoVerisionActual = new VersionNumber("23.2.0");
assertEquals(-1, repoVerisionActual.compareTo(repoVersionMin));
// module min/max repo version is 24.2, actual ACS version is 24.2.0 which is equal to module
repoVersionMin = new VersionNumber("24.2");
repoVerisionActual = new VersionNumber("24.2.0");
assertEquals(0, repoVerisionActual.compareTo(repoVersionMin));
}
}

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.1.1.13-SNAPSHOT</version>
<version>23.3.0.35</version>
</parent>
<properties>
@@ -193,14 +193,6 @@
<artifactId>tika-parsers-standard-package</artifactId>
<version>${dependency.tika.version}</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
@@ -224,10 +216,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15to18</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
@@ -247,6 +235,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.antlr</groupId>
<artifactId>gunit</artifactId>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Data model classes
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -121,7 +121,7 @@ public class AssociationRef implements EntityRef, Serializable
String targetNodeRefStr = tokenizer.nextToken();
String assocTypeQNameStr = tokenizer.nextToken();
this.id = new Long(idStr);
this.id = Long.valueOf(idStr);
this.sourceRef = new NodeRef(sourceNodeRefStr);
this.targetRef = new NodeRef(targetNodeRefStr);
this.assocTypeQName = QName.createQName(assocTypeQNameStr);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Data model classes
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -391,7 +391,7 @@ public class DefaultTypeConverter extends TypeConverter
{
public Boolean convert(Number source)
{
return new Boolean(source.longValue() > 0);
return Boolean.valueOf(source.longValue() > 0);
}
});
addConverter(Number.class, Byte.class, new TypeConverter.Converter<Number, Byte>()
@@ -549,8 +549,8 @@ public class DefaultTypeConverter extends TypeConverter
//
// Boolean ->
//
final Long LONG_FALSE = new Long(0L);
final Long LONG_TRUE = new Long(1L);
final Long LONG_FALSE = Long.valueOf(0L);
final Long LONG_TRUE = Long.valueOf(1L);
addConverter(Boolean.class, Long.class, new TypeConverter.Converter<Boolean, Long>()
{
public Long convert(Boolean source)

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