Compare commits

...

145 Commits

Author SHA1 Message Date
alfresco-build
06d500311c [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-31 07:05:57 +00:00
alfresco-build
8d95ffc9ff [maven-release-plugin][skip ci] prepare release 23.3.0.86 2024-07-31 07:05:54 +00:00
varapathijanakiram
6e05d5d157 Merge pull request #2832 from Alfresco/feature/MNT-24400-Suggester-feature
Suggester feature in Share
2024-07-31 11:54:20 +05:30
vjanakiram
dfff72849d I have added bean 2024-07-29 21:17:30 +05:30
alfresco-build
d60172e860 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-28 00:07:08 +00:00
alfresco-build
3cac4e8206 [maven-release-plugin][skip ci] prepare release 23.3.0.85 2024-07-28 00:07:05 +00:00
Alfresco CI User
b35a64d14f [force] Force release for 2024-07-28. 2024-07-28 00:04:10 +00:00
alfresco-build
10e78191dd [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-25 21:03:12 +00:00
alfresco-build
6290c46d62 [maven-release-plugin][skip ci] prepare release 23.3.0.84 2024-07-25 21:03:09 +00:00
Tiago Salvado
8a61badabc [MNT-24513] Immutable user (IDS): allow to change enabled status (#2789)
* [MNT-24513] Immutable user: allow enabled status change

* [MNT-24513] Created 'allow.immutable.user.enabled.status.update' to control whether an immutabled user enabled status can be changed or not

* [MNT-24513] Regardless user details enabled status, the person nodeRef enabled status is also checked

* [MNT-24513] Prevent LDAP users from being disabled. Changed variable name.
2024-07-25 21:23:51 +01:00
alfresco-build
f9946827c4 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-24 13:18:42 +00:00
alfresco-build
b812c7856e [maven-release-plugin][skip ci] prepare release 23.3.0.83 2024-07-24 13:18:40 +00:00
Eva Vasques
a3f6e13a7c MNT-24503 - FixedAclUpdater Job - Skip count if maxSize is set (#2809) 2024-07-24 13:40:50 +01:00
alfresco-build
afffc7e870 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-24 05:54:22 +00:00
alfresco-build
fe5a01e2bd [maven-release-plugin][skip ci] prepare release 23.3.0.82 2024-07-24 05:54:20 +00:00
purusothaman-mm
03625565e9 [MNT-24292] fix for delete vulnerability (#2806) 2024-07-24 10:45:14 +05:30
alfresco-build
8d1d2b4f1b [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-23 11:55:48 +00:00
alfresco-build
1342c6a7bb [maven-release-plugin][skip ci] prepare release 23.3.0.81 2024-07-23 11:55:45 +00:00
Tom Page
17152b69fc Merge pull request #2807 from Alfresco/feature/PMD730
[skip tests] Upgrade ya-pmd-scan.
2024-07-23 12:43:50 +01:00
Tom Page
1a7027327e [skip tests] PRODENG-291 Upgrade ya-pmd-scan. 2024-07-23 12:17:46 +01:00
alfresco-build
7921969222 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-21 00:07:02 +00:00
alfresco-build
9cc93de7b2 [maven-release-plugin][skip ci] prepare release 23.3.0.80 2024-07-21 00:07:00 +00:00
Alfresco CI User
55c9cf3407 [force] Force release for 2024-07-21. 2024-07-21 00:04:10 +00:00
alfresco-build
120f45ba92 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-19 09:04:23 +00:00
alfresco-build
eacdbd3770 [maven-release-plugin][skip ci] prepare release 23.3.0.79 2024-07-19 09:04:21 +00:00
dependabot[bot]
93d4701d80 Bump dependency.cxf.version from 4.0.4 to 4.0.5 (#2794)
Bumps `dependency.cxf.version` from 4.0.4 to 4.0.5.

Updates `org.apache.cxf:cxf-rt-frontend-jaxws` from 4.0.4 to 4.0.5

Updates `org.apache.cxf:cxf-rt-frontend-jaxrs` from 4.0.4 to 4.0.5

Updates `org.apache.cxf:cxf-rt-rs-client` from 4.0.4 to 4.0.5

Updates `org.apache.cxf:cxf-rt-transports-http` from 4.0.4 to 4.0.5

Updates `org.apache.cxf:cxf-rt-ws-policy` from 4.0.4 to 4.0.5

---
updated-dependencies:
- dependency-name: org.apache.cxf:cxf-rt-frontend-jaxws
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-frontend-jaxrs
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-rs-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-transports-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-ws-policy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-19 10:22:28 +02:00
alfresco-build
64baf03818 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-18 08:49:23 +00:00
alfresco-build
e39606aec5 [maven-release-plugin][skip ci] prepare release 23.3.0.78 2024-07-18 08:49:21 +00:00
Manish Kumar
7581e07c3c Merge pull request #2790 from Alfresco/fix/PRODSEC-8922-XSS
[PRODSEC-8922] fix xss vulnerability
2024-07-18 13:41:30 +05:30
alfresco-build
a01d375e6f [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-17 11:25:21 +00:00
alfresco-build
a98f44803a [maven-release-plugin][skip ci] prepare release 23.3.0.77 2024-07-17 11:25:19 +00:00
SathishK-T
cabc38b386 [MNT-24137] Audit Issue Internal Server Error fix (#2786)
* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

* [MNT-24137][ags][tas] Audit Bug Fix

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-07-17 16:19:19 +05:30
Eva Vasques
9ed29967b7 MNT-24503 - Limits on FixedAclUpdater (#2788)
* Limit the job execution to a configurable amount of nodes (system.fixedACLsUpdater.maxItems)
    * Add query template select_NodesWithAspectIds_Limited that does a left join with alf_store and limits the results
    * Query executions by the job are now limited to maxItemBatchSize
    * Imposing the order by in the query is now configurable (system.fixedACLsUpdater.orderNodes)
2024-07-17 11:47:06 +01:00
alfresco-build
b63a3eae9b [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-17 10:20:52 +00:00
alfresco-build
1ce46c2039 [maven-release-plugin][skip ci] prepare release 23.3.0.76 2024-07-17 10:20:50 +00:00
Suneet Gupta
278aa59302 [MNT-24310] Fix AGS Rest API returning non RM objects (#2787)
* [MNT-24310] Fix AGS Rest API returning non RM objects

* [MNT-24310] Fix AGS Rest API returning non RM objects

* [MNT-24310] Fix AGS Rest API returning non RM objects

* [MNT-24310] Fix AGS Rest API returning non RM objects

* [MNT-24310] Fix AGS Rest API returning non RM objects
2024-07-17 15:14:57 +05:30
Manish Kumar
51a51ecd6b [PRODSEC-8922] fix xss vulnerability 2024-07-17 13:52:19 +05:30
alfresco-build
10f4b10ae8 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-15 16:37:35 +00:00
alfresco-build
24575c436e [maven-release-plugin][skip ci] prepare release 23.3.0.75 2024-07-15 16:37:33 +00:00
Manish Kumar
25c4b677de [PRODSEC-9364] added java-uuid-generator (#2778)
* [PRODSEC-9364] added java-uuid-generator

* [PRODSEC-9364] addressed formatting issues

* [PRODSEC-9364] removed unnecessary qualifier java.util

* [PRODSEC-9364] removed addition import and change year in header
2024-07-15 21:29:09 +05:30
alfresco-build
6f13f36c5a [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-15 09:02:19 +00:00
alfresco-build
db8b353fb1 [maven-release-plugin][skip ci] prepare release 23.3.0.74 2024-07-15 09:02:17 +00:00
Wojtek Świętoń
2ccdee122a ACS-8394 ReportPortal Integration run only on master, as an optional step 2024-07-15 10:22:29 +02:00
alfresco-build
14c1b91a9b [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-14 00:06:55 +00:00
alfresco-build
5b562edad1 [maven-release-plugin][skip ci] prepare release 23.3.0.73 2024-07-14 00:06:53 +00:00
Alfresco CI User
19e577383a [force] Force release for 2024-07-14. 2024-07-14 00:03:41 +00:00
alfresco-build
115997d367 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-12 11:42:17 +00:00
alfresco-build
de2effcefb [maven-release-plugin][skip ci] prepare release 23.3.0.72 2024-07-12 11:42:15 +00:00
Piotr Żurek
79b78448e0 ACS-8323 Switch to defaults from properties (#2776) 2024-07-12 11:31:06 +02:00
alfresco-build
05c4f2282e [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-12 08:51:41 +00:00
alfresco-build
228944c59c [maven-release-plugin][skip ci] prepare release 23.3.0.71 2024-07-12 08:51:39 +00:00
Domenico Sibilio
ec279bcd5d [skip tests] 2024-07-12 10:48:59 +02:00
Domenico Sibilio
97770fd831 Rollback Jackson from 2.17.2 to 2.15.2 (#2777) 2024-07-12 10:10:45 +02:00
alfresco-build
1a99c54074 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-11 15:54:05 +00:00
alfresco-build
b30b7bd252 [maven-release-plugin][skip ci] prepare release 23.3.0.70 2024-07-11 15:54:01 +00:00
dependabot[bot]
7ce9183360 Bump org.codehaus.groovy:groovy-json from 3.0.19 to 3.0.22 (#2734)
Bumps [org.codehaus.groovy:groovy-json](https://github.com/apache/groovy) from 3.0.19 to 3.0.22.
- [Commits](https://github.com/apache/groovy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-11 17:15:58 +02:00
dependabot[bot]
06af664a16 Bump dependency.camel.version from 4.0.0 to 4.6.0 (#2640)
Bumps `dependency.camel.version` from 4.0.0 to 4.6.0.

Updates `org.apache.camel:camel-activemq` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-core` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-spring-xml` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-amqp` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-jackson` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-direct` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-management` from 4.0.0 to 4.6.0

Updates `org.apache.camel:camel-mock` from 4.0.0 to 4.6.0

---
updated-dependencies:
- dependency-name: org.apache.camel:camel-activemq
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-spring-xml
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-amqp
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-jackson
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-direct
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-management
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-11 16:51:14 +02:00
alfresco-build
7adf58d35f [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-11 12:23:08 +00:00
alfresco-build
08e42ed877 [maven-release-plugin][skip ci] prepare release 23.3.0.69 2024-07-11 12:23:06 +00:00
Domenico Sibilio
aa2fb35b41 [skip tests] 2024-07-11 14:20:24 +02:00
Domenico Sibilio
ab1e762a65 Exclude jakarta.transaction-api from commons-dbcp2 (#2772) 2024-07-11 13:45:00 +02:00
Piotr Żurek
c6201fa2fa ACS-8323 Extend the possibility to configure the event sending strategy (#2765) 2024-07-11 12:56:45 +02:00
alfresco-build
0ab31fcc93 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-10 16:33:54 +00:00
alfresco-build
7616781ce9 [maven-release-plugin][skip ci] prepare release 23.3.0.68 2024-07-10 16:33:51 +00:00
dependabot[bot]
a7c83b9acc Bump org.codehaus.mojo:aspectj-maven-plugin from 1.14.0 to 1.15.0 (#2368)
Bumps [org.codehaus.mojo:aspectj-maven-plugin](https://github.com/mojohaus/aspectj-maven-plugin) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/mojohaus/aspectj-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/aspectj-maven-plugin/compare/aspectj-maven-plugin-1.14.0...aspectj-maven-plugin-1.15.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:aspectj-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 17:05:30 +02:00
dependabot[bot]
a09649c40a --- (#2659)
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:57:12 +02:00
dependabot[bot]
0bb0e5b5b0 Bump jakarta.json:jakarta.json-api from 2.1.2 to 2.1.3 (#2267)
Bumps [jakarta.json:jakarta.json-api](https://github.com/eclipse-ee4j/jsonp) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/eclipse-ee4j/jsonp/releases)
- [Commits](https://github.com/eclipse-ee4j/jsonp/commits)

---
updated-dependencies:
- dependency-name: jakarta.json:jakarta.json-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:56:45 +02:00
dependabot[bot]
0f1ef341f6 Bump org.awaitility:awaitility from 4.2.0 to 4.2.1 (#2515)
Bumps [org.awaitility:awaitility](https://github.com/awaitility/awaitility) from 4.2.0 to 4.2.1.
- [Changelog](https://github.com/awaitility/awaitility/blob/master/changelog.txt)
- [Commits](https://github.com/awaitility/awaitility/compare/awaitility-4.2.0...awaitility-4.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:51:06 +02:00
dependabot[bot]
48e4d8a5a6 Bump org.slf4j:slf4j-api from 2.0.9 to 2.0.13 (#2587)
Bumps org.slf4j:slf4j-api from 2.0.9 to 2.0.13.

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:50:00 +02:00
dependabot[bot]
22bd945003 Bump com.ibm.icu:icu4j from 73.2 to 75.1 (#2595)
Bumps [com.ibm.icu:icu4j](https://github.com/unicode-org/icu) from 73.2 to 75.1.
- [Release notes](https://github.com/unicode-org/icu/releases)
- [Commits](https://github.com/unicode-org/icu/commits)

---
updated-dependencies:
- dependency-name: com.ibm.icu:icu4j
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:49:35 +02:00
dependabot[bot]
12b986373e Bump jakarta.jms:jakarta.jms-api from 3.0.0 to 3.1.0 (#2131)
Bumps jakarta.jms:jakarta.jms-api from 3.0.0 to 3.1.0.

---
updated-dependencies:
- dependency-name: jakarta.jms:jakarta.jms-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:47:24 +02:00
dependabot[bot]
fbc5b738ab Bump com.sun.xml.fastinfoset:FastInfoset from 2.1.0 to 2.1.1 (#2265)
Bumps com.sun.xml.fastinfoset:FastInfoset from 2.1.0 to 2.1.1.

---
updated-dependencies:
- dependency-name: com.sun.xml.fastinfoset:FastInfoset
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:47:00 +02:00
dependabot[bot]
92c1b2fb9d Bump org.mybatis:mybatis-spring from 3.0.2 to 3.0.3 (#2330)
Bumps [org.mybatis:mybatis-spring](https://github.com/mybatis/spring) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/mybatis/spring/releases)
- [Commits](https://github.com/mybatis/spring/compare/mybatis-spring-3.0.2...mybatis-spring-3.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:46:16 +02:00
dependabot[bot]
ca3a7663a0 Bump org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0 (#2335)
Bumps org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:45:54 +02:00
dependabot[bot]
ae88784bdb Bump org.apache.commons:commons-email from 1.5 to 1.6.0 (#2386)
Bumps org.apache.commons:commons-email from 1.5 to 1.6.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:44:34 +02:00
dependabot[bot]
4f03115b69 Bump org.jsoup:jsoup from 1.16.1 to 1.18.1 (#2770)
Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.16.1 to 1.18.1.
- [Release notes](https://github.com/jhy/jsoup/releases)
- [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md)
- [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.16.1...jsoup-1.18.1)

---
updated-dependencies:
- dependency-name: org.jsoup:jsoup
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:44:13 +02:00
dependabot[bot]
8fc2da1ce9 Bump org.apache.commons:commons-dbcp2 from 2.9.0 to 2.12.0 (#2486)
Bumps org.apache.commons:commons-dbcp2 from 2.9.0 to 2.12.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:43:39 +02:00
dependabot[bot]
5f0c65b551 Bump dependency.jakarta-ee-jaxb-impl.version from 4.0.3 to 4.0.5 (#2494)
Bumps `dependency.jakarta-ee-jaxb-impl.version` from 4.0.3 to 4.0.5.

Updates `org.glassfish.jaxb:jaxb-runtime` from 4.0.3 to 4.0.5

Updates `org.glassfish.jaxb:jaxb-core` from 4.0.3 to 4.0.5

---
updated-dependencies:
- dependency-name: org.glassfish.jaxb:jaxb-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jaxb:jaxb-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:42:31 +02:00
dependabot[bot]
b3f5cf9f76 Bump jakarta.xml.bind:jakarta.xml.bind-api from 4.0.0 to 4.0.2 (#2495)
Bumps [jakarta.xml.bind:jakarta.xml.bind-api](https://github.com/jakartaee/jaxb-api) from 4.0.0 to 4.0.2.
- [Release notes](https://github.com/jakartaee/jaxb-api/releases)
- [Commits](https://github.com/jakartaee/jaxb-api/compare/4.0.0...4.0.2)

---
updated-dependencies:
- dependency-name: jakarta.xml.bind:jakarta.xml.bind-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:41:01 +02:00
dependabot[bot]
cb3934eb96 Bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.1 (#2521)
Bumps [org.apache.maven.plugins:maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.6.0 to 3.7.1.
- [Release notes](https://github.com/apache/maven-assembly-plugin/releases)
- [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.6.0...maven-assembly-plugin-3.7.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-assembly-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:38:44 +02:00
dependabot[bot]
df00db7cb7 Bump dependency.log4j.version from 2.20.0 to 2.23.1 (#2499)
Bumps `dependency.log4j.version` from 2.20.0 to 2.23.1.

Updates `org.apache.logging.log4j:log4j-slf4j2-impl` from 2.20.0 to 2.23.1

Updates `org.apache.logging.log4j:log4j-api` from 2.20.0 to 2.23.1

Updates `org.apache.logging.log4j:log4j-core` from 2.20.0 to 2.23.1

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-slf4j2-impl
  dependency-type: direct:development
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:37:30 +02:00
dependabot[bot]
af4e0c0a01 Bump dependency.cxf.version from 4.0.2 to 4.0.4 (#2505)
Bumps `dependency.cxf.version` from 4.0.2 to 4.0.4.

Updates `org.apache.cxf:cxf-rt-frontend-jaxws` from 4.0.2 to 4.0.4

Updates `org.apache.cxf:cxf-rt-frontend-jaxrs` from 4.0.2 to 4.0.4

Updates `org.apache.cxf:cxf-rt-rs-client` from 4.0.2 to 4.0.4

Updates `org.apache.cxf:cxf-rt-transports-http` from 4.0.2 to 4.0.4

Updates `org.apache.cxf:cxf-rt-ws-policy` from 4.0.2 to 4.0.4

---
updated-dependencies:
- dependency-name: org.apache.cxf:cxf-rt-frontend-jaxws
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-frontend-jaxrs
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-rs-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-transports-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.cxf:cxf-rt-ws-policy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:36:39 +02:00
dependabot[bot]
b6a56cb0f8 Bump org.apache.maven.plugins:maven-compiler-plugin (#2519)
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.13.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.13.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:35:41 +02:00
dependabot[bot]
aac9be6887 Bump net.minidev:json-smart from 2.5.0 to 2.5.1 (#2532)
Bumps [net.minidev:json-smart](https://github.com/netplex/json-smart-v2) from 2.5.0 to 2.5.1.
- [Release notes](https://github.com/netplex/json-smart-v2/releases)
- [Commits](https://github.com/netplex/json-smart-v2/compare/2.5.0...2.5.1)

---
updated-dependencies:
- dependency-name: net.minidev:json-smart
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:35:08 +02:00
dependabot[bot]
c831a5e23d Bump org.eclipse.parsson:parsson from 1.1.4 to 1.1.6 (#2572)
Bumps [org.eclipse.parsson:parsson](https://github.com/eclipse-ee4j/parsson) from 1.1.4 to 1.1.6.
- [Release notes](https://github.com/eclipse-ee4j/parsson/releases)
- [Commits](https://github.com/eclipse-ee4j/parsson/compare/1.1.4...1.1.6)

---
updated-dependencies:
- dependency-name: org.eclipse.parsson:parsson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:31:03 +02:00
dependabot[bot]
0e9633fa5b Bump commons-io:commons-io from 2.14.0 to 2.16.1 (#2575)
Bumps commons-io:commons-io from 2.14.0 to 2.16.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:30:04 +02:00
dependabot[bot]
971f8c9b46 Bump com.github.docker-java:docker-java from 3.3.2 to 3.3.6 (#2479)
Bumps [com.github.docker-java:docker-java](https://github.com/docker-java/docker-java) from 3.3.2 to 3.3.6.
- [Release notes](https://github.com/docker-java/docker-java/releases)
- [Changelog](https://github.com/docker-java/docker-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/docker-java/docker-java/compare/3.3.2...3.3.6)

---
updated-dependencies:
- dependency-name: com.github.docker-java:docker-java
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:27:35 +02:00
dependabot[bot]
cb89ed65fb Bump io.swagger:swagger-parser from 1.0.67 to 1.0.71 (#2621)
Bumps [io.swagger:swagger-parser](https://github.com/swagger-api/swagger-parser) from 1.0.67 to 1.0.71.
- [Release notes](https://github.com/swagger-api/swagger-parser/releases)
- [Commits](https://github.com/swagger-api/swagger-parser/compare/v1.0.67...v1.0.71)

---
updated-dependencies:
- dependency-name: io.swagger:swagger-parser
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:17:09 +02:00
dependabot[bot]
34357a83d8 Bump Alfresco/ya-pmd-scan from 3.0.0 to 3.0.2 (#2631)
Bumps [Alfresco/ya-pmd-scan](https://github.com/alfresco/ya-pmd-scan) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/alfresco/ya-pmd-scan/releases)
- [Commits](https://github.com/alfresco/ya-pmd-scan/compare/v3.0.0...v3.0.2)

---
updated-dependencies:
- dependency-name: Alfresco/ya-pmd-scan
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:16:14 +02:00
dependabot[bot]
b29afa2248 Bump dependency.aspectj.version from 1.9.20.1 to 1.9.22.1 (#2641)
Bumps `dependency.aspectj.version` from 1.9.20.1 to 1.9.22.1.

Updates `org.aspectj:aspectjrt` from 1.9.20.1 to 1.9.22.1
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

Updates `org.aspectj:aspectjtools` from 1.9.20.1 to 1.9.22.1
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

---
updated-dependencies:
- dependency-name: org.aspectj:aspectjrt
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.aspectj:aspectjtools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:15:43 +02:00
dependabot[bot]
c89871c4fa Bump org.mockito:mockito-core from 5.4.0 to 5.12.0 (#2642)
Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.4.0 to 5.12.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v5.4.0...v5.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:14:16 +02:00
dependabot[bot]
2a07b65e25 Bump org.apache.commons:commons-compress from 1.26.0 to 1.26.2 (#2662)
Bumps org.apache.commons:commons-compress from 1.26.0 to 1.26.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:13:33 +02:00
dependabot[bot]
36286e76e9 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.7.0 (#2676)
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.7.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.7.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:12:56 +02:00
dependabot[bot]
267a776620 Bump org.apache.xmlbeans:xmlbeans from 5.2.0 to 5.2.1 (#2666)
Bumps org.apache.xmlbeans:xmlbeans from 5.2.0 to 5.2.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:11:48 +02:00
dependabot[bot]
5da314f03a Bump commons-validator:commons-validator from 1.7 to 1.9.0 (#2671)
Bumps commons-validator:commons-validator from 1.7 to 1.9.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:11:23 +02:00
dependabot[bot]
02b43f42ef Bump com.google.guava:guava from 32.1.2-jre to 33.2.1-jre (#2674)
Bumps [com.google.guava:guava](https://github.com/google/guava) from 32.1.2-jre to 33.2.1-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:10:24 +02:00
dependabot[bot]
1bcde87d42 Bump commons-net:commons-net from 3.9.0 to 3.11.1 (#2685)
Bumps commons-net:commons-net from 3.9.0 to 3.11.1.

---
updated-dependencies:
- dependency-name: commons-net:commons-net
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 16:08:59 +02:00
dependabot[bot]
c06b210056 Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.2 (#2703)
Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.3.0 to 3.4.2.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.3.0...maven-jar-plugin-3.4.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-jar-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:26:37 +02:00
dependabot[bot]
f4a89937ef Bump org.apache.maven.plugins:maven-dependency-plugin (#2707)
Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.6.0 to 3.7.1.
- [Release notes](https://github.com/apache/maven-dependency-plugin/releases)
- [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.6.0...maven-dependency-plugin-3.7.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-dependency-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:26:12 +02:00
dependabot[bot]
fc8c37b1e2 Bump commons-logging:commons-logging from 1.2 to 1.3.3 (#2740)
Bumps commons-logging:commons-logging from 1.2 to 1.3.3.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:23:12 +02:00
dependabot[bot]
fcc4bc9ac4 Bump org.eclipse.jetty:jetty-webapp from 11.0.16 to 11.0.22 (#2739)
Bumps org.eclipse.jetty:jetty-webapp from 11.0.16 to 11.0.22.

---
updated-dependencies:
- dependency-name: org.eclipse.jetty:jetty-webapp
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:22:50 +02:00
dependabot[bot]
8ee8be1696 Bump com.networknt:json-schema-validator from 1.0.86 to 1.5.0 (#2760)
Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.86 to 1.5.0.
- [Release notes](https://github.com/networknt/json-schema-validator/releases)
- [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md)
- [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.86...1.5.0)

---
updated-dependencies:
- dependency-name: com.networknt:json-schema-validator
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:22:12 +02:00
dependabot[bot]
3aeb049d6b Bump dependency.rest-assured.version from 5.3.2 to 5.5.0 (#2761)
Bumps `dependency.rest-assured.version` from 5.3.2 to 5.5.0.

Updates `io.rest-assured:rest-assured` from 5.3.2 to 5.5.0
- [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt)
- [Commits](https://github.com/rest-assured/rest-assured/commits/rest-assured-5.5.0)

Updates `io.rest-assured:json-path` from 5.3.2 to 5.5.0
- [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt)
- [Commits](https://github.com/rest-assured/rest-assured/commits/rest-assured-5.5.0)

Updates `io.rest-assured:xml-path` from 5.3.2 to 5.5.0
- [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt)
- [Commits](https://github.com/rest-assured/rest-assured/commits/rest-assured-5.5.0)

Updates `io.rest-assured:json-schema-validator` from 5.3.2 to 5.5.0

---
updated-dependencies:
- dependency-name: io.rest-assured:rest-assured
  dependency-type: direct:development
  update-type: version-update:semver-minor
- dependency-name: io.rest-assured:json-path
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: io.rest-assured:xml-path
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: io.rest-assured:json-schema-validator
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:21:39 +02:00
dependabot[bot]
2311665003 Bump dependency.jackson.version from 2.15.2 to 2.17.2 (#2759)
Bumps `dependency.jackson.version` from 2.15.2 to 2.17.2.

Updates `com.fasterxml.jackson.core:jackson-core` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.15.2...jackson-core-2.17.2)

Updates `com.fasterxml.jackson.core:jackson-databind` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.datatype:jackson-datatype-joda` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-datatype-joda/compare/jackson-datatype-joda-2.15.2...jackson-datatype-joda-2.17.2)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.15.2...jackson-dataformats-text-2.17.2)

Updates `com.fasterxml.jackson.core:jackson-annotations` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.module:jackson-module-jaxb-annotations` from 2.15.2 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-modules-base/compare/jackson-modules-base-2.15.2...jackson-modules-base-2.17.2)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-joda
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.fasterxml.jackson.core:jackson-annotations
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.fasterxml.jackson.module:jackson-module-jaxb-annotations
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-10 15:21:02 +02:00
alfresco-build
90fad5d4e8 [maven-release-plugin][skip ci] prepare for next development iteration 2024-07-10 09:41:26 +00:00
alfresco-build
dee3674494 [maven-release-plugin][skip ci] prepare release 23.3.0.67 2024-07-10 09:41:24 +00:00
dependabot[bot]
91b91e3dee Bump org.projectlombok:lombok from 1.18.30 to 1.18.34 (#2729)
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.30 to 1.18.34.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.30...v1.18.34)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

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

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

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

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

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

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

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

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

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

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

* Added Undeletable and Unmovable Aspects to Data Dictionary Folder

* [APPS-2019] Updated Integration Test Cases

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

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

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

* ACS-8048 Accept multiple signature algorithms

* ACS-8048 Fix PMD issue

* ACS-8048 Log using the default signature algorithm

* ACS-8048 Refactor

---------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

Co-authored-by: Sathish Kumar <ST28@ford.com>
2024-06-25 19:34:58 +05:30
alfresco-build
8398a5dca0 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-23 00:06:44 +00:00
alfresco-build
52731727c6 [maven-release-plugin][skip ci] prepare release 23.3.0.57 2024-06-23 00:06:42 +00:00
Alfresco CI User
2f45231149 [force] Force release for 2024-06-23. 2024-06-23 00:03:45 +00:00
alfresco-build
447d0c4f56 [maven-release-plugin][skip ci] prepare for next development iteration 2024-06-19 11:19:32 +00:00
120 changed files with 4241 additions and 551 deletions

View File

@@ -138,7 +138,7 @@ jobs:
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
- uses: Alfresco/ya-pmd-scan@v3.0.0
- uses: Alfresco/ya-pmd-scan@v4.0.0
with:
classpath-build-command: "mvn test-compile -ntp -Pags -pl \"-:alfresco-community-repo-docker\""
@@ -174,6 +174,7 @@ jobs:
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -181,24 +182,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl ${{ matrix.testModule }} -am ${{ matrix.testAttributes }} -DfailIfNoTests=false "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -206,6 +213,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -253,6 +261,7 @@ jobs:
- name: "Set up the environment"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -260,24 +269,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl remote-api -Dtest=${{ matrix.testSuite }} -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -285,6 +300,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -320,6 +336,7 @@ jobs:
env:
MARIADB_VERSION: ${{ matrix.version }}
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -327,24 +344,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -352,6 +375,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -383,6 +407,7 @@ jobs:
env:
MARIADB_VERSION: 10.6
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -390,24 +415,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -415,6 +446,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -446,6 +478,7 @@ jobs:
env:
MYSQL_VERSION: 8
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -453,24 +486,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -478,6 +517,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -508,6 +548,7 @@ jobs:
env:
POSTGRES_VERSION: 13.12
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -515,24 +556,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -540,6 +587,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -570,6 +618,7 @@ jobs:
env:
POSTGRES_VERSION: 14.9
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -577,24 +626,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -602,6 +657,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -632,6 +688,7 @@ jobs:
env:
POSTGRES_VERSION: 15.4
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -639,24 +696,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -664,6 +727,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -690,6 +754,7 @@ jobs:
- name: "Run ActiveMQ"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile activemq up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.13.1
id: rp-prepare
with:
@@ -697,24 +762,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=MessagingUnitTestSuite -DfailIfNoTests=false "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.13.1
id: rp-summarize
with:
@@ -722,6 +793,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -797,6 +869,7 @@ jobs:
- name: "Set up the environment"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -804,24 +877,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=${{ matrix.testSuite }} -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco ${{ matrix.mvn-options }} "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -829,6 +908,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -895,6 +975,7 @@ jobs:
if: ${{ matrix.test-name }} == 'Integration TAS tests'
run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -902,16 +983,19 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
eval "args=($RP_OPTS)"
@@ -924,9 +1008,12 @@ jobs:
if: ${{ always() && steps.tests.outcome == 'failure' }}
run: ${TAS_SCRIPTS}/output_logs_for_failures.sh "packaging/tests/${{ matrix.pom-dir }}"
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -934,6 +1021,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.tests.outcome != 'success'
run: |
@@ -960,6 +1048,7 @@ jobs:
- name: "Run Postgres 15.4 database"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -967,24 +1056,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl :alfresco-share-services -am -Dtest=ShareServicesTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -992,6 +1087,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
@@ -1027,6 +1123,7 @@ jobs:
bash ./scripts/ci/init.sh
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -1034,10 +1131,11 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }} "${args[@]}"
@@ -1071,6 +1169,7 @@ jobs:
bash ./scripts/ci/init.sh
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -1078,10 +1177,11 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }} "${args[@]}"
@@ -1117,6 +1217,7 @@ jobs:
${{ env.TAS_SCRIPTS }}/wait-for-alfresco-start.sh "http://localhost:8080/alfresco"
mvn -B install -pl :alfresco-governance-services-automation-community-rest-api -am -Pags -Pall-tas-tests -DskipTests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare
with:
@@ -1124,25 +1225,31 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Test"
id: run-tests
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }}
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -Dskip.automationtests=false -Pags -Pall-tas-tests "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize
with:
@@ -1150,6 +1257,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<build>
@@ -98,7 +98,7 @@
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.3.2</version>
<version>3.3.6</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>

View File

@@ -49,6 +49,7 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI;
import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.UserModel;
@@ -254,4 +255,14 @@ public class RestAPIFactory
{
return getGSCoreAPI(userModel).usingHoldsAPI();
}
public RetentionScheduleAPI getRetentionScheduleAPI()
{
return getGSCoreAPI(null).usingRetentionScheduleAPI();
}
public RetentionScheduleAPI getRetentionScheduleAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingRetentionScheduleAPI();
}
}

View File

@@ -0,0 +1,58 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.retentionschedule;
import lombok.EqualsAndHashCode;
import org.alfresco.utility.model.TestModel;
import lombok.Data;
import java.util.List;
/**
* retention schedule
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class RetentionSchedule extends TestModel
{
private String id ;
private String parentId;
private String authority;
private String instructions;
private boolean isRecordLevel;
private boolean isUnpublishedUpdates;
private List<RetentionScheduleActionDefinition> actions;
public boolean getIsRecordLevel()
{
return isRecordLevel;
}
public void setIsRecordLevel(boolean recordLevel) {
isRecordLevel = recordLevel;
}
}

View File

@@ -0,0 +1,50 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.retentionschedule;
import java.util.List;
import lombok.Data;
/**
* retention schedule action definition
*/
@Data
public class RetentionScheduleActionDefinition
{
private String id;
private String name;
private int periodAmount;
private String period;
private String periodProperty;
private boolean combineRetentionStepConditions;
private List<String> events;
private boolean eligibleOnFirstCompleteEvent;
private String description;
private boolean retainRecordMetadataAfterDestruction;
private String location;
private int index;
}

View File

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

View File

@@ -0,0 +1,37 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.retentionschedule;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.alfresco.rest.core.RestModels;
@Data
public class RetentionScheduleEntry extends RestModels<RetentionSchedule, RetentionScheduleEntry>
{
@JsonProperty
private RetentionSchedule entry;
}

View File

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

View File

@@ -0,0 +1,38 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.retentionschedule;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.alfresco.rest.core.RestModels;
@Data
public class RetentionScheduleStepEntry extends RestModels<RetentionScheduleActionDefinition, RetentionScheduleStepEntry>
{
@JsonProperty
private RetentionScheduleActionDefinition entry;
}

View File

@@ -47,6 +47,7 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI;
/**
* Defines the entire GS Core API
@@ -193,4 +194,9 @@ public class GSCoreAPI extends RMModelRequest
}
public HoldsAPI usingHoldsAPI() { return new HoldsAPI(getRmRestWrapper()); }
public RetentionScheduleAPI usingRetentionScheduleAPI()
{
return new RetentionScheduleAPI(getRmRestWrapper());
}
}

View File

@@ -0,0 +1,198 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.requests.gscore.api;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleActionDefinition;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleCollection;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleStepCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
public class RetentionScheduleAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public RetentionScheduleAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* Creates a retention schedule.
*
* @param retentionScheduleModel The retentionSchedule model
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The created {@link RetentionSchedule}
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code recordCategoryId} is not a valid format or {@code recordCategoryId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* </ul>
*/
public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId, String parameters)
{
mandatoryString("recordCategoryId", recordCategoryId);
mandatoryObject("retentionScheduleModel", retentionScheduleModel);
return getRmRestWrapper().processModel(RetentionSchedule.class, requestWithBody(
POST,
toJson(retentionScheduleModel),
"record-categories/{recordCategoryId}/retention-schedules",
recordCategoryId,
parameters
));
}
/**
* See {@link #createRetentionSchedule(RetentionSchedule, String, String)}
*/
public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId)
{
return createRetentionSchedule(retentionScheduleModel, recordCategoryId, EMPTY);
}
/**
* Gets the retentionSchedule of a record category.
*
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The {@link RetentionSchedule} for the given {@code recordCategoryId}
* @throws RuntimeException for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
*</ul>
*/
public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId, String parameters)
{
mandatoryString("recordCategoryId", recordCategoryId);
return getRmRestWrapper().processModels(RetentionScheduleCollection.class, simpleRequest(
GET,
"record-categories/{recordCategoryId}/retention-schedules?{parameters}",
recordCategoryId,
parameters
));
}
/**
* See {@link #getRetentionSchedule(String, String)}
*/
public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId)
{
return getRetentionSchedule(recordCategoryId, EMPTY);
}
/**
* Creates a step in the retention schedule.
*
* @param retentionScheduleActionDefinition The retentionScheduleActionDefinition model
* @param retentionScheduleId The identifier of a retention schedule id
* @param parameters The URL parameters to add
* @return The created {@link RetentionScheduleActionDefinition}
* @throws RuntimeException for the following cases:
* <ul>
* <li>{@code retentionScheduleId} is not a valid format or {@code retentionScheduleId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code retentionScheduleId}</li>
* <li>{@code retentionScheduleId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* </ul>
*/
public RetentionScheduleActionDefinition createRetentionScheduleStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition, String retentionScheduleId, String parameters)
{
mandatoryString("retentionScheduleId", retentionScheduleId);
mandatoryObject("retentionScheduleActionDefinition", retentionScheduleActionDefinition);
return getRmRestWrapper().processModel(RetentionScheduleActionDefinition.class, requestWithBody(
POST,
toJson(retentionScheduleActionDefinition),
"retention-schedules/{retentionScheduleId}/retention-steps",
retentionScheduleId,
parameters
));
}
/**
* See {@link #createRetentionScheduleStep(RetentionScheduleActionDefinition, String)} (RetentionSchedule, String, String)}
*/
public RetentionScheduleActionDefinition createRetentionScheduleStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition, String retentionScheduleId)
{
return createRetentionScheduleStep(retentionScheduleActionDefinition, retentionScheduleId, EMPTY);
}
/**
* Gets the retentionSchedule of a record category.
*
* @param retentionScheduleId The identifier of a record category
* @param parameters The URL parameters to add
* @return The {@link RetentionScheduleActionDefinition} for the given {@code recordCategoryId}
* @throws RuntimeException for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
*</ul>
*/
public RetentionScheduleStepCollection getRetentionScheduleStep(String retentionScheduleId, String parameters)
{
mandatoryString("retentionScheduleId", retentionScheduleId);
return getRmRestWrapper().processModels(RetentionScheduleStepCollection.class, simpleRequest(
GET,
"retention-schedules/{retentionScheduleId}/retention-steps?{parameters}",
retentionScheduleId,
parameters
));
}
/**
* See {@link #getRetentionScheduleStep(String, String)}
*/
public RetentionScheduleStepCollection getRetentionScheduleStep(String recordCategoryId)
{
return getRetentionScheduleStep(recordCategoryId, EMPTY);
}
}

View File

@@ -0,0 +1,377 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.retentionschedule;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleActionDefinition;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleStepCollection;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertNotNull;
import static org.testng.AssertJUnit.assertEquals;
/**
* Retention schedule step test case
*/
public class RetentionScheduleStepTests extends BaseRMRestTest
{
private RecordCategory recordCategory;
private RetentionSchedule createdRetentionSchedule;
private final RetentionScheduleActionDefinition retentionScheduleActionDefinition = new RetentionScheduleActionDefinition();
private RetentionScheduleActionDefinition createdRetentionActionDefinition;
private UserModel nonRMuser;
private final List<String> recordCategories = new ArrayList<>();
private static final String TEST_USER = "testUser";
private static final String RECORD_CATEGORY = "recordCategory";
private static final String PERIOD_PROPERTY = "cm:created";
private static final String AUTHORITY = "authority";
private static final String INSTRUCTIONS = "instructions";
private static final int PERIOD_AMOUNT = 5;
private static final String PERIOD = "month";
private static final List<String> EVENTS = Arrays.asList("case_closed","abolished");
private static final String TRANSFER_STEP = "transfer";
private static final String RETAIN_STEP = "retain";
private static final String INVALID_PERIOD = "random";
private static final String CUTOFF_STEP = "cutoff";
private static final String DESTROY_STEP = "destroyContent";
private static final String INVALID_PASSWORD = "wrongPassword";
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@BeforeClass(alwaysRun = true)
public void preconditionForRetentionScheduleStepTests()
{
createRMSiteIfNotExists();
// create a non rm user
nonRMuser = dataUser.createRandomTestUser(TEST_USER);
//Create record category
recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = new RetentionSchedule();
retentionSchedule.setAuthority(AUTHORITY + getRandomAlphanumeric());
retentionSchedule.setInstructions(INSTRUCTIONS + getRandomAlphanumeric());
retentionSchedule.setIsRecordLevel(false);
//Create retention schedule with a valid user
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
retentionScheduleActionDefinition.setName(RETAIN_STEP);
retentionScheduleActionDefinition.setDescription(INSTRUCTIONS);
retentionScheduleActionDefinition.setPeriodAmount(PERIOD_AMOUNT);
retentionScheduleActionDefinition.setPeriodProperty(PERIOD_PROPERTY);
retentionScheduleActionDefinition.setPeriod(PERIOD);
retentionScheduleActionDefinition.setCombineRetentionStepConditions(false);
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(true);
retentionScheduleActionDefinition.setEvents(EVENTS);
}
@Test(priority = 1)
public void createRetentionScheduleStepFor422()
{
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
//Creating the first action "transfer" should give 422
actionDefinition.setName(TRANSFER_STEP);
actionDefinition.setLocation("location");
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(UNPROCESSABLE_ENTITY);
}
@Test(priority = 2)
public void createRetentionScheduleStepWithInvalidPeriodValue()
{
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
//Invalid period value
actionDefinition.setPeriod(INVALID_PERIOD);
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(BAD_REQUEST);
}
@Test(priority = 3)
public void createRetentionScheduleWithInvalidStep()
{
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(TRANSFER_STEP);
actionDefinition1.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
actionDefinition2.setName(CUTOFF_STEP);
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2,retentionSchedule.getId());
// Verify the status code
assertStatusCode(CONFLICT);
}
@Test(priority = 4)
public void createRetentionScheduleWithInvalidStepAfterDestroy()
{
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(DESTROY_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
actionDefinition2.setName(CUTOFF_STEP);
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2,retentionSchedule.getId());
// Verify the status code
assertStatusCode(CONFLICT);
}
@Test(priority = 5)
public void combineRetentionStepConditionsNotValidForNonAccessionStep()
{
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
actionDefinition.setCombineRetentionStepConditions(true);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
assertStatusCode(BAD_REQUEST);
}
@Test(priority = 6)
public void createRetentionScheduleWithSameStep()
{
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(RETAIN_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
// Verify the status code
assertStatusCode(CONFLICT);
}
@Test(priority = 7)
public void createRetentionScheduleWithMultipleTransferStep()
{
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
recordCategories.add(recordCategory.getId());
RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory);
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
actionDefinition.setName(RETAIN_STEP);
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId());
assertStatusCode(CREATED);
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(TRANSFER_STEP);
actionDefinition1.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId());
RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
actionDefinition2.setName(TRANSFER_STEP);
actionDefinition2.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId());
// Verify the status code
assertStatusCode(CREATED);
}
@Test(priority = 8)
public void createRetentionScheduleStepFor201()
{
//Create retention schedule action definition
createdRetentionActionDefinition = getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(CREATED);
// Find this retention schedule is created one or not
assertEquals(createdRetentionActionDefinition.getName(), retentionScheduleActionDefinition.getName());
assertEquals(createdRetentionActionDefinition.getDescription(), retentionScheduleActionDefinition.getDescription());
assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionScheduleActionDefinition.getPeriodAmount());
assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionScheduleActionDefinition.isCombineRetentionStepConditions());
assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent());
}
@Test(priority = 9)
public void createRetentionScheduleStepFor401()
{
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(UNAUTHORIZED);
}
@Test(priority = 10)
public void createRetentionScheduleStepFor403()
{
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionScheduleStep(retentionScheduleActionDefinition,createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(FORBIDDEN);
}
@Test(priority = 11)
public void retentionScheduleStepFor400()
{
getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId());
// Verify the status code
assertStatusCode(BAD_REQUEST);
}
@Test(priority = 12)
public void createRetentionScheduleStepFor404()
{
//Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(retentionScheduleActionDefinition,getRandomAlphanumeric());
// Verify the status code
assertStatusCode(NOT_FOUND);
}
@Test(priority = 13)
public void retentionScheduleStepFor403()
{
// Get retention schedule steps with user having no rights
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).getRetentionScheduleStep(createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(FORBIDDEN);
}
@Test(priority = 14)
public void retentionScheduleStepFor401()
{
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(UNAUTHORIZED);
}
@Test(priority = 15)
public void retentionScheduleStepWith200()
{
RetentionScheduleStepCollection receiveRetentionStepCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(createdRetentionSchedule.getId());
// Verify the status code
assertStatusCode(OK);
receiveRetentionStepCollection.getEntries().forEach(c ->
{
RetentionScheduleActionDefinition retentionActionDef = c.getEntry();
assertNotNull(retentionActionDef.getId());
// Find this retention schedule is created one or not
assertEquals(createdRetentionActionDefinition.getId(), retentionActionDef.getId());
assertEquals(createdRetentionActionDefinition.getName(), retentionActionDef.getName());
assertEquals(createdRetentionActionDefinition.getDescription(), retentionActionDef.getDescription());
assertEquals(createdRetentionActionDefinition.getPeriod(), retentionActionDef.getPeriod());
assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionActionDef.getPeriodAmount());
assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionActionDef.isCombineRetentionStepConditions());
assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionActionDef.isEligibleOnFirstCompleteEvent());
});
}
private RetentionSchedule createRetentionSchedule(RecordCategory recordCategory)
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
retentionSchedule.setAuthority(AUTHORITY + getRandomAlphanumeric());
retentionSchedule.setInstructions(INSTRUCTIONS + getRandomAlphanumeric());
retentionSchedule.setIsRecordLevel(false);
//Create retention schedule with a valid user
retentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
// Verify the status code
assertStatusCode(CREATED);
return retentionSchedule;
}
private static RetentionScheduleActionDefinition getRetentionScheduleActionDefinition()
{
RetentionScheduleActionDefinition actionDefinition = new RetentionScheduleActionDefinition();
actionDefinition.setDescription(INSTRUCTIONS);
actionDefinition.setPeriodAmount(PERIOD_AMOUNT);
actionDefinition.setPeriodProperty(PERIOD_PROPERTY);
actionDefinition.setPeriod(PERIOD);
actionDefinition.setCombineRetentionStepConditions(false);
actionDefinition.setEligibleOnFirstCompleteEvent(true);
actionDefinition.setEvents(EVENTS);
return actionDefinition;
}
@AfterClass(alwaysRun = true)
public void cleanUpRetentionScheduleStepTests()
{
rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategory.getName());
recordCategories.forEach(this::deleteRecordCategory);
dataUser.deleteUser(nonRMuser);
}
}

View File

@@ -0,0 +1,270 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.retentionschedule;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule;
import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleCollection;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.AssertJUnit.assertEquals;
/**
* This class contains the tests for the Retention Schedule CRUD V1 API
*/
public class RetentionScheduleTests extends BaseRMRestTest
{
private RecordCategory recordCategory;
private RetentionSchedule createdRetentionSchedule;
private UserModel nonRMuser;
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@BeforeClass(alwaysRun = true)
public void preconditionForRetentionScheduleTests()
{
createRMSiteIfNotExists();
// create a non rm user
nonRMuser = dataUser.createRandomTestUser("testUser");
//Create record category
recordCategory = createRootCategory(getRandomName("recordCategory"));
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a retention schedule with a user having no rights
* Then it will give 403 as status code
* </pre>
*/
@Test(priority = 1)
public void createRetentionScheduleFor403()
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
// Create retention schedule with user having no rights
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionSchedule(retentionSchedule, recordCategory.getId());
// Verify the status code
assertStatusCode(FORBIDDEN);
}
/**
* <pre>
* Given that a record category does not exists
* When I ask the API to create a retention schedule on a category Id
* Then it will give 404 as a status code
* </pre>
*/
@Test(priority = 2)
public void createRetentionScheduleFor404()
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
//Create retention schedule with category id not exist
getRestAPIFactory().getRetentionScheduleAPI().createRetentionSchedule(retentionSchedule, getRandomAlphanumeric());
// Verify the status code
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a retention schedule on a category id with a user having unauthorized access
* Then it will give 401 as a status code
* </pre>
*/
@Test(priority = 3)
public void createRetentionScheduleFor401()
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
//Create retention schedule with a user with unauthorized access
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).createRetentionSchedule(retentionSchedule, recordCategory.getId());
// Verify the status code
assertStatusCode(UNAUTHORIZED);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a retention schedule with a user having access
* Then it is created with a 201 status code
* </pre>
*/
@Test(priority = 4)
public void createRetentionScheduleFor201()
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
String authority = "authority" + getRandomAlphanumeric();
String instructions = "instructions" + getRandomAlphanumeric();
boolean isRecordLevel = false;
retentionSchedule.setAuthority(authority);
retentionSchedule.setInstructions(instructions);
retentionSchedule.setIsRecordLevel(isRecordLevel);
//Create retention schedule with a valid user
createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI()
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
// Verify the status code
assertStatusCode(CREATED);
assertEquals(createdRetentionSchedule.getAuthority(), authority);
assertEquals(createdRetentionSchedule.getInstructions(), instructions);
assertFalse(createdRetentionSchedule.getIsRecordLevel());
assertNotNull(createdRetentionSchedule.getId());
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a retention schedule on a category id having retention schedule already
* Then it will give 409 as a status code
* </pre>
*/
@Test(priority = 5)
public void createRetentionScheduleFor409()
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
//Create retention schedule on a category with already having retention schedule
getRestAPIFactory().getRetentionScheduleAPI()
.createRetentionSchedule(retentionSchedule, recordCategory.getId());
assertStatusCode(CONFLICT);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to get a retention schedule on a given categoryId with a user having no rights
* Then it will give 403
* </pre>
*/
@Test(priority = 6)
public void retentionScheduleWith403()
{
//Get retention schedule with user having no rights
getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).getRetentionSchedule(recordCategory.getId());
// Verify the status code
assertStatusCode(FORBIDDEN);
}
/**
* <pre>
* Given that a record category does not exists
* When I ask the API to get a retention schedule on a category Id
* Then it will give 404 as a status code
* </pre>
*/
@Test(priority = 7)
public void retentionScheduleWith404()
{
//Get retention schedule with category id that does not exist
getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(getRandomAlphanumeric());
// Verify the status code
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to get a retention schedule on a categoryId with a user having unauthorized access
* Then it will give 401 as a status code
* </pre>
*/
@Test(priority = 8)
public void retentionScheduleWith401()
{
//Create retention schedule with a user with unauthorized access
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).getRetentionSchedule(recordCategory.getId());
// Verify the status code
assertStatusCode(UNAUTHORIZED);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to get a retention schedule on a categoryId with a user having access
* Then it will give retentionSchedule with 200 as a status code
* </pre>
*/
@Test(priority = 9)
public void retentionScheduleWith200()
{
RetentionScheduleCollection retentionScheduleCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(recordCategory.getId());
// Verify the status code
assertStatusCode(OK);
retentionScheduleCollection.getEntries().forEach(c ->
{
RetentionSchedule retentionSchedule = c.getEntry();
String retentionScheduleId = retentionSchedule.getId();
assertNotNull(retentionScheduleId);
logger.info("Checking retention schedule " + retentionScheduleId);
// Find this retention schedule is created one or not
assertEquals(createdRetentionSchedule.getId(), retentionScheduleId);
assertEquals(createdRetentionSchedule.getParentId(),retentionSchedule.getParentId());
assertEquals(createdRetentionSchedule.getAuthority(), retentionSchedule.getAuthority());
assertEquals(createdRetentionSchedule.getInstructions(), retentionSchedule.getInstructions());
assertEquals(createdRetentionSchedule.getIsRecordLevel(), retentionSchedule.getIsRecordLevel());
assertEquals(createdRetentionSchedule.isUnpublishedUpdates(), retentionSchedule.isUnpublishedUpdates());
});
}
@AfterClass(alwaysRun = true)
public void cleanUpRetentionScheduleTests()
{
rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategory.getName());
deleteRecordCategory(recordCategory.getId());
dataUser.deleteUser(nonRMuser);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,6 +31,7 @@
<property name="personService" ref="PersonService"/>
<property name="dispositionService" ref="DispositionService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
</bean>
<bean id="searchTypesFactory" class="org.alfresco.rm.rest.api.impl.SearchTypesFactory">
@@ -147,6 +148,20 @@
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.retentionschedule.RetentionScheduleRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="dispositionService" ref="DispositionService"/>
<property name="nodeService" ref="NodeService"/>
</bean>
<bean class="org.alfresco.rm.rest.api.retentionschedule.RetentionScheduleActionRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="nodeService" ref="NodeService"/>
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
</bean>
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -59,6 +59,9 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -198,7 +201,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
/**
* Behavior to initialize the disposition schedule of a newly filed record.
*
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnFileRecord#onFileRecord(org.alfresco.service.cmr.repository.NodeRef)
* @see RecordsManagementPolicies.OnFileRecord#onFileRecord(NodeRef)
*/
@Override
@Behaviour(kind=BehaviourKind.CLASS, type="rma:record")
@@ -216,7 +219,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#refreshDispositionAction(NodeRef)
* @see DispositionService#refreshDispositionAction(NodeRef)
*/
@Override
public void refreshDispositionAction(NodeRef nodeRef)
@@ -242,7 +245,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
/** ========= Disposition Property Methods ========= */
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#registerDispositionProperty(org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty)
* @see DispositionService#registerDispositionProperty(DispositionProperty)
*/
@Override
public void registerDispositionProperty(DispositionProperty dispositionProperty)
@@ -251,7 +254,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties(boolean, java.lang.String)
* @see DispositionService#getDispositionProperties(boolean, String)
*/
@Override
public Collection<DispositionProperty> getDispositionProperties(boolean isRecordLevel, String dispositionAction)
@@ -270,7 +273,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties()
* @see DispositionService#getDispositionProperties()
*/
@Override
public Collection<DispositionProperty> getDispositionProperties()
@@ -281,12 +284,11 @@ public class DispositionServiceImpl extends ServiceBaseImpl
/** ========= Disposition Schedule Methods ========= */
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#getDispositionSchedule(NodeRef)
*/
@Override
public DispositionSchedule getDispositionSchedule(final NodeRef nodeRef)
{
DispositionSchedule ds = null;
NodeRef dsNodeRef = null;
if (isRecord(nodeRef))
{
@@ -311,36 +313,33 @@ public class DispositionServiceImpl extends ServiceBaseImpl
if (dsNextAction != null)
{
final NodeRef action = dsNextAction.getNextActionNodeRef();
if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF)))
if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF)) && !dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY))
{
if (!dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY))
final String dispositionActionName = dsNextAction.getNextActionName();
final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf();
RunAsWork<Void> runAsWork = () -> {
nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate);
return null;
};
// if the current transaction is READ ONLY set the property on the node
// in a READ WRITE transaction
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
{
final String dispositionActionName = dsNextAction.getNextActionName();
final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf();
RunAsWork<Void> runAsWork = () -> {
nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate);
return null;
};
// if the current transaction is READ ONLY set the property on the node
// in a READ WRITE transaction
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
{
transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback<Void>) () -> {
AuthenticationUtil.runAsSystem(runAsWork);
return null;
}, false, true);
}
else
{
transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback<Void>) () -> {
AuthenticationUtil.runAsSystem(runAsWork);
}
return null;
}, false, true);
}
else
{
AuthenticationUtil.runAsSystem(runAsWork);
}
if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME))
{
nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName);
}
if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME))
{
nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName);
}
}
@@ -352,7 +351,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
// Get the disposition instructions for the node reference provided
dsNodeRef = getDispositionScheduleImpl(nodeRef);
}
DispositionSchedule ds = null;
if (dsNodeRef != null)
{
ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dsNodeRef);
@@ -382,7 +381,8 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
return result;
}
@Override
public DispositionSchedule getOriginDispositionSchedule(NodeRef nodeRef)
{
NodeRef parent = this.nodeService.getPrimaryParent(nodeRef).getParentRef();
@@ -406,7 +406,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#getAssociatedDispositionSchedule(NodeRef)
*/
@Override
public DispositionSchedule getAssociatedDispositionSchedule(NodeRef nodeRef)
@@ -437,7 +437,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl
*/
private NodeRef getAssociatedDispositionScheduleImpl(NodeRef nodeRef)
{
NodeRef result = null;
ParameterCheck.mandatory("nodeRef", nodeRef);
// Make sure we are dealing with an RM node
@@ -445,6 +444,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
{
throw new AlfrescoRuntimeException("Can not find the associated retention schedule for a non records management component. (nodeRef=" + nodeRef.toString() + ")");
}
NodeRef result = null;
if (getInternalNodeService().hasAspect(nodeRef, ASPECT_SCHEDULED))
{
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ASSOC_DISPOSITION_SCHEDULE, RegexQNamePattern.MATCH_ALL);
@@ -459,7 +459,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedRecordsManagementContainer(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
* @see DispositionService#getAssociatedRecordsManagementContainer(DispositionSchedule)
*/
@Override
public NodeRef getAssociatedRecordsManagementContainer(DispositionSchedule dispositionSchedule)
@@ -477,12 +477,9 @@ public class DispositionServiceImpl extends ServiceBaseImpl
{
// TODO in the future we should be able to support disposition schedule reuse, but for now just warn that
// only the first disposition schedule will be considered
if (LOGGER.isWarnEnabled())
{
LOGGER.warn("Retention schedule has more than one associated records management container. " +
"This is not currently supported so only the first container will be considered. " +
"(dispositionScheduleNodeRef=" + dispositionSchedule.getNodeRef().toString() + ")");
}
LOGGER.atWarn().log("Retention schedule has more than one associated records management container. " +
"This is not currently supported so only the first container will be considered. " +
"(dispositionScheduleNodeRef={})", dispositionSchedule.getNodeRef());
}
// Get the container reference
@@ -495,7 +492,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#hasDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
* @see DispositionService#hasDisposableItems(DispositionSchedule)
*/
@Override
public boolean hasDisposableItems(DispositionSchedule dispositionSchdule)
@@ -537,19 +534,16 @@ public class DispositionServiceImpl extends ServiceBaseImpl
return true;
}
}
else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null)
else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null && hasDisposableItemsImpl(isRecordLevelDisposition, item))
{
if (hasDisposableItemsImpl(isRecordLevelDisposition, item));
{
return true;
}
return true;
}
}
return false;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule)
* @see DispositionService#getDisposableItems(DispositionSchedule)
*/
@Override
public List<NodeRef> getDisposableItems(DispositionSchedule dispositionSchedule)
@@ -564,7 +558,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItem(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#isDisposableItem(NodeRef)
*/
@Override
public boolean isDisposableItem(NodeRef nodeRef)
@@ -604,20 +598,18 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#createDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef, java.util.Map)
* @see DispositionService#createDispositionSchedule(NodeRef, Map)
*/
@Override
public DispositionSchedule createDispositionSchedule(NodeRef nodeRef, Map<QName, Serializable> props)
{
NodeRef dsNodeRef = null;
// Check mandatory parameters
ParameterCheck.mandatory("nodeRef", nodeRef);
// Check exists
if (!nodeService.exists(nodeRef))
{
throw new AlfrescoRuntimeException("Unable to create retention schedule, because node does not exist. (nodeRef=" + nodeRef.toString() + ")");
throw new EntityNotFoundException(nodeRef.getId());
}
// Check is sub-type of rm:recordCategory
@@ -625,10 +617,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl
if (!TYPE_RECORD_CATEGORY.equals(nodeRefType) &&
!dictionaryService.isSubClass(nodeRefType, TYPE_RECORD_CATEGORY))
{
throw new AlfrescoRuntimeException("Unable to create retention schedule on a node that is not a records management container.");
throw new InvalidArgumentException("The given id:'" + nodeRef.getId() + "' (nodeType:" + nodeRef
+ ") is not valid. Expected nodeType is:" + TYPE_RECORD_CATEGORY);
}
behaviourFilter.disableBehaviour(nodeRef, ASPECT_SCHEDULED);
NodeRef dsNodeRef = null;
try
{
// Add the schedules aspect if required
@@ -662,7 +656,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
else
{
// Error since the node already has a disposition schedule set
throw new AlfrescoRuntimeException("Unable to create retention schedule on node that already has a retention schedule.");
throw new ConstraintViolatedException("Unable to create retention schedule on node that already has a retention schedule.");
}
}
finally
@@ -686,7 +680,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
{
// make sure at least a name has been defined
String name = (String)actionDefinitionParams.get(PROP_DISPOSITION_ACTION_NAME);
if (name == null || name.length() == 0)
if (name == null || name.isEmpty())
{
throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition");
}
@@ -695,10 +689,10 @@ public class DispositionServiceImpl extends ServiceBaseImpl
// create the child association from the schedule to the action definition
NodeRef actionNodeRef = this.nodeService.createNode(schedule.getNodeRef(),
RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
ASSOC_DISPOSITION_ACTION_DEFINITIONS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName(name)),
RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
// get the updated disposition schedule and retrieve the new action definition
NodeRef scheduleParent = this.nodeService.getPrimaryParent(schedule.getNodeRef()).getParentRef();
@@ -707,7 +701,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#removeDispositionActionDefinition(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule, org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition)
* @see DispositionService#removeDispositionActionDefinition(DispositionSchedule, DispositionActionDefinition)
*/
@Override
public void removeDispositionActionDefinition(DispositionSchedule schedule, DispositionActionDefinition actionDefinition)
@@ -777,16 +771,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl
DispositionAction da;
// check if current transaction is a READ ONLY one and if true create the node in a READ WRITE transaction
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY))
{
da =
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<DispositionAction>()
{
public DispositionAction execute() throws Throwable
{
return createDispositionAction(nodeRef, props);
}
}, false, true);
if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) {
da = transactionService.getRetryingTransactionHelper().doInTransaction(
() -> createDispositionAction(nodeRef, props),
false,
true
);
}
else
{
@@ -836,13 +826,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl
Period period = dispositionActionDefinition.getPeriod();
if (period != null)
{
Date contextDate = null;
Date contextDate;
// Get the period properties value
QName periodProperty = dispositionActionDefinition.getPeriodProperty();
if (periodProperty != null)
{
if (RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty))
if (PROP_DISPOSITION_AS_OF.equals(periodProperty))
{
DispositionAction lastCompletedDispositionAction = getLastCompletedDispostionAction(nodeRef);
if (lastCompletedDispositionAction != null)
@@ -886,7 +876,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isNextDispositionActionEligible(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#isNextDispositionActionEligible(NodeRef)
*/
@Override
public boolean isNextDispositionActionEligible(NodeRef nodeRef)
@@ -940,7 +930,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
{
NodeRef eventExecution = assoc.getChildRef();
Boolean isCompleteValue = (Boolean) getInternalNodeService().getProperty(eventExecution, PROP_EVENT_EXECUTION_COMPLETE);
boolean isComplete = false;
boolean isComplete;
if (isCompleteValue != null)
{
isComplete = isCompleteValue.booleanValue();
@@ -987,7 +977,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getNextDispositionAction(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#getNextDispositionAction(NodeRef)
*/
@Override
public DispositionAction getNextDispositionAction(NodeRef nodeRef)
@@ -1006,7 +996,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
/** ========= Disposition Action History Methods ========= */
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getCompletedDispositionActions(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#getCompletedDispositionActions(NodeRef)
*/
@Override
public List<DispositionAction> getCompletedDispositionActions(NodeRef nodeRef)
@@ -1022,7 +1012,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getLastCompletedDispostionAction(org.alfresco.service.cmr.repository.NodeRef)
* @see DispositionService#getLastCompletedDispostionAction(NodeRef)
*/
@Override
public DispositionAction getLastCompletedDispostionAction(NodeRef nodeRef)
@@ -1038,7 +1028,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItemCutoff(NodeRef)
* @see DispositionService#isDisposableItemCutoff(NodeRef)
*/
@Override
public boolean isDisposableItemCutoff(NodeRef nodeRef)
@@ -1048,7 +1038,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
* @see DispositionService#updateNextDispositionAction(NodeRef)
*/
@Override
public void updateNextDispositionAction(final NodeRef nodeRef)
@@ -1058,7 +1048,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
{
/**
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
* @see RunAsWork#doWork()
*/
@Override
public Void doWork()
@@ -1077,7 +1067,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
* @see DispositionService#updateNextDispositionAction(NodeRef)
*/
@Override
public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule)
@@ -1087,7 +1077,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
{
/**
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
* @see RunAsWork#doWork()
*/
@Override
public Void doWork()
@@ -1113,16 +1103,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
List<DispositionActionDefinition> dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions();
DispositionActionDefinition currentDispositionActionDefinition = null;
DispositionActionDefinition currentDispositionActionDefinition;
DispositionActionDefinition nextDispositionActionDefinition = null;
if (currentDispositionAction == null)
if (currentDispositionAction == null && !dispositionActionDefinitions.isEmpty())
{
if (!dispositionActionDefinitions.isEmpty())
{
// The next disposition action is the first action
nextDispositionActionDefinition = dispositionActionDefinitions.get(0);
}
// The next disposition action is the first action
nextDispositionActionDefinition = dispositionActionDefinitions.get(0);
}
else
{
@@ -1167,7 +1154,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#cutoffDisposableItem(NodeRef)
* @see DispositionService#cutoffDisposableItem(NodeRef)
*/
@Override
public void cutoffDisposableItem(final NodeRef nodeRef)
@@ -1205,6 +1192,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
// runAs system so that we can close a record that has already been cutoff
authenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
recordFolderService.closeRecordFolder(nodeRef);
@@ -1224,6 +1212,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
}
@Override
public Date getDispositionActionDate(NodeRef record, NodeRef dispositionSchedule, String dispositionActionName)
{
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dispositionSchedule);
@@ -1243,7 +1232,8 @@ public class DispositionServiceImpl extends ServiceBaseImpl
}
return null;
}
@Override
public void recalculateNextDispositionStep(NodeRef record)
{
List<NodeRef> recordFolders = recordFolderService.getRecordFolders(record);
@@ -1384,14 +1374,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
Date calculatedDate = (nextDispositionActionDate != null ? nextDispositionActionDate : maxDate);
// We only need to update the date if the current one is too early.
if (recordDate.before(calculatedDate))
{
return WriteMode.DATE_ONLY;
}
else
{
return WriteMode.READ_ONLY;
}
return recordDate.before(calculatedDate) ? WriteMode.DATE_ONLY : WriteMode.READ_ONLY;
}
/**
@@ -1414,7 +1397,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, folderDS);
List<DispositionActionDefinition> dispositionActionDefinitions = ds.getDispositionActionDefinitions();
if (dispositionActionDefinitions != null && dispositionActionDefinitions.size() > 0)
if (dispositionActionDefinitions != null && !dispositionActionDefinitions.isEmpty())
{
DispositionActionDefinition firstDispositionActionDef = dispositionActionDefinitions.get(0);
dispositionNodeRef = folderDS;

View File

@@ -34,10 +34,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinitionImpl;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.AssocChild;
@@ -53,6 +59,8 @@ import org.alfresco.rm.rest.api.model.Record;
import org.alfresco.rm.rest.api.model.RecordCategory;
import org.alfresco.rm.rest.api.model.RecordCategoryChild;
import org.alfresco.rm.rest.api.model.RecordFolder;
import org.alfresco.rm.rest.api.model.RetentionPeriod;
import org.alfresco.rm.rest.api.model.RetentionSteps;
import org.alfresco.rm.rest.api.model.Transfer;
import org.alfresco.rm.rest.api.model.TransferChild;
import org.alfresco.rm.rest.api.model.TransferContainer;
@@ -61,6 +69,8 @@ import org.alfresco.rm.rest.api.model.UnfiledContainer;
import org.alfresco.rm.rest.api.model.UnfiledContainerChild;
import org.alfresco.rm.rest.api.model.UnfiledRecordFolder;
import org.alfresco.rm.rest.api.model.UnfiledRecordFolderChild;
import org.alfresco.rm.rest.api.model.RetentionSchedule;
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -70,6 +80,9 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility class containing Alfresco and RM java services required by the API
@@ -81,6 +94,9 @@ import org.alfresco.service.namespace.QName;
public class ApiNodesModelFactory
{
/** Logger */
private static final Logger LOGGER = LoggerFactory.getLogger(ApiNodesModelFactory.class);
// excluded namespaces (aspects, properties, assoc types)
public static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
@@ -102,6 +118,7 @@ public class ApiNodesModelFactory
private PersonService personService;
private DispositionService dispositionService;
private ServiceRegistry serviceRegistry;
private RecordsManagementServiceRegistry services;
public NodeService getNodeService()
{
@@ -153,6 +170,11 @@ public class ApiNodesModelFactory
this.serviceRegistry = serviceRegistry;
}
public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry services)
{
this.services = services;
}
/**
* Helper method that sets the basic information for most of the node types.
*
@@ -504,15 +526,15 @@ public class ApiNodesModelFactory
}
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
{
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordFolder(true);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordCategory(false);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
}
@@ -523,11 +545,11 @@ public class ApiNodesModelFactory
}
else
{
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
if (isRecordFolder(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordFolder(false);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
if (isRecordCategory(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsRecordCategory(true);
}
@@ -536,13 +558,28 @@ public class ApiNodesModelFactory
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
recordCategoryChild.setHasRetentionSchedule(ds != null);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
if (isRecordCategoryChildClosed(isMinimalInfo, propertyFilter, includeParam))
{
recordCategoryChild.setIsClosed(null);
}
}
}
private boolean isRecordCategoryChildClosed(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam)
{
return (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED));
}
private boolean isRecordCategory(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam)
{
return (!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY));
}
private boolean isRecordFolder(boolean isMinimalInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam)
{
return (!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER));
}
/**
* Utility method that maps record specific fields
@@ -565,7 +602,8 @@ public class ApiNodesModelFactory
{
Serializable val = info.getProperties().get(ContentModel.PROP_CONTENT);
if ((val != null) && (val instanceof ContentData)) {
if (val instanceof ContentData)
{
ContentData cd = (ContentData)val;
String mimeType = cd.getMimetype();
String mimeTypeName = serviceRegistry.getMimetypeService().getDisplaysByMimetype().get(mimeType);
@@ -891,4 +929,238 @@ public class ApiNodesModelFactory
mapAssociations(record, info, parameters.getInclude());
return record;
}
}
/**
* Helper method that sets the information for the retention schedule type.
* @param dispositionSchedule
* @return RetentionSchedule
*/
public RetentionSchedule mapRetentionScheduleData(DispositionSchedule dispositionSchedule)
{
RetentionSchedule retentionSchedule = new RetentionSchedule();
retentionSchedule.setId(dispositionSchedule.getNodeRef().getId());
if (dispositionSchedule.getNodeRef() != null) {
NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef();
retentionSchedule.setParentId(parent.getId());
}
retentionSchedule.setInstructions(dispositionSchedule.getDispositionInstructions());
retentionSchedule.setAuthority(dispositionSchedule.getDispositionAuthority());
retentionSchedule.setIsRecordLevel(dispositionSchedule.isRecordLevelDisposition());
boolean unpublishedUpdates = dispositionSchedule.getDispositionActionDefinitions().stream()
.map(DispositionActionDefinition::getNodeRef)
.anyMatch(actionDefNodeRef -> nodeService.hasAspect(actionDefNodeRef, RecordsManagementModel.ASPECT_UNPUBLISHED_UPDATE));
retentionSchedule.setUnpublishedUpdates(unpublishedUpdates);
return retentionSchedule;
}
/**
* Helper method that sets the information for the retention schedule action definition type.
* @param dispositionActionDefinition
* @return RetentionScheduleActionDefinition
*/
public RetentionScheduleActionDefinition mapRetentionScheduleActionDefData(DispositionActionDefinition dispositionActionDefinition)
{
RetentionScheduleActionDefinition retentionScheduleActionDefinition = new RetentionScheduleActionDefinition();
// Mapping basic properties
mapRetentionActionProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
// Mapping period and period amount
mapPeriodProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
// Mapping events properties
mapEventsProperties(dispositionActionDefinition, retentionScheduleActionDefinition);
return retentionScheduleActionDefinition;
}
/**
* Helper method that sets core information for the retention schedule action definition type.
* @param dispositionActionDefinition
* @param retentionScheduleActionDefinition
*/
private void mapRetentionActionProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
retentionScheduleActionDefinition.setId(dispositionActionDefinition.getId());
retentionScheduleActionDefinition.setName(dispositionActionDefinition.getName());
retentionScheduleActionDefinition.setDescription(dispositionActionDefinition.getDescription());
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent());
if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null)
{
retentionScheduleActionDefinition.setCombineRetentionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
}
retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation());
if (dispositionActionDefinition.getGhostOnDestroy() != null)
{
retentionScheduleActionDefinition.setRetainRecordMetadataAfterDestruction(dispositionActionDefinition.getGhostOnDestroy().equals("ghost"));
}
retentionScheduleActionDefinition.setIndex(dispositionActionDefinition.getIndex());
}
/**
* Helper method that sets the period-related information for the retention schedule action definition type.
* @param dispositionActionDefinition
* @param retentionScheduleActionDefinition
*/
private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
if (dispositionActionDefinition.getPeriodProperty() != null)
{
retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService));
}
String period = dispositionActionDefinition.getPeriod().toString();
if (!period.isEmpty())
{
// In rest api we are splitting `period` property into `period` and `periodAmount`.
// so we need to split the period into two properties.
// ex. period -> 'month|10' so the split properties would be like below
// period -> 'month'
// periodAmount -> 10
String[] periodArray = period.split("\\|");
if (periodArray.length > 0)
{
retentionScheduleActionDefinition.setPeriod(periodArray[0]);
}
if (periodArray.length > 1)
{
try
{
retentionScheduleActionDefinition.setPeriodAmount(Integer.parseInt(periodArray[1]));
}
catch (NumberFormatException numberFormatException)
{
LOGGER.error("Error parsing period amount: {}{}", numberFormatException.getMessage(), periodArray[1], numberFormatException);
throw numberFormatException;
}
}
}
}
/**
* Helper method that sets the events information for the retention schedule action definition type.
* @param dispositionActionDefinition
* @param retentionScheduleActionDefinition
*/
private void mapEventsProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
List<RecordsManagementEvent> events = dispositionActionDefinition.getEvents();
if (events != null && !events.isEmpty())
{
List<String> eventNames = events.stream()
.map(RecordsManagementEvent::getName)
.collect(Collectors.toList());
retentionScheduleActionDefinition.setEvents(eventNames);
}
}
/**
* Helper method that sets the optional information for the retention schedule type.
* @param retentionSchedule
* @param schedule
* @param includeParam
*/
public void mapRetentionScheduleOptionalInfo(RetentionSchedule retentionSchedule, DispositionSchedule schedule, List<String> includeParam)
{
if (includeParam != null && !includeParam.isEmpty() && includeParam.contains("actions"))
{
List<RetentionScheduleActionDefinition> actions = schedule.getDispositionActionDefinitions().stream()
.map(this::mapRetentionScheduleActionDefData)
.collect(Collectors.toList());
retentionSchedule.setActions(actions);
}
}
/**
* this method is used for creation of retention schedule action definition params
* @param nodeInfo retention schedule action definition
* @return Map<QName, Serializable>
*/
public Map<QName, Serializable> createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo)
{
Map<QName, Serializable> actionDefinitionParams= new HashMap<>();
String retentionActionName = nodeInfo.getName();
if (nodeInfo.getName().equals(RetentionSteps.DESTROY_NODE.stepName) ||
nodeInfo.getName().equals(RetentionSteps.DESTROY_CONTENT.stepName))
{
retentionActionName = "destroy";
}
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, retentionActionName);
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, nodeInfo.getDescription());
StringBuilder retentionPeriod = new StringBuilder(nodeInfo.getPeriod()).append("|");
if (isPeriodAmountApplicable(nodeInfo.getPeriod()))
{
retentionPeriod.append(nodeInfo.getPeriodAmount());
}
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, retentionPeriod.toString());
QName periodProperty = QName.createQName(nodeInfo.getPeriodProperty(), namespaceService);
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD_PROPERTY, periodProperty);
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT_COMBINATION,
nodeInfo.isEligibleOnFirstCompleteEvent());
boolean combineConditions = nodeInfo.getName().equals(RetentionSteps.ACCESSION.stepName) && nodeInfo.isCombineRetentionStepConditions();
actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, combineConditions);
if(nodeInfo.getLocation() != null && nodeInfo.getName().equals(RetentionSteps.TRANSFER.stepName))
{
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION,
nodeInfo.getLocation());
}
List<String> inputEvents = nodeInfo.getEvents();
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents);
if (RetentionSteps.DESTROY_CONTENT.stepName.equals(nodeInfo.getName()))
{
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost");
}
else if (RetentionSteps.DESTROY_NODE.stepName.equals(nodeInfo.getName()))
{
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "delete");
}
return actionDefinitionParams;
}
/**
* this method is used retrieve retention schedule action details
* @param retentionScheduleNodeRef nodeRef
* @return List<DispositionActionDefinition>
*/
public List<DispositionActionDefinition> getRetentionActions(NodeRef retentionScheduleNodeRef)
{
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(
retentionScheduleNodeRef,
RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
RegexQNamePattern.MATCH_ALL);
// we are getting disposition action definitions based on retention schedule child association.
// setting the index value for each action.
List<DispositionActionDefinition> actions;
actions = IntStream.range(0, assocs.size())
.mapToObj(index ->
{
ChildAssociationRef assoc = assocs.get(index);
return new DispositionActionDefinitionImpl(
services.getRecordsManagementEventService(),
services.getRecordsManagementActionService(),
nodeService,
assoc.getChildRef(),
index);
})
.collect(Collectors.toList());
return actions;
}
/**
* this method is used to check period amount applicable or not for particular period
* @param period period
* @return boolean
*/
private boolean isPeriodAmountApplicable(String period)
{
// periodAmount property only applicable for following periods
// day, week, month, quarter, year and duration
return period.equals(RetentionPeriod.DAY.periodName) || period.equals(RetentionPeriod.MONTH.periodName) || period.equals(RetentionPeriod.QUARTER.periodName)
|| period.equals(RetentionPeriod.WEEK.periodName) || period.equals(RetentionPeriod.XML_DURATION.periodName) || period.equals(RetentionPeriod.YEAR.periodName);
}
}

View File

@@ -92,7 +92,7 @@ public class SearchTypesFactory
boolean includeRecords = false;
boolean includeSubTypes = false;
if (q != null)
if (q != null && q.getTree() != null)
{
// filtering via "where" clause
MapBasedQueryWalker propertyWalker = new MapBasedQueryWalker(listFolderChildrenEqualsQueryProperties, null);
@@ -101,11 +101,11 @@ public class SearchTypesFactory
Boolean isUnfiledRecordFolder = propertyWalker.getProperty(UnfiledChild.PARAM_IS_UNFILED_RECORD_FOLDER,
WhereClauseParser.EQUALS, Boolean.class);
Boolean isRecord = propertyWalker.getProperty(UnfiledChild.PARAM_IS_RECORD, WhereClauseParser.EQUALS, Boolean.class);
if ((isUnfiledRecordFolder != null && isUnfiledRecordFolder.booleanValue()) || (isRecord != null && !isRecord.booleanValue()))
if (checkIncludeUnfiledRecordFolders(isUnfiledRecordFolder, isRecord))
{
includeUnfiledRecordFolders = true;
}
else if ((isUnfiledRecordFolder != null && !isUnfiledRecordFolder.booleanValue()) || (isRecord != null && isRecord.booleanValue()))
else if (checkIncludeRecords(isUnfiledRecordFolder, isRecord))
{
includeRecords = true;
}
@@ -199,11 +199,11 @@ public class SearchTypesFactory
WhereClauseParser.EQUALS, Boolean.class);
Boolean isRecordCategory = propertyWalker.getProperty(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY, WhereClauseParser.EQUALS, Boolean.class);
if ((isRecordFolder != null && isRecordFolder.booleanValue()) || (isRecordCategory != null && !isRecordCategory.booleanValue()))
if (checkIncludeUnfiledRecordFolders(isRecordFolder, isRecordCategory))
{
includeRecordFolders = true;
}
else if ((isRecordFolder != null && !isRecordFolder.booleanValue()) || (isRecordCategory != null && isRecordCategory.booleanValue()))
else if (checkIncludeRecords(isRecordFolder, isRecordCategory))
{
includeRecordCategories = true;
}
@@ -291,4 +291,16 @@ public class SearchTypesFactory
return new Pair<>(filterNodeTypeQName, filterIncludeSubTypes);
}
private static boolean checkIncludeRecords(Boolean isUnfiledRecordFolder, Boolean isRecord)
{
return (isUnfiledRecordFolder != null && !isUnfiledRecordFolder.booleanValue()) || (isRecord != null
&& isRecord.booleanValue());
}
private static boolean checkIncludeUnfiledRecordFolders(Boolean isUnfiledRecordFolder, Boolean isRecord)
{
return (isUnfiledRecordFolder != null && isUnfiledRecordFolder.booleanValue()) || (isRecord != null
&& !isRecord.booleanValue());
}
}

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.rm.rest.api.model;
/**
* Retention event values
*/
public enum RetentionEvents
{
CASE_CLOSED("case_closed"),
ABOLISHED("abolished"),
RE_DESIGNATED("re_designated"),
NO_LONGER_NEEDED("no_longer_needed"),
SUPERSEDED("superseded"),
VERSIONED("versioned"),
STUDY_COMPLETE("study_complete"),
TRAINING_COMPLETE("training_complete"),
TRANSFERRED_INACTIVE_STORAGE("related_record_trasfered_inactive_storage"),
OBSOLETE("obsolete"),
ALLOWANCES_GRANTED_TERMINATED("all_allowances_granted_are_terminated"),
WGI_ACTION_COMPLETE("WGI_action_complete"),
SEPARATION("separation"),
CASE_COMPLETE("case_complete"),
DECLASSIFICATION_REVIEW("declassification_review");
public final String eventName;
RetentionEvents(String eventName)
{
this.eventName = eventName;
}
}

View File

@@ -0,0 +1,55 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
/**
* Retention period values
*/
public enum RetentionPeriod
{
DAY("day"),
END_OF_FINANCIAL_MONTH("fmend"),
END_OF_FINANCIAL_QUARTER("fqend"),
END_OF_FINANCIAL_YEAR("fyend"),
IMMEDIATELY("immediately"),
END_OF_MONTH("monthend"),
END_OF_QUARTER("quarterend"),
END_OF_YEAR("yearend"),
MONTH("month"),
NONE("none"),
QUARTER("quarter"),
WEEK("week"),
XML_DURATION("duration"),
YEAR("year");
public final String periodName;
RetentionPeriod(String periodName)
{
this.periodName = periodName;
}
}

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.rm.rest.api.model;
import lombok.Data;
import java.util.List;
/**
* retention schedule
*/
@Data
public class RetentionSchedule
{
private String id ;
private String parentId;
private String authority;
private String instructions;
private boolean isRecordLevel;
private boolean isUnpublishedUpdates;
private List<RetentionScheduleActionDefinition> actions;
public boolean getIsRecordLevel()
{
return isRecordLevel;
}
public void setIsRecordLevel(boolean recordLevel)
{
isRecordLevel = recordLevel;
}
}

View File

@@ -0,0 +1,51 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
import java.util.List;
import lombok.Data;
/**
* retention schedule action definition
*/
@Data
public class RetentionScheduleActionDefinition
{
private String id;
private String name;
private String description;
private int periodAmount;
private String period;
private String periodProperty;
private boolean combineRetentionStepConditions;
private List<String> events;
private boolean eligibleOnFirstCompleteEvent;
private boolean retainRecordMetadataAfterDestruction;
private String location;
private int index;
}

View File

@@ -0,0 +1,47 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
/**
* Retention steps values
*/
public enum RetentionSteps
{
RETAIN("retain"),
CUTOFF("cutoff"),
TRANSFER("transfer"),
ACCESSION("accession"),
DESTROY_CONTENT("destroyContent"),
DESTROY_NODE("destroyNode");
public final String stepName;
RetentionSteps(String stepName)
{
this.stepName = stepName;
}
}

View File

@@ -0,0 +1,284 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.retentionschedule;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.UnprocessableContentException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.RetentionEvents;
import org.alfresco.rm.rest.api.model.RetentionPeriod;
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
import org.alfresco.rm.rest.api.model.RetentionSteps;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
/**
* Retention schedule action relation is used to perform the retention schedule step operations.
*/
@RelationshipResource(name = "retention-steps", entityResource = RetentionScheduleEntityResource.class, title = "Retention Schedule Action")
public class RetentionScheduleActionRelation implements RelationshipResourceAction.Read<RetentionScheduleActionDefinition>,
RelationshipResourceAction.Create<RetentionScheduleActionDefinition>
{
private FilePlanComponentsApiUtils apiUtils;
protected NodeService nodeService;
private RecordsManagementServiceRegistry service;
private ApiNodesModelFactory nodesModelFactory;
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry service)
{
this.service = service;
}
@Override
@WebApiDescription(title="Create a retention schedule step for the particular retention schedule using the 'retentionScheduleId'")
public List<RetentionScheduleActionDefinition> create(String retentionScheduleId, List<RetentionScheduleActionDefinition> nodeInfos, Parameters parameters)
{
checkNotBlank("retentionScheduleId", retentionScheduleId);
mandatory("entity", nodeInfos);
mandatory("parameters", parameters);
NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
// validation for the order of the step
retentionScheduleStepValidation(retentionScheduleNodeRef, nodeInfos.get(0));
// request property validation
retentionScheduleRequestValidation(nodeInfos.get(0));
// create the parameters for the action definition
Map<QName, Serializable> actionDefinitionParams = nodesModelFactory.createRetentionActionDefinitionParams(nodeInfos.get(0));
// create the child association from the schedule to the action definition
NodeRef actionNodeRef = this.nodeService.createNode(retentionScheduleNodeRef,
RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName(nodeInfos.get(0).getName())),
RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
DispositionSchedule dispositionSchedule = new DispositionScheduleImpl(service, nodeService, retentionScheduleNodeRef);
DispositionActionDefinition dispositionActionDefinition = dispositionSchedule.getDispositionActionDefinition(actionNodeRef.getId());
List<RetentionScheduleActionDefinition> responseActions = new ArrayList<>();
if (dispositionActionDefinition != null)
{
responseActions.add(nodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition));
}
return responseActions;
}
@Override
@WebApiDescription(title = "Return a paged list of retention schedule action definition based on the 'retentionScheduleId'")
public CollectionWithPagingInfo<RetentionScheduleActionDefinition> readAll(String retentionScheduleId, Parameters parameters)
{
checkNotBlank("retentionScheduleId", retentionScheduleId);
mandatory("parameters", parameters);
NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
List<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
List<RetentionScheduleActionDefinition> actionDefinitionList = actions.stream()
.map(nodesModelFactory::mapRetentionScheduleActionDefData)
.collect(Collectors.toList());
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), actionDefinitionList, false,
actionDefinitionList.size());
}
/**
* this method is used to validate the order of the retention schedule step
* @param retentionScheduleNodeRef nodeRef
* @param retentionScheduleActionDefinition retention schedule action definition
*/
private void retentionScheduleStepValidation(NodeRef retentionScheduleNodeRef, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
if (checkStepNameIsEmpty(retentionScheduleActionDefinition.getName()))
{
throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition");
}
List<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
Set<String> completedActions = new HashSet<>();
if (!actions.isEmpty())
{
completedActions = actions.stream()
.map(DispositionActionDefinition::getName)
.collect(Collectors.toSet());
}
if (completedActions.contains("destroy"))
{
throw new ConstraintViolatedException("Invalid Step - destroy action is already added. No other action is allowed after Destroy.");
}
if (checkStepAlreadyExists(completedActions, retentionScheduleActionDefinition.getName()))
{
throw new ConstraintViolatedException("Invalid Step - This step already exists. You cant create it again. Only transfer action is allowed multiple times.");
}
if (firstStepValidation(actions, retentionScheduleActionDefinition.getName()))
{
throw new UnprocessableContentException("Invalid Step - cutoff or retain should be the first step");
}
if (isCutOffStepAllowed(completedActions, retentionScheduleActionDefinition.getName()))
{
throw new ConstraintViolatedException("Invalid Step - Can't use cutoff after transfer or accession");
}
}
private boolean checkStepNameIsEmpty(String name)
{
return name == null || name.isEmpty();
}
/**
* this method is used to validate the request of the retention schedule
* @param retentionScheduleActionDefinition retention schedule action definition
*/
private void retentionScheduleRequestValidation(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
// step name validation
if (invalidStepNameCheck(retentionScheduleActionDefinition.getName()))
{
throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName());
}
validatePeriodAndPeriodProperty(retentionScheduleActionDefinition);
// event name validation
if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents()))
{
throw new InvalidArgumentException("event value is invalid: " + retentionScheduleActionDefinition.getEvents());
}
if (validateCombineRetentionStepConditionsForNonAccessionStep(retentionScheduleActionDefinition))
{
throw new IllegalArgumentException("combineRetentionStepConditions property is only valid for accession step. Not valid for :" + retentionScheduleActionDefinition.getName());
}
if (validateLocationForNonTransferStep(retentionScheduleActionDefinition))
{
throw new IllegalArgumentException("location property is only valid for transfer step. Not valid for :" + retentionScheduleActionDefinition.getName());
}
}
private void validatePeriodAndPeriodProperty(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
// period value validation
if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod()))
{
throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod());
}
// periodProperty validation
List<String> validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf");
if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals))
{
throw new InvalidArgumentException("periodProperty value is invalid: " + retentionScheduleActionDefinition.getPeriodProperty());
}
}
private boolean validateCombineRetentionStepConditionsForNonAccessionStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
return !retentionScheduleActionDefinition.getName().equals(RetentionSteps.ACCESSION.stepName)
&& retentionScheduleActionDefinition.isCombineRetentionStepConditions();
}
private boolean validateLocationForNonTransferStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{
return retentionScheduleActionDefinition.getLocation() != null
&& !retentionScheduleActionDefinition.getName().equals(RetentionSteps.TRANSFER.stepName)
&& !retentionScheduleActionDefinition.getLocation().isEmpty();
}
private boolean checkStepAlreadyExists(Set<String> completedActions, String stepName)
{
return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName);
}
private boolean firstStepValidation(List<DispositionActionDefinition> actions, String stepName)
{
return actions.isEmpty()
&& !stepName.equals(RetentionSteps.CUTOFF.stepName) && (!stepName.equals(RetentionSteps.RETAIN.stepName));
}
private boolean isCutOffStepAllowed(Set<String> completedActions, String stepName)
{
return (completedActions.contains(RetentionSteps.TRANSFER.stepName) || completedActions.contains(RetentionSteps.ACCESSION.stepName))
&& stepName.equals(RetentionSteps.CUTOFF.stepName);
}
private boolean invalidStepNameCheck(String stepName)
{
return stepName != null && Arrays.stream(RetentionSteps.values())
.noneMatch(retentionStep -> retentionStep.stepName.equals(stepName));
}
private boolean invalidPeriodCheck(String period)
{
return period != null && Arrays.stream(RetentionPeriod.values())
.noneMatch(retentionPeriod -> retentionPeriod.periodName.equals(period));
}
private boolean invalidEventNameCheck(List<String> events)
{
return !events.isEmpty() && events.stream()
.anyMatch(event -> Arrays.stream(RetentionEvents.values())
.noneMatch(retentionEvent -> retentionEvent.eventName.equals(event)));
}
}

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.rm.rest.api.retentionschedule;
import org.alfresco.rest.framework.resource.EntityResource;
/**
* Retention schedule entity resource
*/
@EntityResource(name="retention-schedules", title = "Retention Schedule")
public class RetentionScheduleEntityResource
{
}

View File

@@ -0,0 +1,144 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.retentionschedule;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.UnprocessableContentException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.RetentionSchedule;
import org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_AUTHORITY;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_INSTRUCTIONS;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_RECORD_LEVEL_DISPOSITION;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.TYPE_RECORD_CATEGORY;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
/**
* Retention schedule relation is used perform retention schedule operation for a record category.
*/
@RelationshipResource(name = "retention-schedules", entityResource = RecordCategoriesEntityResource.class, title = "Retention Schedule")
public class RetentionScheduleRelation implements RelationshipResourceAction.Read<RetentionSchedule>,
RelationshipResourceAction.Create<RetentionSchedule>
{
private FilePlanComponentsApiUtils apiUtils;
private ApiNodesModelFactory nodesModelFactory;
private DispositionService dispositionService;
protected NodeService nodeService;
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setDispositionService(DispositionService dispositionService)
{
this.dispositionService = dispositionService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
@Override
@WebApiDescription(title="Create a retention schedule for the particular record category using the 'recordCategoryId'")
public List<RetentionSchedule> create(String recordCategoryId, List<RetentionSchedule> nodeInfos, Parameters parameters)
{
checkNotBlank("recordCategoryId", recordCategoryId);
mandatory("entity", nodeInfos);
mandatory("parameters", parameters);
NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordCategoryId);
if (checkCategoryHasAssocFolder(parentNodeRef) && nodeInfos.get(0).getIsRecordLevel())
{
throw new UnprocessableContentException("Record level retention schedule cannot be created for a record category having folder associated.");
}
List<RetentionSchedule> result = new ArrayList<>();
// Create the disposition schedule
Map<QName, Serializable> dsProps = new HashMap<>();
dsProps.put(PROP_DISPOSITION_AUTHORITY, nodeInfos.get(0).getAuthority());
dsProps.put(PROP_DISPOSITION_INSTRUCTIONS, nodeInfos.get(0).getInstructions());
dsProps.put(PROP_RECORD_LEVEL_DISPOSITION, nodeInfos.get(0).getIsRecordLevel());
DispositionSchedule dispositionSchedule = dispositionService.createDispositionSchedule(parentNodeRef, dsProps);
RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
result.add(retentionSchedule);
return result;
}
private boolean checkCategoryHasAssocFolder(NodeRef nodeRef)
{
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
return assocs.stream()
.map(assoc -> nodeService.getType(assoc.getChildRef()))
.anyMatch(nodeType -> nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER));
}
@Override
@WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'")
public CollectionWithPagingInfo<RetentionSchedule> readAll(String recordCategoryId, Parameters parameters)
{
checkNotBlank("recordCategoryId", recordCategoryId);
mandatory("parameters", parameters);
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(recordCategoryId, TYPE_RECORD_CATEGORY);
DispositionSchedule schedule = dispositionService.getDispositionSchedule(parentNodeRef);
RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(schedule);
List<RetentionSchedule> retentionScheduleList = new ArrayList<>();
nodesModelFactory.mapRetentionScheduleOptionalInfo(retentionSchedule, schedule, parameters.getInclude());
retentionScheduleList.add(retentionSchedule);
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), retentionScheduleList, false,
retentionScheduleList.size());
}
}

View File

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

View File

@@ -51,6 +51,8 @@ import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorReg
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.junit.Assert;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -437,19 +439,12 @@ public class DispositionServiceImplTest extends BaseRMTestCase
// Check the disposition schedule
checkDispositionSchedule(ds, "testCreateDispositionSchedule", "testCreateDispositionSchedule", false);
}
});
// Failure: create disposition schedule on container with existing disposition schedule
doTestInTransaction(new FailureTest
(
"Can not create a disposition schedule on a container with an existing disposition schedule"
)
{
@Override
public void run()
{
utils.createBasicDispositionSchedule(rmContainer);
// Failure: create disposition schedule on container with existing disposition schedule
Assert.assertThrows(ConstraintViolatedException.class,
() -> {
utils.createBasicDispositionSchedule(rmContainer);
});
}
});
}
@@ -492,19 +487,12 @@ public class DispositionServiceImplTest extends BaseRMTestCase
// Check the disposition schedule
checkDispositionSchedule(testA, "testA", "testA", false);
checkDispositionSchedule(testB, "testB", "testB", false);
}
});
// Failure: create disposition schedule on container with existing disposition schedule
doTestInTransaction(new FailureTest
(
"Can not create a disposition schedule on container with an existing disposition schedule"
)
{
@Override
public void run()
{
utils.createBasicDispositionSchedule(mhContainer11);
// Failure: create disposition schedule on container with existing disposition schedule
Assert.assertThrows(ConstraintViolatedException.class,
() -> {
utils.createBasicDispositionSchedule(rmContainer);
});
}
});

View File

@@ -0,0 +1,126 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.disposition;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.model.RetentionSchedule;
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Period;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
/**
* Retention schedule model unit test
*/
public class RetentionScheduleModelUnitTest extends BaseUnitTest
{
private static final String AUTHORITY = "authority";
private static final String INSTRUCTIONS = "instructions";
private static final String RETAIN_STEP = "retain";
@InjectMocks
private ApiNodesModelFactory apiNodesModelFactory;
@Mock
DispositionSchedule dispositionSchedule;
@Mock
DispositionActionDefinition dispositionActionDefinition;
@Test
public void mapRetentionScheduleDataTest()
{
// Mock data
NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true);
ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record);
when(dispositionSchedule.getDispositionAuthority()).thenReturn(AUTHORITY);
when(dispositionSchedule.getDispositionInstructions()).thenReturn(INSTRUCTIONS);
when(dispositionSchedule.getNodeRef()).thenReturn(nodeRef);
when(dispositionSchedule.isRecordLevelDisposition()).thenReturn(false);
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
// Call the method
RetentionSchedule actualResult = apiNodesModelFactory.mapRetentionScheduleData(dispositionSchedule);
//Expected Result
RetentionSchedule expectedResult = new RetentionSchedule();
expectedResult.setId(nodeRef.getId());
expectedResult.setParentId(filePlan.getId());
expectedResult.setAuthority(AUTHORITY);
expectedResult.setInstructions(INSTRUCTIONS);
// Assertions
assertEquals(expectedResult, actualResult);
}
@Test
public void mapRetentionScheduleActionDefDataTest()
{
// Mock data
NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true);
String period = "month|10";
ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record);
when(dispositionActionDefinition.getNodeRef()).thenReturn(nodeRef);
when(dispositionActionDefinition.getName()).thenReturn(RETAIN_STEP);
when(dispositionActionDefinition.getDescription()).thenReturn("Description");
when(dispositionActionDefinition.getIndex()).thenReturn(1);
when(dispositionActionDefinition.getGhostOnDestroy()).thenReturn("ghost");
when(dispositionActionDefinition.getPeriod()).thenReturn(new Period(period));
when(dispositionActionDefinition.getLocation()).thenReturn("location");
when(dispositionActionDefinition.getId()).thenReturn(nodeRef.getId());
when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef);
// Call the method
RetentionScheduleActionDefinition actualResult = apiNodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition);
//Expected Result
RetentionScheduleActionDefinition expectedResult = getRetentionScheduleActionDefinition(nodeRef);
// Assertion
assertEquals(expectedResult, actualResult);
}
private static RetentionScheduleActionDefinition getRetentionScheduleActionDefinition(NodeRef nodeRef)
{
RetentionScheduleActionDefinition expectedResult = new RetentionScheduleActionDefinition();
expectedResult.setId(nodeRef.getId());
expectedResult.setName(RETAIN_STEP);
expectedResult.setDescription("Description");
expectedResult.setIndex(1);
expectedResult.setLocation("location");
expectedResult.setPeriod("month");
expectedResult.setPeriodAmount(10);
expectedResult.setRetainRecordMetadataAfterDestruction(true);
return expectedResult;
}
}

View File

@@ -93,15 +93,15 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity);
assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue());
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringEndLower());
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringLower());
assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc());
assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue());
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringEndLower());
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringLower());
assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc());
assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue());
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringEndLower());
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringLower());
assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc());
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<build>

View File

@@ -40,6 +40,8 @@ tags:
description: Retrieve and manage unfiled record folders
- name: holds
description: Retrieve and manage holds
- name: retention-schedules
description: Perform retention schedule specific operations
paths:
## GS sites
@@ -2634,7 +2636,196 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
##retention-schedule
'/record-categories/{recordCategoryId}/retention-schedules':
post:
tags:
- retention-schedules
summary: Create a retention schedule
description: |
Create a retention schedule.
For example, using the following JSON body will create a retention schedule:
```JSON
{
"authority": "Retention Authority",
"instructions": "Retention Instructions",
"isRecordLevel": false
}
```
operationId: createRetentionSchedule
parameters:
- $ref: '#/parameters/recordCategoryIdParam'
- in: body
name: retentionNodeBodyCreate
description: |
The retention schedule information to create.
schema:
$ref: '#/definitions/RetentionNodeBodyCreate'
consumes:
- application/json
produces:
- application/json
responses:
'201':
description: Successful response
schema:
$ref: '#/definitions/RetentionScheduleResponse'
'400':
description: |
Invalid parameter: value of recordCategoryId is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to create retention schedule
'404':
description: recordCategoryId does not exist
'409':
description: Retention schedule already exist for the given recordCategoryId
'422':
description: Record level retention schedule cannot be created for a record category having folder associated
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
tags:
- retention-schedules
summary: Get the retention schedule for a record category
description: |
Get the retention schedule for a record category.
You can use the **include** parameter (include=actions) to return additional information.
operationId: getRetentionScheduleList
parameters:
- $ref: '#/parameters/recordCategoryIdParam'
- $ref: '#/parameters/retentionScheduleIncludeParam'
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/RetentionScheduleResponseList'
'400':
description: |
Invalid parameter: value of recordCategoryId is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to get retention schedule
'404':
description: recordCategoryId does not exist
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/retention-schedules/{retentionScheduleId}/retention-steps':
post:
tags:
- retention-schedules
summary: Create a step in the retention schedule
description: |
Create a step in the retention schedule.
Order of steps:
* "**retain**" or "**cutoff**" should be first
* can't use "**cutoff**" after "**transfer**" or "**accession**"
* only the "**transfer**" action is allowed multiple times
* no steps are allowed after "**destroy**"
For example, the following JSON body will create a step in the retention schedule:
```JSON
{
"name":"accession",
"description":"Step Description",
"periodAmount": 2,
"period":"month",
"periodProperty":"cm:created",
"combineRetentionStepConditions": false,
"events":["versioned"],
"eligibleOnFirstCompleteEvent": true
}
```
operationId: createRetentionScheduleAction
parameters:
- $ref: '#/parameters/retentionScheduleIdParam'
- in: body
name: nodeBodyCreate
description: |
The retention schedule steps information to create.
required: true
schema:
$ref: '#/definitions/RetentionStepNodeBodyCreate'
consumes:
- application/json
produces:
- application/json
responses:
'201':
description: Successful response
schema:
$ref: '#/definitions/RetentionStepNodeBodyResponse'
'400':
description: |
Invalid parameter: value of retentionScheduleId is invalid
Invalid parameter (e.g. event, period, periodProperty)
'401':
description: Authentication failed
'403':
description: Current user does not have permission to create retention schedule step
'404':
description: retentionScheduleId does not exist
'409':
description: |
* Invalid Step - Can't use Cut Off after Transfer or Accession
* Invalid Step - Destroy action already completed. Can't do any other Action
* Invalid Step - This step already exists. You cant create this step [Transfer action is allowed many times]
'422':
description: Cut Off or Retain should be the first step
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
tags:
- retention-schedules
summary: Get the list of steps in the retention schedule
description: |
Get the list of steps in the retention schedule.
operationId: getRetentionScheduleActionList
parameters:
- $ref: '#/parameters/retentionScheduleIdParam'
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/RetentionStepsNodeBodyResponse'
'400':
description: |
Invalid parameter: value of retentionScheduleId is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to get retention schedule steps
'404':
description: retentionScheduleId does not exist
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
parameters:
## File plans
filePlanEntryIncludeParam:
@@ -3100,6 +3291,22 @@ parameters:
If true, then a name clash will cause an attempt to auto rename by finding a unique name using an integer suffix.
required: false
type: boolean
## RetentionSchedule
retentionScheduleIdParam:
name: retentionScheduleId
in: path
description:
The identifier of a retention schedule.
required: true
type: string
retentionScheduleIncludeParam:
name: include
in: query
description: |
Returns additional information about the retention schedule actions. Any optional field from the response model can be requested. For example:
* actions
required: false
type: string
definitions:
FilePlanComponentBodyUpdate:
type: object
@@ -4258,6 +4465,228 @@ definitions:
type: array
items:
$ref: '#/definitions/HoldBulkStatusEntry'
RetentionNodeBodyCreate:
type: object
properties:
authority:
type: string
description: |
Authority name for the retention schedule.
instructions:
type: string
description: |
Required instructions for the retention schedule.
isRecordLevel:
type: boolean
default: false
description: |
This field is used to specify whether the retention schedule needs to be applied in the folder level or record level.
True will cause the the retention schedule to apply to records and false will cause the retention schedule to apply to record folders.
This cannot be changed once items start being managed by the retention schedule.
RetentionScheduleResponse:
type: object
properties:
id:
type: string
parentId:
type: string
authority:
type: string
instructions:
type: string
isRecordLevel:
type: boolean
unpublishedUpdates:
type: boolean
RetentionScheduleResponseList:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/FullRetentionScheduleResponse'
FullRetentionScheduleResponse:
type: object
properties:
id:
type: string
parentId:
type: string
authority:
type: string
instructions:
type: string
isRecordLevel:
type: boolean
unpublishedUpdates:
type: boolean
actions:
type: array
items:
$ref: '#/definitions/Actions'
Actions:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
periodAmount:
type: integer
period:
type: string
periodProperty:
type: string
combineRetentionStepConditions:
type: boolean
default: false
eligibleOnFirstCompleteEvent:
type: boolean
default: true
retainRecordMetadataAfterDestruction:
type: boolean
location:
type: string
events:
type: array
items:
type: string
index:
type: integer
RetentionStepNodeBodyCreate:
type: object
required:
- name
- description
properties:
name:
type: string
description: |
The valid names are:
* retain
* cutoff
* accession
* transfer
* destroyContent
* destroyNode
destroyNode step can be used to destroy content along with record metadata.
In case, record metadata needs to be retained, then destroyContent step should be used.
description:
type: string
description: |
This property is used to provide the step description.
periodAmount:
type: integer
description: |
This property is only applicable for the following period values.
* day
* month
* quarter
* week
* duration
* year
period:
type: string
description: |
Valid values for the period.
* day = Day
* fmend = End Of Financial Month
* fqend = End Of Financial Quarter
* fyend = End Of Financial Year
* immediately = Immediately
* monthend = End Of Month
* quarterend = End Of Quarter
* yearend = End Of Year
* month = Month
* none = None
* quarter = Quarter
* week = Week
* duration = XML Duration
* year = Year
If you provide XML Duration for the period value, you need to specify a time interval using XML syntax.
The syntax should take the form of:
P = Period (required)
nY = Number of years
nM = Number of months
nD = Number of days
T = Start time of a time section (required if specifying hours, minutes, or seconds)
nH = Number of hours
nM = Number of minutes
nS = Number of seconds
For example, P2M10D represents two months and ten days.
periodProperty:
type: string
default: cm:created
description: |
Valid values for the periodProperty property
* cm:created = Created Date (defult value)
* rma:cutOffDate = Cut Off Date
* rma:dispositionAsOf = Retention Action
combineRetentionStepConditions:
type: boolean
description: |
This property is only valid for **accession** step.
This is used to specify whether to combine the period condition and events for the step execution or only consider one of them.
For example:
**periodCondition**: After a period of 2 months
**eventsCondition**: Case Closed event
This flag can be used to consider only (**periodCondition** or **eventsCondition**) or both of them at once.
events:
type: array
items:
type: string
description: |
Valid values for the events property
* case_closed = Case Closed
* abolished = Abolished
* re_designated = Redesignated
* no_longer_needed = No Longer Needed
* superseded = Superseded
* versioned = Versioned
* study_complete = Study Complete
* training_complete = Training Complete
* related_record_trasfered_inactive_storage = Related Record Transferred to Inactive Storage
* obsolete = Obsolete
* all_allowances_granted_are_terminated = All Allowances Granted are Terminated
* WGI_action_complete = WGI Action Complete
* separation = Separation
* case_complete = Case Complete
* declassification_review = Declassification Review
eligibleOnFirstCompleteEvent:
type: boolean
description: |
* false = When all events have happened
* true = Whichever event is earlier
location:
type: string
description: |
This property is only valid for transfer step
RetentionStepNodeBodyResponse:
type: object
properties:
actions:
$ref: '#/definitions/Actions'
RetentionStepsNodeBodyResponse:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/RetentionStepNodeBodyResponse'
##
RequestBodyFile:
type: object

View File

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

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<dependencies>
@@ -47,11 +47,11 @@
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.uuid/java-uuid-generator -->
<dependency>
<groupId>org.safehaus.jug</groupId>
<artifactId>jug</artifactId>
<version>2.0.0</version>
<classifier>asl</classifier>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>

View File

@@ -21,7 +21,7 @@ package org.alfresco.util;
import java.security.SecureRandom;
import java.util.Random;
import org.safehaus.uuid.UUIDGenerator;
import com.fasterxml.uuid.Generators;
import org.alfresco.api.AlfrescoPublicApi;
/**
@@ -69,7 +69,7 @@ public final class GUID
public static String generate()
{
int randomInt = RANDOM.nextInt(SECURE_RANDOM_POOL_MAX_ITEMS);
return UUIDGenerator.getInstance().generateRandomBasedUUID(SECURE_RANDOM_POOL[randomInt]).toString();
return Generators.randomBasedGenerator(SECURE_RANDOM_POOL[randomInt]).generate().toString();
}
// == Not sure if we need this functionality again (derekh) ==

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -33,13 +33,13 @@ import java.util.HashSet;
import java.util.Set;
import java.util.zip.CRC32;
import com.fasterxml.uuid.Generators;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.service.cmr.repository.datatype.Duration;
import org.alfresco.util.GUID;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.safehaus.uuid.UUIDGenerator;
import org.alfresco.util.ParameterCheck;
/**
@@ -497,7 +497,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
this.userName = userName;
this.validDuration = validDuration;
this.testDuration = validDuration.divide(2);
final String guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
final String guid = Generators.randomBasedGenerator().generate().toString();
this.ticketId = computeTicketId(expires, expiryDate, userName, guid);

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<dependencies>
@@ -84,7 +84,7 @@
<include>org.alfresco:alfresco-core</include>
<include>org.alfresco:alfresco-repository</include>
<include>org.apache.commons:commons-compress</include>
<include>org.safehaus.jug:jug</include>
<include>com.fasterxml.uuid:java-uuid-generator</include>
<include>org.alfresco.surf:spring-surf-core</include>
<include>org.tukaani:xz</include>
<include>org.apache.maven:maven-artifact</include>

View File

@@ -25,6 +25,7 @@
*/
package org.alfresco.repo.module.tool;
import com.fasterxml.uuid.Generators;
import de.schlichtherle.truezip.file.*;
import de.schlichtherle.truezip.fs.FsSyncException;
import de.schlichtherle.truezip.fs.archive.zip.JarDriver;
@@ -34,7 +35,6 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.module.ModuleVersionNumber;
import org.alfresco.service.cmr.module.ModuleDetails;
import org.alfresco.service.cmr.module.ModuleInstallState;
import org.safehaus.uuid.UUIDGenerator;
import java.io.BufferedInputStream;
import java.io.IOException;
@@ -916,7 +916,7 @@ public class ModuleManagementTool implements LogOutput
*/
private static String generateGuid()
{
return UUIDGenerator.getInstance().generateTimeBasedUUID().toString();
return Generators.timeBasedGenerator().generate().toString();
}
/**

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<organization>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>
@@ -17,7 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<rest.api.explorer.branch>master</rest.api.explorer.branch>
<httpclient-osgi-version>4.5.6</httpclient-osgi-version>
<commons-lang3.version>3.13.0</commons-lang3.version>
<commons-lang3.version>3.14.0</commons-lang3.version>
<scribejava-apis.version>8.3.3</scribejava-apis.version>
<java.version>17</java.version>
</properties>
@@ -171,14 +171,14 @@
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.19</version>
<version>3.0.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-json-->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-json</artifactId>
<version>3.0.19</version>
<version>3.0.22</version>
</dependency>
<dependency>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<properties>
@@ -110,6 +110,11 @@
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>

View File

@@ -34,6 +34,7 @@
<%@ page import="org.alfresco.service.cmr.module.ModuleDetails" %>
<%@ page import="org.alfresco.service.cmr.module.ModuleInstallState" %>
<%@ page import="java.util.Calendar" %>
<%@ page import="org.owasp.encoder.Encode" %>
<!-- Enterprise index-jsp placeholder -->
<%
@@ -88,7 +89,7 @@ ModuleDetails shareServicesModule = moduleService.getModule("alfresco-share-serv
<p></p>
<p><a href="./s/index">Alfresco WebScripts Home</a> (admin only - INTERNAL)</p>
<p></p>
<p><a href="<%=UrlUtil.getApiExplorerUrl(sysAdminParams, request.getRequestURL().toString(), request.getRequestURI())%>">Alfresco API Explorer</a></p>
<p><a href="<%=Encode.forHtmlAttribute(UrlUtil.getApiExplorerUrl(sysAdminParams, request.getRequestURL().toString(), request.getRequestURI()))%>">Alfresco API Explorer</a></p>
<%
if (descriptorService.getLicenseDescriptor() == null && transactionService.isReadOnly())
{

93
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -51,54 +51,54 @@
<dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.1.3-A3</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.3-A2</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>5.1.3</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.3</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.0</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.27</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.20.1</dependency.aspectj.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
<dependency.spring.version>6.0.19</dependency.spring.version>
<dependency.spring-security.version>6.3.0</dependency.spring-security.version>
<dependency.spring-security.version>6.3.1</dependency.spring-security.version>
<dependency.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.15.2</dependency.jackson.version>
<dependency.cxf.version>4.0.2</dependency.cxf.version>
<dependency.cxf.version>4.0.5</dependency.cxf.version>
<dependency.opencmis.version>1.0.0-jakarta-1</dependency.opencmis.version>
<dependency.webscripts.version>9.0</dependency.webscripts.version>
<dependency.bouncycastle.version>1.78.1</dependency.bouncycastle.version>
<dependency.mockito-core.version>5.4.0</dependency.mockito-core.version>
<dependency.assertj.version>3.24.2</dependency.assertj.version>
<dependency.mockito-core.version>5.12.0</dependency.mockito-core.version>
<dependency.assertj.version>3.26.3</dependency.assertj.version>
<dependency.org-json.version>20231013</dependency.org-json.version>
<dependency.commons-dbcp.version>2.9.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.14.0</dependency.commons-io.version>
<dependency.gson.version>2.10.1</dependency.gson.version>
<dependency.guava.version>32.1.2-jre</dependency.guava.version>
<dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.16.1</dependency.commons-io.version>
<dependency.gson.version>2.11.0</dependency.gson.version>
<dependency.guava.version>33.2.1-jre</dependency.guava.version>
<dependency.httpclient.version>4.5.14</dependency.httpclient.version>
<dependency.httpcore.version>4.4.16</dependency.httpcore.version>
<dependency.httpcomponents-httpclient5.version>5.2.1</dependency.httpcomponents-httpclient5.version>
<dependency.httpcomponents-httpcore5.version>5.2.3</dependency.httpcomponents-httpcore5.version>
<dependency.httpcomponents-httpcore5.version>5.2.5</dependency.httpcomponents-httpcore5.version>
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>2.0.9</dependency.slf4j.version>
<dependency.log4j.version>2.20.0</dependency.log4j.version>
<dependency.groovy.version>3.0.19</dependency.groovy.version>
<dependency.slf4j.version>2.0.13</dependency.slf4j.version>
<dependency.log4j.version>2.23.1</dependency.log4j.version>
<dependency.groovy.version>3.0.22</dependency.groovy.version>
<dependency.tika.version>2.9.2</dependency.tika.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>5.2.5</dependency.poi.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
<dependency.camel.version>4.0.5</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
<dependency.camel.version>4.6.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
<dependency.netty.version>4.1.110.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
<dependency.activemq.version>5.18.3</dependency.activemq.version>
<dependency.apache-compress.version>1.26.0</dependency.apache-compress.version>
<dependency.awaitility.version>4.2.0</dependency.awaitility.version>
<dependency.apache-compress.version>1.26.2</dependency.apache-compress.version>
<dependency.awaitility.version>4.2.1</dependency.awaitility.version>
<dependency.swagger-ui.version>4.1.3</dependency.swagger-ui.version>
<dependency.swagger-parser.version>1.0.67</dependency.swagger-parser.version>
<dependency.swagger-parser.version>1.0.71</dependency.swagger-parser.version>
<dependency.maven-filtering.version>3.1.1</dependency.maven-filtering.version>
<dependency.maven-artifact.version>3.8.6</dependency.maven-artifact.version>
<dependency.jdom2.version>2.0.6.1</dependency.jdom2.version>
<dependency.pooled-jms.version>3.1.6</dependency.pooled-jms.version>
<dependency.jakarta-ee-jaxb-api.version>4.0.0</dependency.jakarta-ee-jaxb-api.version>
<dependency.jakarta-ee-jaxb-impl.version>4.0.3</dependency.jakarta-ee-jaxb-impl.version>
<dependency.jakarta-ee-jaxb-api.version>4.0.2</dependency.jakarta-ee-jaxb-api.version>
<dependency.jakarta-ee-jaxb-impl.version>4.0.5</dependency.jakarta-ee-jaxb-impl.version>
<dependency.jakarta-ws-api.version>3.0.1</dependency.jakarta-ws-api.version>
<dependency.jakarta-soap-api.version>2.0.1</dependency.jakarta-soap-api.version>
<dependency.jakarta-annotation-api.version>2.1.1</dependency.jakarta-annotation-api.version>
@@ -106,12 +106,12 @@
<dependency.jakarta-jws-api.version>3.0.0</dependency.jakarta-jws-api.version>
<dependency.jakarta-ee-mail.version>2.0.1</dependency.jakarta-ee-mail.version>
<dependency.jakarta-ee-activation.version>2.0.1</dependency.jakarta-ee-activation.version>
<dependency.jakarta-ee-jms.version>3.0.0</dependency.jakarta-ee-jms.version>
<dependency.jakarta-ee-jms.version>3.1.0</dependency.jakarta-ee-jms.version>
<dependency.java-ee-activation.version>1.2.0</dependency.java-ee-activation.version>
<dependency.jakarta-ee-json-api.version>2.1.2</dependency.jakarta-ee-json-api.version>
<dependency.jakarta-ee-json-impl.version>1.1.4</dependency.jakarta-ee-json-impl.version>
<dependency.jakarta-ee-json-api.version>2.1.3</dependency.jakarta-ee-json-api.version>
<dependency.jakarta-ee-json-impl.version>1.1.6</dependency.jakarta-ee-json-impl.version>
<dependency.jakarta-json-path.version>2.9.0</dependency.jakarta-json-path.version>
<dependency.json-smart.version>2.5.0</dependency.json-smart.version>
<dependency.json-smart.version>2.5.1</dependency.json-smart.version>
<alfresco.googledrive.version>4.1.0</alfresco.googledrive.version>
<alfresco.aos-module.version>3.1.0-A1</alfresco.aos-module.version>
<alfresco.api-explorer.version>23.2.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
@@ -124,7 +124,7 @@
<dependency.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>5.0.1</dependency.tas-utility.version>
<dependency.rest-assured.version>5.3.2</dependency.rest-assured.version>
<dependency.rest-assured.version>5.5.0</dependency.rest-assured.version>
<dependency.tas-email.version>2.0.0</dependency.tas-email.version>
<dependency.tas-webdav.version>1.21</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.19</dependency.tas-ftp.version>
@@ -151,7 +151,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>23.3.0.56</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -401,7 +401,7 @@
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
@@ -442,7 +442,7 @@
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
<version>3.11.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@@ -462,7 +462,7 @@
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.2.0</version>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
@@ -621,7 +621,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.alfresco.aos-module</groupId>
@@ -700,13 +700,13 @@
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.0.86</version>
<version>1.5.0</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.16.1</version>
<version>1.18.1</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
@@ -851,6 +851,17 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${dependency.commons-dbcp.version}</version>
<exclusions>
<!-- Exclude jakarta.transaction-api so that other repositories importing
the alfresco-repository as a dependency, not having community-repo as
a parent, and therefore not sharing the dependencyManagement with it,
won't inherit the outdated jakarta.transaction-api version coming from
this library -->
<exclusion>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
@@ -936,7 +947,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -975,7 +986,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.13.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
@@ -1005,7 +1016,7 @@
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.2</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
@@ -1014,7 +1025,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<version>3.7.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -1024,11 +1035,11 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<version>3.7.1</version>
</plugin>
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
@@ -1074,7 +1085,7 @@
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>1.10.9</version>
<version>1.10.14</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<dependencies>
@@ -137,7 +137,7 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>11.0.16</version>
<version>11.0.22</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -909,16 +909,14 @@ public class AuditImpl implements Audit
public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker)
{
final String applicationName = auditApplication.getKey().substring(1);
AuditQueryParameters parameters = new AuditQueryParameters();
parameters.setApplicationName(applicationName);
parameters.setApplicationName(auditApplication.getName());
parameters.setFromTime(propertyWalker.getFromTime());
parameters.setToTime(propertyWalker.getToTime());
parameters.setFromId(propertyWalker.getFromId());
parameters.setToId(propertyWalker.getToId());
parameters.setUser(propertyWalker.getCreatedByUser());
return auditService.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
return auditService.getAuditEntriesCountByAppAndProperties(parameters);
}
}

View File

@@ -125,7 +125,7 @@ public class PeopleImpl implements People
protected ResetPasswordService resetPasswordService;
protected UserRegistrySynchronizer userRegistrySynchronizer;
protected Renditions renditions;
private Boolean allowImmutableEnabledUpdate;
private final static Map<String, QName> sort_params_to_qnames;
static
@@ -202,6 +202,11 @@ public class PeopleImpl implements People
this.userRegistrySynchronizer = userRegistrySynchronizer;
}
public void setAllowImmutableEnabledUpdate(Boolean allowImmutableEnabledUpdate)
{
this.allowImmutableEnabledUpdate = allowImmutableEnabledUpdate;
}
/**
* Validate, perform -me- substitution and canonicalize the person ID.
*
@@ -708,16 +713,26 @@ public class PeopleImpl implements People
// if requested, update password
updatePassword(isAdmin, personIdToUpdate, person);
if (person.isEnabled() != null)
Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
Boolean isEnabled = person.isEnabled();
if (isEnabled != null)
{
if (isAdminAuthority(personIdToUpdate))
{
throw new PermissionDeniedException("Admin authority cannot be disabled.");
}
// note: if current user is not an admin then permission denied exception is thrown
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
if (allowImmutableEnabledStatusUpdate(personIdToUpdate, isAdmin, immutableProperties))
{
LOGGER.info("User " + personIdToUpdate + " is immutable but enabled status will be set to: " + isEnabled);
}
else
{
// note: if current user is not an admin then permission denied exception is thrown
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
}
}
NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
@@ -742,9 +757,7 @@ public class PeopleImpl implements People
properties.putAll(nodes.mapToNodeProperties(customProps));
}
// MNT-21150 LDAP synced attributes can be changed using REST API
Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
// MNT-21150 LDAP synced attributes can't be changed using REST API
immutableProperties.forEach(immutableProperty -> {
if (properties.containsKey(immutableProperty))
{
@@ -768,6 +781,28 @@ public class PeopleImpl implements People
return getPerson(personId);
}
private boolean allowImmutableEnabledStatusUpdate(String userId, boolean isAdmin, Set<QName> immutableProperties)
{
if (allowImmutableEnabledUpdate)
{
boolean containLdapUserAccountStatus = false;
QName propertyNameToCheck = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "userAccountStatusProperty");
for (QName immutableProperty : immutableProperties)
{
if (immutableProperty.equals(propertyNameToCheck))
{
containLdapUserAccountStatus = true;
break;
}
}
return isAdmin && !containLdapUserAccountStatus && !isMutableAuthority(userId);
}
return false;
}
private boolean checkCurrentUserOrAdmin(String personId)
{
boolean isAdmin = isAdminAuthority();

View File

@@ -0,0 +1,40 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.framework.core.exceptions;
/**
* Unprocessable Content
*/
public class UnprocessableContentException extends ApiException
{
private static final long serialVersionUID = -6857652090677361159L;
public UnprocessableContentException(String msgId)
{
super(msgId);
}
}

View File

@@ -178,6 +178,7 @@
<entry key="org.alfresco.rest.framework.core.exceptions.ArchivedContentException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_PRECONDITION_FAILED}" />
<entry key="org.alfresco.rest.framework.core.exceptions.RestoreInProgressException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_CONFLICT}" />
<entry key="org.alfresco.rest.framework.core.exceptions.InvalidNodeTypeException" value="#{T(org.apache.http.HttpStatus).SC_UNPROCESSABLE_ENTITY}" />
<entry key="org.alfresco.rest.framework.core.exceptions.UnprocessableContentException" value="#{T(org.apache.http.HttpStatus).SC_UNPROCESSABLE_ENTITY}" />
</map>
</property>
</bean>
@@ -763,6 +764,7 @@
<property name="thumbnailService" ref="ThumbnailService" />
<property name="resetPasswordService" ref="resetPasswordService" />
<property name="userRegistrySynchronizer" ref="userRegistrySynchronizer" />
<property name="allowImmutableEnabledUpdate" value="${allow.immutable.user.enabled.status.update}" />
</bean>
<bean id="People" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.56</version>
<version>23.3.0.87-SNAPSHOT</version>
</parent>
<dependencies>
@@ -94,7 +94,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -120,7 +120,7 @@
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.7</version>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
@@ -133,7 +133,7 @@
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>73.2</version>
<version>75.1</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
@@ -273,7 +273,7 @@
<dependency>
<groupId>com.sun.xml.fastinfoset</groupId>
<artifactId>FastInfoset</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.htmlparser</groupId>
@@ -402,7 +402,7 @@
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.2</version>
<version>3.0.3</version>
</dependency>
<!-- Activiti -->
@@ -839,7 +839,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<version>1.15.0</version>
<executions>
<execution>
<!-- phase>process-sources</phase -->

View File

@@ -41,6 +41,8 @@ public class IdsEntity
private Long idFour;
private List<Long> ids;
private boolean ordered;
private Integer maxResults;
public Long getIdOne()
{
return idOne;
@@ -89,4 +91,12 @@ public class IdsEntity
{
this.ordered = ordered;
}
public int getMaxResults()
{
return maxResults;
}
public void setMaxResults(Integer maxResults)
{
this.maxResults = maxResults;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -276,11 +276,10 @@ public interface AuditComponent
/**
* Issue an audit query to retrieve count of records for a given application and properties
*
* @param applicationName the name of the application
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
* @return a map containing min/max and the associated value
*/
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{
return -1;
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -956,10 +956,8 @@ public class AuditComponentImpl implements AuditComponent
return auditDAO.getAuditEntriesCountByApp(applicationId);
}
@Override public int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
@Override public int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{
org.alfresco.repo.domain.audit.AuditQueryParameters dbParameters = new org.alfresco.repo.domain.audit.AuditQueryParameters();
return auditDAO.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
return auditDAO.getAuditEntriesCountByAppAndProperties(parameters);
}
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -190,8 +190,8 @@ public class AuditServiceImpl implements AuditService
/**
* {@inheritDoc}
*/
@Override public int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
@Override public int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{
return auditComponent.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
return auditComponent.getAuditEntriesCountByAppAndProperties(parameters);
}
}

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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%
*/
/*
* #%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.repo.domain;
@@ -102,21 +102,22 @@ public class CrcHelper
{
throw new RuntimeException("UTF-8 encoding is not supported");
}
// Get the short value (case-sensitive or not)
// Crc Value will change based on the case-sensitive, So we need to get the short value based on case-sensitive
String valueShort = null;
int valueLen = valueLowerCase.length();
String currentValue = caseSensitive ? value : valueLowerCase;
int valueLen = currentValue.length();
if (valueLen < dataLength)
{
valueShort = valueLowerCase;
valueShort = currentValue;
}
else if (useCharsFromStart)
{
valueShort = valueLowerCase.substring(0, dataLength - 1);
valueShort = currentValue.substring(0, dataLength - 1);
}
else
{
valueShort = valueLowerCase.substring(valueLen - dataLength);
valueShort = currentValue.substring(valueLen - dataLength);
}
return new Pair<String, Long>(valueShort, valueCrc);
}
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -248,11 +248,10 @@ public interface AuditDAO
/**
* Issue an audit query to retrieve count of records for a given application and properties
*
* @param applicationName name of the application to be queried
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
* @return a map containing min/max and the associated value
*/
default int getAuditEntriesCountByAppAndProperties(String applicationName, org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
default int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
{
return -1;
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -237,7 +237,7 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
}
@Override
public int getAuditEntriesCountByAppAndProperties(String applicationName, org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
public int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
{
AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters);

View File

@@ -2785,6 +2785,23 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
selectNodesWithAspects(qnameIds, minNodeId, maxNodeId, ordered, resultsCallback);
}
@Override
public void getNodesWithAspects(
Set<QName> aspectQNames,
Long minNodeId, Long maxNodeId, boolean ordered,
int maxResults,
NodeRefQueryCallback resultsCallback)
{
Set<Long> qnameIdsSet = qnameDAO.convertQNamesToIds(aspectQNames, false);
if (qnameIdsSet.isEmpty())
{
// No point running a query
return;
}
List<Long> qnameIds = new ArrayList<>(qnameIdsSet);
selectNodesWithAspects(qnameIds, minNodeId, maxNodeId, ordered, maxResults, resultsCallback);
}
/**
* @return Returns a writable copy of the cached aspects set
*/
@@ -4960,6 +4977,10 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
List<Long> qnameIds,
Long minNodeId, Long maxNodeId, boolean ordered,
NodeRefQueryCallback resultsCallback);
protected abstract void selectNodesWithAspects(
List<Long> qnameIds,
Long minNodeId, Long maxNodeId, boolean ordered, int maxResults,
NodeRefQueryCallback resultsCallback);
protected abstract Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex);
protected abstract int updateNodeAssoc(Long id, int assocIndex);
protected abstract int deleteNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId);
@@ -5088,4 +5109,5 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
protected abstract Long selectMinTxInNodeIdRange(Long fromNodeId, Long toNodeId);
protected abstract Long selectMaxTxInNodeIdRange(Long fromNodeId, Long toNodeId);
protected abstract Long selectNextTxCommitTime(Long fromCommitTime);
}

View File

@@ -427,6 +427,22 @@ public interface NodeDAO extends NodeBulkLoader
Long minNodeId, Long maxNodeId, boolean ordered,
NodeRefQueryCallback resultsCallback);
/**
* Get nodes with aspects between the given ranges, ordering the results optionally
* and limit the result set
*
* @param aspectQNames the aspects that must be on the nodes
* @param minNodeId the minimum node ID (inclusive)
* @param maxNodeId the maximum node ID (exclusive)
* @param ordered if the results are to be ordered by nodeID
* @param maxResults limit query to maxResults
* @param resultsCallback callback to process results
*/
public void getNodesWithAspects(
Set<QName> aspectQNames,
Long minNodeId, Long maxNodeId, boolean ordered, int maxResults,
NodeRefQueryCallback resultsCallback);
/*
* Node Assocs
*/

View File

@@ -116,6 +116,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType";
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
private static final String SELECT_NODES_WITH_ASPECT_IDS_LIMITED = "alfresco.node.select_NodesWithAspectIds_Limited";
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
private static final String DELETE_NODE_ASSOC = "alfresco.node.delete_NodeAssoc";
@@ -799,6 +800,33 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
template.select(SELECT_NODES_WITH_ASPECT_IDS, parameters, resultHandler);
}
@Override
protected void selectNodesWithAspects(
List<Long> qnameIds,
Long minNodeId, Long maxNodeId, boolean ordered,
final int maxResults,
final NodeRefQueryCallback resultsCallback)
{
@SuppressWarnings("rawtypes")
ResultHandler resultHandler = new ResultHandler()
{
public void handleResult(ResultContext context)
{
NodeEntity entity = (NodeEntity) context.getResultObject();
Pair<Long, NodeRef> nodePair = new Pair<>(entity.getId(), entity.getNodeRef());
resultsCallback.handle(nodePair);
}
};
IdsEntity parameters = new IdsEntity();
parameters.setIdOne(minNodeId);
parameters.setIdTwo(maxNodeId);
parameters.setIds(qnameIds);
parameters.setOrdered(ordered);
parameters.setMaxResults(maxResults);
template.select(SELECT_NODES_WITH_ASPECT_IDS_LIMITED, parameters, resultHandler);
}
@Override
protected Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex)
{

View File

@@ -85,8 +85,11 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
public static final String FIXED_ACL_ASYNC_REQUIRED_KEY = "FIXED_ACL_ASYNC_REQUIRED";
public static final String FIXED_ACL_ASYNC_CALL_KEY = "FIXED_ACL_ASYNC_CALL";
protected static final QName LOCK_Q_NAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "FixedAclUpdater");
private static final int DEFAULT_MAX_ITEMS = Integer.MAX_VALUE;
/** A set of listeners to receive callback events whenever permissions are updated by this class. */
private static Set<FixedAclUpdaterListener> listeners = Sets.newConcurrentHashSet();
@@ -101,6 +104,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
private int maxItemBatchSize = 100;
private int numThreads = 4;
private boolean forceSharedACL = false;
private int maxItems = DEFAULT_MAX_ITEMS;
private boolean orderNodes = true;
private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
private PolicyComponent policyComponent;
@@ -147,12 +152,22 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
this.forceSharedACL = forceSharedACL;
}
public void setOrderNodes(boolean orderNodes)
{
this.orderNodes = orderNodes;
}
public void setLockTimeToLive(long lockTimeToLive)
{
this.lockTimeToLive = lockTimeToLive;
this.lockRefreshTime = lockTimeToLive / 2;
}
public void setMaxItems(int maxItems)
{
this.maxItems = maxItems > 0 ? maxItems : DEFAULT_MAX_ITEMS;
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
@@ -209,7 +224,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
public List<NodeRef> execute() throws Throwable
{
getNodesCallback.init();
nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, true, getNodesCallback);
nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, orderNodes, maxItemBatchSize, getNodesCallback);
getNodesCallback.done();
return getNodesCallback.getNodes();
@@ -220,6 +235,11 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
int countNodesWithAspects()
{
if (maxItems < DEFAULT_MAX_ITEMS) {
log.info("Job limited to process a maximum of " + maxItems + " Pending Acls");
return maxItems;
}
final CountNodesWithAspectCallback countNodesCallback = new CountNodesWithAspectCallback();
int count = transactionService.getRetryingTransactionHelper()
.doInTransaction(new RetryingTransactionCallback<Integer>()
@@ -238,6 +258,9 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
private class AclWorkProvider implements BatchProcessWorkProvider<NodeRef>
{
private GetNodesWithAspects getNodesWithAspects;
private long estimatedUpdatedItems;
private long execTime;
private long execBatches;
AclWorkProvider()
{
@@ -259,8 +282,37 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
@Override
public Collection<NodeRef> getNextWork()
{
return getNodesWithAspects.getNodesWithAspects();
if(estimatedUpdatedItems >= maxItems)
{
log.info("Reached max items to process. Nodes Processed: " + estimatedUpdatedItems + "/" + maxItems);
return Collections.emptyList();
}
long initTime = System.currentTimeMillis();
Collection<NodeRef> batchNodes = getNodesWithAspects.getNodesWithAspects();
long endTime = System.currentTimeMillis();
if (log.isDebugEnabled())
{
log.debug("Query for batch executed in " + (endTime-initTime) + " ms");
}
if (!batchNodes.isEmpty())
{
// Increment estimatedUpdatedItems with the expected number of nodes to process
estimatedUpdatedItems += batchNodes.size();
execTime+=endTime-initTime;
execBatches++;
}
return batchNodes;
}
public double getAverageQueryExecutionTime()
{
return execBatches > 0 ? execTime/execBatches : 0;
}
}
protected class AclWorker implements BatchProcessor.BatchProcessWorker<NodeRef>
@@ -451,6 +503,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
try
{
log.info("Running FixedAclUpdater. Max Items: " + maxItems + ", Impose order: " + orderNodes);
lockToken = jobLockService.getLock(LOCK_Q_NAME, lockTimeToLive, 0, 1);
jobLockService.refreshLock(lockToken, LOCK_Q_NAME, lockRefreshTime, jobLockRefreshCallback);
@@ -460,6 +513,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
transactionService.getRetryingTransactionHelper(), provider, numThreads, maxItemBatchSize, applicationContext,
log, 100);
int count = bp.process(worker, true);
log.info("FixedAclUpdater updated " + count + ". Average query time " + provider.getAverageQueryExecutionTime() + " ms");
return count;
}
catch (LockAcquisitionException e)

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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%
*/
/*
* #%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.repo.domain.propval;
import org.alfresco.repo.domain.CrcHelper;
@@ -44,6 +44,7 @@ public class PropertyStringValueEntity
private String stringValue;
private String stringEndLower;
private Long stringCrc;
private String stringLower;
public PropertyStringValueEntity()
{
@@ -115,6 +116,9 @@ public class PropertyStringValueEntity
Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true);
stringEndLower = crcPair.getFirst();
stringCrc = crcPair.getSecond();
// Calculate the crc value with case-insensitive
Pair<String, Long> crcPairWithCaseInSensitive = CrcHelper.getStringCrcPair(value, 16, false, false);
stringLower = crcPairWithCaseInSensitive.getFirst();
}
public Long getId()
@@ -156,4 +160,14 @@ public class PropertyStringValueEntity
{
this.stringCrc = stringCrc;
}
public String getStringLower()
{
return stringLower;
}
public void setStringLower(String stringLower)
{
this.stringLower = stringLower;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -36,18 +36,13 @@ import org.springframework.beans.factory.InitializingBean;
/**
* Sends a message to a destination in the current thread.
*/
public class DirectEventSender implements EventSender, InitializingBean
public class DirectEventSender implements EventSender
{
protected Event2MessageProducer event2MessageProducer;
protected final Event2MessageProducer event2MessageProducer;
@Override
public void afterPropertiesSet()
public DirectEventSender(Event2MessageProducer event2MessageProducer)
{
PropertyCheck.mandatory(this, "event2MessageProducer", event2MessageProducer);
}
public void setEvent2MessageProducer(Event2MessageProducer event2MessageProducer)
{
this.event2MessageProducer = event2MessageProducer;
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -46,28 +46,18 @@ public class EnqueuingEventSender extends DirectEventSender
{
protected static final Log LOGGER = LogFactory.getLog(EnqueuingEventSender.class);
protected Executor enqueueThreadPoolExecutor;
protected Executor dequeueThreadPoolExecutor;
protected final Executor enqueueThreadPoolExecutor;
protected final Executor dequeueThreadPoolExecutor;
protected BlockingQueue<EventInMaking> queue = new LinkedBlockingQueue<>();
protected Runnable listener = createListener();
@Override
public void afterPropertiesSet()
public EnqueuingEventSender(Event2MessageProducer event2MessageProducer, Executor enqueueThreadPoolExecutor, Executor dequeueThreadPoolExecutor)
{
super.afterPropertiesSet();
super(event2MessageProducer);
PropertyCheck.mandatory(this, "enqueueThreadPoolExecutor", enqueueThreadPoolExecutor);
PropertyCheck.mandatory(this, "dequeueThreadPoolExecutor", dequeueThreadPoolExecutor);
}
public void setEnqueueThreadPoolExecutor(Executor enqueueThreadPoolExecutor)
{
this.enqueueThreadPoolExecutor = enqueueThreadPoolExecutor;
}
public void setDequeueThreadPoolExecutor(Executor dequeueThreadPoolExecutor)
{
this.dequeueThreadPoolExecutor = dequeueThreadPoolExecutor;
dequeueThreadPoolExecutor.execute(listener);
}
/**
@@ -91,6 +81,12 @@ public class EnqueuingEventSender extends DirectEventSender
});
}
@Override
public void initialize()
{
dequeueThreadPoolExecutor.execute(listener);
}
/**
* Create listener task in charge of dequeuing and sending events ready to be sent.
* @return The task in charge of dequeuing and sending events ready to be sent.

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -40,4 +40,13 @@ public interface EventSender
* @param eventProducer - callback function that creates an event
*/
void accept(Callable<Optional<RepoEvent<?>>> eventProducer);
/**
* It's called right after event sender instantiation (see {@link org.alfresco.repo.event2.EventSenderFactoryBean}).
* It might be used to initialize the sender implementation.
*/
default void initialize()
{
//no initialization by default
}
}

View File

@@ -0,0 +1,158 @@
/*
* #%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.repo.event2;
import jakarta.annotation.Nonnull;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.env.PropertyResolver;
import java.util.Optional;
import java.util.concurrent.Executor;
public class EventSenderFactoryBean extends AbstractFactoryBean<EventSender>
{
static final String LEGACY_SKIP_QUEUE_PROPERTY = "repo.event2.queue.skip";
static final String EVENT_SEND_STRATEGY_PROPERTY = "repo.event2.send.strategy";
private static final String DIRECT_EVENT_SENDER_NAME = "direct";
private static final String ASYNC_EVENT_SENDER_NAME = "async";
private final PropertyResolver propertyResolver;
private final Event2MessageProducer event2MessageProducer;
private final Executor enqueueThreadPoolExecutor;
private final Executor dequeueThreadPoolExecutor;
private String configuredSenderName;
private boolean legacySkipQueueConfig;
public EventSenderFactoryBean(@Autowired PropertyResolver propertyResolver, Event2MessageProducer event2MessageProducer,
Executor enqueueThreadPoolExecutor, Executor dequeueThreadPoolExecutor)
{
super();
PropertyCheck.mandatory(this, "propertyResolver", propertyResolver);
PropertyCheck.mandatory(this, "event2MessageProducer", event2MessageProducer);
PropertyCheck.mandatory(this, "enqueueThreadPoolExecutor", enqueueThreadPoolExecutor);
PropertyCheck.mandatory(this, "dequeueThreadPoolExecutor", dequeueThreadPoolExecutor);
this.propertyResolver = propertyResolver;
this.event2MessageProducer = event2MessageProducer;
this.enqueueThreadPoolExecutor = enqueueThreadPoolExecutor;
this.dequeueThreadPoolExecutor = dequeueThreadPoolExecutor;
}
@Value("${" + LEGACY_SKIP_QUEUE_PROPERTY + "}")
public void setLegacySkipQueueConfig(boolean legacySkipQueueConfig)
{
this.legacySkipQueueConfig = legacySkipQueueConfig;
}
@Value("${" + EVENT_SEND_STRATEGY_PROPERTY + "}")
public void setConfiguredSenderName(String configuredSenderName)
{
this.configuredSenderName = configuredSenderName;
}
@Override
public Class<?> getObjectType()
{
return EventSender.class;
}
@Override
@Nonnull
protected EventSender createInstance() throws Exception
{
EventSender sender = instantiateConfiguredSender();
sender.initialize();
return sender;
}
private EventSender instantiateConfiguredSender()
{
if (isSenderNameConfigured())
{
return instantiateSender(getConfiguredSenderName());
}
return isLegacySkipQueueConfigured() ? instantiateDirectSender() : instantiateAsyncSender();
}
protected EventSender instantiateSender(String senderName)
{
if (DIRECT_EVENT_SENDER_NAME.equalsIgnoreCase(senderName))
{
return instantiateDirectSender();
}
if (ASYNC_EVENT_SENDER_NAME.equalsIgnoreCase(senderName))
{
return instantiateAsyncSender();
}
throw new IllegalStateException("Failed to instantiate sender: " + senderName);
}
private DirectEventSender instantiateDirectSender()
{
return new DirectEventSender(getEvent2MessageProducer());
}
private EnqueuingEventSender instantiateAsyncSender()
{
return new EnqueuingEventSender(getEvent2MessageProducer(), enqueueThreadPoolExecutor, dequeueThreadPoolExecutor);
}
private boolean isSenderNameConfigured()
{
return !Optional.ofNullable(getConfiguredSenderName())
.map(String::isBlank)
.orElse(true);
}
private boolean isLegacySkipQueueConfigured()
{
return Optional.ofNullable(resolveProperty(LEGACY_SKIP_QUEUE_PROPERTY, Boolean.class))
.orElse(legacySkipQueueConfig);
}
private String getConfiguredSenderName()
{
return Optional.ofNullable(resolveProperty(EVENT_SEND_STRATEGY_PROPERTY, String.class))
.orElse(configuredSenderName);
}
protected <T> T resolveProperty(String key, Class<T> targetType)
{
return propertyResolver.getProperty(key, targetType);
}
protected Event2MessageProducer getEvent2MessageProducer()
{
return event2MessageProducer;
}
}

View File

@@ -36,7 +36,10 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.UUIDUtil;
import org.alfresco.sync.events.types.ActivityEvent;
import org.alfresco.sync.events.types.Event;
import org.alfresco.model.ContentModel;
@@ -108,8 +111,6 @@ import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.PeriodType;
import org.safehaus.uuid.UUID;
import org.safehaus.uuid.UUIDGenerator;
/**
* QuickShare Service implementation.
@@ -435,8 +436,8 @@ public class QuickShareServiceImpl implements QuickShareService,
// If it is retura dto built from the existing properties.
if (! nodeService.getAspects(nodeRef).contains(QuickShareModel.ASPECT_QSHARE))
{
UUID uuid = UUIDGenerator.getInstance().generateRandomBasedUUID();
sharedId = Base64.encodeBase64URLSafeString(uuid.toByteArray()); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw)
UUID uuid = Generators.randomBasedGenerator().generate();
sharedId = Base64.encodeBase64URLSafeString(UUIDUtil.asByteArray(uuid)); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw)
final Map<QName, Serializable> props = new HashMap<QName, Serializable>(2);
props.put(QuickShareModel.PROP_QSHARE_SHAREDID, sharedId);
@@ -1246,7 +1247,7 @@ public class QuickShareServiceImpl implements QuickShareService,
}
// Create the expiry action
final QuickShareLinkExpiryAction expiryAction = new QuickShareLinkExpiryActionImpl(java.util.UUID.randomUUID().toString(), sharedId,
final QuickShareLinkExpiryAction expiryAction = new QuickShareLinkExpiryActionImpl(UUID.randomUUID().toString(), sharedId,
"QuickShare link expiry action");
// Create the persisted schedule
final ScheduledPersistedAction schedule = scheduledPersistedActionService.createSchedule(expiryAction);

View File

@@ -36,7 +36,11 @@ import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -49,12 +53,30 @@ public class AuthenticationContextImpl implements AuthenticationContext
private final Log logger = LogFactory.getLog(getClass());
private TenantService tenantService;
private PersonService personService;
private AuthenticationService authenticationService;
private Boolean allowImmutableEnabledUpdate;
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setAllowImmutableEnabledUpdate(Boolean allowImmutableEnabledUpdate)
{
this.allowImmutableEnabledUpdate = allowImmutableEnabledUpdate;
}
/**
* Explicitly set the given validated user details to be authenticated.
*
@@ -70,7 +92,7 @@ public class AuthenticationContextImpl implements AuthenticationContext
{
// Apply the same validation that ACEGI would have to the user details - we may be going through a 'back
// door'.
if (!ud.isEnabled())
if (isDisabled(userId, ud))
{
throw new DisabledException("User is disabled");
}
@@ -114,6 +136,43 @@ public class AuthenticationContextImpl implements AuthenticationContext
}
}
private boolean isDisabled(String userId, UserDetails ud)
{
boolean isDisabled = !ud.isEnabled();
boolean isSystemUser = isSystemUserName(userId);
if (allowImmutableEnabledUpdate && !isSystemUser)
{
try
{
boolean isImmutable = isImmutableAuthority(userId);
boolean isPersonEnabled = personService.isEnabled(userId);
isDisabled = isDisabled || (isImmutable && !isPersonEnabled);
}
catch (Exception e)
{
if (logger.isWarnEnabled())
{
logger.warn("Failed to determine if person is enabled: " + userId + ", using user details status: " + isDisabled);
}
}
}
return isDisabled;
}
private boolean isImmutableAuthority(String authorityName)
{
return AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
@Override public Boolean doWork() throws Exception
{
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
return !mutableAuthenticationService.isAuthenticationMutable(authorityName);
}
});
}
public Authentication setSystemUserAsCurrentUser()
{
return setSystemUserAsCurrentUser(TenantService.DEFAULT_DOMAIN);

View File

@@ -4,30 +4,35 @@
* %%
* 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
* 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.repo.security.authentication.identityservice;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.web.util.UriComponentsBuilder;
/**
@@ -35,6 +40,7 @@ import org.springframework.web.util.UriComponentsBuilder;
*
* @author Gavin Cornwell
*/
@SuppressWarnings("PMD.ExcessivePublicCount")
public class IdentityServiceConfig
{
private static final String REALMS = "realms";
@@ -62,6 +68,7 @@ public class IdentityServiceConfig
private String principalAttribute;
private boolean clientIdValidationDisabled;
private String adminConsoleRedirectPath;
private String signatureAlgorithms;
/**
*
@@ -306,4 +313,18 @@ public class IdentityServiceConfig
{
this.adminConsoleRedirectPath = adminConsoleRedirectPath;
}
public Set<SignatureAlgorithm> getSignatureAlgorithms()
{
return Stream.of(signatureAlgorithms.split(","))
.map(String::trim)
.map(SignatureAlgorithm::from)
.filter(Objects::nonNull)
.collect(Collectors.toUnmodifiableSet());
}
public void setSignatureAlgorithms(String signatureAlgorithms)
{
this.signatureAlgorithms = signatureAlgorithms;
}
}

View File

@@ -58,10 +58,13 @@ import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.jwk.source.DefaultJWKSetCache;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.BadJOSEException;
import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jose.proc.SecurityContext;
import com.nimbusds.jose.util.ResourceRetriever;
@@ -129,6 +132,9 @@ import org.springframework.web.util.UriComponentsBuilder;
public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentityServiceFacade>
{
private static final Log LOGGER = LogFactory.getLog(IdentityServiceFacadeFactoryBean.class);
private static final JOSEObjectType AT_JWT = new JOSEObjectType("at+jwt");
private boolean enabled;
private SpringBasedIdentityServiceFacadeFactory factory;
@@ -554,12 +560,20 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
static class JwtDecoderProvider
{
private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.RS256;
private static final SignatureAlgorithm DEFAULT_SIGNATURE_ALGORITHM = SignatureAlgorithm.RS256;
private final IdentityServiceConfig config;
private final Set<SignatureAlgorithm> signatureAlgorithms;
JwtDecoderProvider(IdentityServiceConfig config)
{
this.config = requireNonNull(config);
this.signatureAlgorithms = ofNullable(config.getSignatureAlgorithms())
.filter(not(Set::isEmpty))
.orElseGet(() -> {
LOGGER.warn("Unable to find any valid signature algorithms in the configuration. "
+ "Using the default signature algorithm: " + DEFAULT_SIGNATURE_ALGORITHM.getName() + ".");
return Set.of(DEFAULT_SIGNATURE_ALGORITHM);
});
}
public JwtDecoder createJwtDecoder(RestOperations rest, ProviderDetails providerDetails)
@@ -587,13 +601,13 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
{
final RSAPublicKey publicKey = parsePublicKey(config.getRealmKey());
return NimbusJwtDecoder.withPublicKey(publicKey)
.signatureAlgorithm(SIGNATURE_ALGORITHM)
.signatureAlgorithm(DEFAULT_SIGNATURE_ALGORITHM)
.build();
}
final String jwkSetUri = requireValidJwkSetUri(providerDetails);
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithm(SIGNATURE_ALGORITHM)
final NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder decoderBuilder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri);
signatureAlgorithms.forEach(decoderBuilder::jwsAlgorithm);
return decoderBuilder
.restOperations(rest)
.jwtProcessorCustomizer(this::reconfigureJWKSCache)
.build();
@@ -633,8 +647,11 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
resourceRetriever.get(), cache);
jwtProcessor.setJWSKeySelector(new JWSVerificationKeySelector<>(
JWSAlgorithm.parse(SIGNATURE_ALGORITHM.getName()),
signatureAlgorithms.stream()
.map(signatureAlgorithm -> JWSAlgorithm.parse(signatureAlgorithm.getName()))
.collect(Collectors.toSet()),
cachingJWKSource));
jwtProcessor.setJWSTypeVerifier(new CustomJOSEObjectTypeVerifier(JOSEObjectType.JWT, AT_JWT));
}
private OAuth2TokenValidator<Jwt> createJwtTokenValidator(ProviderDetails providerDetails)
@@ -759,7 +776,6 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
}
}
static class CustomClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory
{
CustomClientHttpRequestFactory(HttpClient httpClient)
@@ -781,9 +797,22 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
}
}
static class CustomJOSEObjectTypeVerifier extends DefaultJOSEObjectTypeVerifier<SecurityContext>
{
public CustomJOSEObjectTypeVerifier(JOSEObjectType... allowedTypes)
{
super(Set.of(allowedTypes));
}
@Override
public void verify(JOSEObjectType type, SecurityContext context) throws BadJOSEException
{
super.verify(type, context);
}
}
private static boolean isDefined(String value)
{
return value != null && !value.isBlank();
}
}

View File

@@ -1,32 +1,33 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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%
*/
/*
* #%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.repo.security.person;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.batch.BatchProcessor;
@@ -41,7 +42,6 @@ import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.safehaus.uuid.UUID;
import org.springframework.context.ApplicationEvent;
/**
@@ -168,7 +168,7 @@ public class SplitPersonCleanupBootstrapBean extends AbstractLifecycleBean
try
{
@SuppressWarnings("unused")
UUID id = new UUID(guidString);
UUID id = UUID.fromString(guidString);
// We have a valid guid.
return true;
}
@@ -188,7 +188,7 @@ public class SplitPersonCleanupBootstrapBean extends AbstractLifecycleBean
try
{
@SuppressWarnings("unused")
UUID id = new UUID(guidString);
UUID id = UUID.fromString(guidString);
// We have a valid guid.
return true;
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* 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
@@ -256,11 +256,10 @@ public interface AuditService
/**
* Issue an audit query to retrieve min / max audit record id for a given application and properties
*
* @param applicationName the name of the application
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
* @return a map containing min/max and the associated value
*/
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{
return -1;
}

View File

@@ -274,6 +274,15 @@
<property name="tenantService">
<ref bean="tenantService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="authenticationService">
<ref bean="AuthenticationService" />
</property>
<property name="allowImmutableEnabledUpdate">
<value>${allow.immutable.user.enabled.status.update}</value>
</property>
</bean>
<!-- Simple Authentication component that rejects all authentication requests -->

View File

@@ -4,6 +4,8 @@
view:childName="app:messages">
<view:aspects>
<app:uifacets></app:uifacets>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<view:properties>
<cm:description>${spaces.messages.description}</cm:description>

View File

@@ -4,6 +4,8 @@
view:childName="app:webclient_extension">
<view:aspects>
<app:uifacets></app:uifacets>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<view:properties>
<cm:description>${spaces.web.client.extension.description}</cm:description>

View File

@@ -12,6 +12,10 @@
<cm:title>${spaces.rendition.rendering_actions.name}</cm:title>
<cm:description>${spaces.rendition.rendering_actions.description}</cm:description>
</view:properties>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
</view:view>

View File

@@ -12,6 +12,10 @@
<cm:title>${spaces.replication.replication_actions.name}</cm:title>
<cm:description>${spaces.replication.replication_actions.description}</cm:description>
</view:properties>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
</view:view>

View File

@@ -11,5 +11,9 @@
<cm:title>${spaces.actions.scheduled_actions.name}</cm:title>
<cm:description>${spaces.actions.scheduled_actions.description}</cm:description>
</view:properties>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
</view:view>

View File

@@ -14,5 +14,9 @@
<cm:description>${spaces.solr_facets.root.description}
</cm:description>
</view:properties>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</srft:facets>
</view:view>

View File

@@ -1,7 +1,7 @@
<view:view xmlns:view="http://www.alfresco.org/view/repository/1.0"
xmlns:cm="http://www.alfresco.org/model/content/1.0"
xmlns:app="http://www.alfresco.org/model/application/1.0"
xmlns:emailserver="http://www.alfresco.org/model/emailserver/1.0">
xmlns:emailserver="http://www.alfresco.org/model/emailserver/1.0" xmlns:sys="http://www.alfresco.org/model/system/1.0">
<!-- NOTE: all replaced properties referenced from repository.properties file must also be
mapped in the import-export-context.xml spacesStoreImporter/configuration section -->
@@ -30,6 +30,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.dictionary.name}</cm:title>
<cm:description>${spaces.dictionary.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<cm:contains>
<cm:folder view:childName="${spaces.templates.childname}">
<app:uifacets/>
@@ -37,6 +41,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.templates.name}</cm:title>
<cm:description>${spaces.templates.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder
view:childName="${spaces.templates.content.childname}">
@@ -45,6 +53,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.templates.content.name}</cm:title>
<cm:description>${spaces.templates.content.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder
view:childName="${spaces.templates.email.childname}">
@@ -53,6 +65,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.templates.email.name}</cm:title>
<cm:description>${spaces.templates.email.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<cm:contains>
<cm:folder
view:childName="${spaces.templates.email.invite.childname}">
@@ -79,6 +95,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.templates.rss.name}</cm:title>
<cm:description>${spaces.templates.rss.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder
view:childName="${spaces.savedsearches.childname}">
@@ -93,6 +113,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.savedsearches.name}</cm:title>
<cm:description>${spaces.savedsearches.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder view:childName="${spaces.scripts.childname}">
<app:uifacets/>
@@ -100,6 +124,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.scripts.name}</cm:title>
<cm:description>${spaces.scripts.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder view:childName="${spaces.nodetemplates.childname}">
<app:uifacets/>
@@ -107,6 +135,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.nodeTemplatesSpace.name}</cm:title>
<cm:description>${spaces.nodeTemplatesSpace.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder view:childName="${spaces.smartfolders.childname}">
<view:acl view:inherit="false">
@@ -120,6 +152,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.smartfoldertemplates.name}</cm:title>
<cm:description>${spaces.smartfoldertemplates.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
<cm:folder view:childName="${spaces.smartdownloads.childname}">
<view:acl view:inherit="false">
@@ -133,6 +169,10 @@
<app:icon>space-icon-default</app:icon>
<cm:title>${spaces.smartdownloads.name}</cm:title>
<cm:description>${spaces.smartdownloads.description}</cm:description>
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
</cm:folder>
</cm:contains>
</cm:folder>

View File

@@ -4,10 +4,13 @@
xmlns:view="http://www.alfresco.org/view/repository/1.0"
xmlns:cm="http://www.alfresco.org/model/content/1.0"
xmlns:app="http://www.alfresco.org/model/application/1.0"
xmlns:trx="http://www.alfresco.org/model/transfer/1.0">
xmlns:trx="http://www.alfresco.org/model/transfer/1.0"
xmlns:sys="http://www.alfresco.org/model/system/1.0">
<cm:folder view:childName="${spaces.transfers.childname}">
<view:aspects>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<view:properties>
<cm:description>${spaces.transfers.description}</cm:description>

View File

@@ -3,6 +3,8 @@
<cm:folder xmlns:alf="http://www.alfresco.org" xmlns:d="http://www.alfresco.org/model/dictionary/1.0" xmlns:view="http://www.alfresco.org/view/repository/1.0" xmlns:act="http://www.alfresco.org/model/action/1.0" xmlns:wf="http://www.alfresco.org/model/workflow/1.0" xmlns:app="http://www.alfresco.org/model/application/1.0" xmlns:ver="http://www.alfresco.org/model/versionstore/1.0" xmlns:usr="http://www.alfresco.org/model/user/1.0" xmlns:cm="http://www.alfresco.org/model/content/1.0" xmlns:sys="http://www.alfresco.org/model/system/1.0" xmlns:rule="http://www.alfresco.org/model/rule/1.0" xmlns:fm="http://www.alfresco.org/model/forum/1.0" xmlns:bpm="http://www.alfresco.org/model/bpm/1.0" xmlns:custom="custom.model" xmlns="" view:childName="cm:webscripts">
<view:aspects>
<app:uifacets></app:uifacets>
<sys:undeletable/>
<sys:unmovable/>
</view:aspects>
<view:properties>
<cm:description>${webscripts.url_addressable_web_services}</cm:description>

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