[feature/MNT-24127-EndpointToCalculateFolderSize] Added Endpoint to calculate folder size

This commit is contained in:
Mohit Singh
2024-07-29 11:41:01 +05:30
78 changed files with 1122 additions and 431 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/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/free-hosted-runner-disk-space@v1.35.2
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2 - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.35.2
- uses: Alfresco/ya-pmd-scan@v3.0.0 - uses: Alfresco/ya-pmd-scan@v4.0.0
with: with:
classpath-build-command: "mvn test-compile -ntp -Pags -pl \"-:alfresco-community-repo-docker\"" classpath-build-command: "mvn test-compile -ntp -Pags -pl \"-:alfresco-community-repo-docker\""
@@ -174,6 +174,7 @@ jobs:
- name: "Init" - name: "Init"
run: bash ./scripts/ci/init.sh run: bash ./scripts/ci/init.sh
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -181,24 +182,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" eval "args=($RP_OPTS)"
mvn -B test -pl ${{ matrix.testModule }} -am ${{ matrix.testAttributes }} -DfailIfNoTests=false "${args[@]}" mvn -B test -pl ${{ matrix.testModule }} -am ${{ matrix.testAttributes }} -DfailIfNoTests=false "${args[@]}"
continue-on-error: true continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -206,6 +213,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -253,6 +261,7 @@ jobs:
- name: "Set up the environment" - name: "Set up the environment"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -260,24 +269,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -285,6 +300,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -320,6 +336,7 @@ jobs:
env: env:
MARIADB_VERSION: ${{ matrix.version }} MARIADB_VERSION: ${{ matrix.version }}
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -327,24 +344,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -352,6 +375,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -383,6 +407,7 @@ jobs:
env: env:
MARIADB_VERSION: 10.6 MARIADB_VERSION: 10.6
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -390,24 +415,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -415,6 +446,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -446,6 +478,7 @@ jobs:
env: env:
MYSQL_VERSION: 8 MYSQL_VERSION: 8
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -453,24 +486,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -478,6 +517,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -508,6 +548,7 @@ jobs:
env: env:
POSTGRES_VERSION: 13.12 POSTGRES_VERSION: 13.12
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -515,24 +556,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -540,6 +587,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -570,6 +618,7 @@ jobs:
env: env:
POSTGRES_VERSION: 14.9 POSTGRES_VERSION: 14.9
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -577,24 +626,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -602,6 +657,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -632,6 +688,7 @@ jobs:
env: env:
POSTGRES_VERSION: 15.4 POSTGRES_VERSION: 15.4
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -639,24 +696,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -664,6 +727,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -690,6 +754,7 @@ jobs:
- name: "Run ActiveMQ" - name: "Run ActiveMQ"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile activemq up -d run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile activemq up -d
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.13.1 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.13.1
id: rp-prepare id: rp-prepare
with: with:
@@ -697,24 +762,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=MessagingUnitTestSuite -DfailIfNoTests=false "${args[@]}" mvn -B test -pl repository -am -Dtest=MessagingUnitTestSuite -DfailIfNoTests=false "${args[@]}"
continue-on-error: true continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.13.1 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.13.1
id: rp-summarize id: rp-summarize
with: with:
@@ -722,6 +793,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -797,6 +869,7 @@ jobs:
- name: "Set up the environment" - name: "Set up the environment"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -804,24 +877,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -829,6 +908,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -895,6 +975,7 @@ jobs:
if: ${{ matrix.test-name }} == 'Integration TAS tests' if: ${{ matrix.test-name }} == 'Integration TAS tests'
run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -902,16 +983,19 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: tests id: tests
env: 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) }} timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: | run: |
eval "args=($RP_OPTS)" eval "args=($RP_OPTS)"
@@ -924,9 +1008,12 @@ jobs:
if: ${{ always() && steps.tests.outcome == 'failure' }} if: ${{ always() && steps.tests.outcome == 'failure' }}
run: ${TAS_SCRIPTS}/output_logs_for_failures.sh "packaging/tests/${{ matrix.pom-dir }}" run: ${TAS_SCRIPTS}/output_logs_for_failures.sh "packaging/tests/${{ matrix.pom-dir }}"
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -934,6 +1021,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.tests.outcome != 'success' if: steps.tests.outcome != 'success'
run: | run: |
@@ -960,6 +1048,7 @@ jobs:
- name: "Run Postgres 15.4 database" - name: "Run Postgres 15.4 database"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -967,24 +1056,30 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests" - name: "Run tests"
id: run-tests id: run-tests
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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 continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -992,6 +1087,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |
@@ -1027,6 +1123,7 @@ jobs:
bash ./scripts/ci/init.sh bash ./scripts/ci/init.sh
bash ./scripts/ci/build.sh bash ./scripts/ci/build.sh
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -1034,10 +1131,11 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify" - name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }} timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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/init.sh
bash ./scripts/ci/build.sh bash ./scripts/ci/build.sh
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -1078,10 +1177,11 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify" - name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }} timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" 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[@]}" 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" ${{ 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 mvn -B install -pl :alfresco-governance-services-automation-community-rest-api -am -Pags -Pall-tas-tests -DskipTests
- name: "Prepare Report Portal" - name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v5.1.0
id: rp-prepare id: rp-prepare
with: with:
@@ -1124,25 +1225,31 @@ jobs:
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary" - name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env: env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }} RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }} RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }} RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Test" - name: "Test"
id: run-tests id: run-tests
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }} timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env: env:
RP_OPTS: ${{ steps.rp-prepare.outputs.mvn-opts }} RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: | run: |
eval "args=($RP_OPTS)" eval "args=($RP_OPTS)"
mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -Dskip.automationtests=false -Pags -Pall-tas-tests "${args[@]}" mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -Dskip.automationtests=false -Pags -Pall-tas-tests "${args[@]}"
continue-on-error: true continue-on-error: true
- name: "Update GitHub Step Summary" - name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: | run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal" - name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0 uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v5.1.0
id: rp-summarize id: rp-summarize
with: with:
@@ -1150,6 +1257,7 @@ jobs:
rp-launch-key: ${{ steps.rp-prepare.outputs.key }} rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }} rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }} rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure" - name: "Exit on failure"
if: steps.run-tests.outcome != 'success' if: steps.run-tests.outcome != 'success'
run: | run: |

View File

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

View File

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

View File

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

View File

@@ -40,7 +40,7 @@ public class RetentionScheduleActionDefinition
private int periodAmount; private int periodAmount;
private String period; private String period;
private String periodProperty; private String periodProperty;
private boolean combineDispositionStepConditions; private boolean combineRetentionStepConditions;
private List<String> events; private List<String> events;
private boolean eligibleOnFirstCompleteEvent; private boolean eligibleOnFirstCompleteEvent;
private String description; private String description;

View File

@@ -79,7 +79,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
private static final String RETAIN_STEP = "retain"; private static final String RETAIN_STEP = "retain";
private static final String INVALID_PERIOD = "random"; private static final String INVALID_PERIOD = "random";
private static final String CUTOFF_STEP = "cutoff"; private static final String CUTOFF_STEP = "cutoff";
private static final String DESTROY_STEP = "destroy"; private static final String DESTROY_STEP = "destroyContent";
private static final String INVALID_PASSWORD = "wrongPassword"; private static final String INVALID_PASSWORD = "wrongPassword";
@Autowired @Autowired
@@ -107,7 +107,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
retentionScheduleActionDefinition.setPeriodAmount(PERIOD_AMOUNT); retentionScheduleActionDefinition.setPeriodAmount(PERIOD_AMOUNT);
retentionScheduleActionDefinition.setPeriodProperty(PERIOD_PROPERTY); retentionScheduleActionDefinition.setPeriodProperty(PERIOD_PROPERTY);
retentionScheduleActionDefinition.setPeriod(PERIOD); retentionScheduleActionDefinition.setPeriod(PERIOD);
retentionScheduleActionDefinition.setCombineDispositionStepConditions(false); retentionScheduleActionDefinition.setCombineRetentionStepConditions(false);
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(true); retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(true);
retentionScheduleActionDefinition.setEvents(EVENTS); retentionScheduleActionDefinition.setEvents(EVENTS);
} }
@@ -118,6 +118,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition(); RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition();
//Creating the first action "transfer" should give 422 //Creating the first action "transfer" should give 422
actionDefinition.setName(TRANSFER_STEP); actionDefinition.setName(TRANSFER_STEP);
actionDefinition.setLocation("location");
//Create retention schedule action definition //Create retention schedule action definition
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId()); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId());
// Verify the status code // Verify the status code
@@ -151,6 +152,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition(); RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(TRANSFER_STEP); actionDefinition1.setName(TRANSFER_STEP);
actionDefinition1.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId()); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId());
assertStatusCode(CREATED); assertStatusCode(CREATED);
@@ -190,6 +192,20 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
} }
@Test(priority = 5) @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() public void createRetentionScheduleWithSameStep()
{ {
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY)); RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
@@ -209,7 +225,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(CONFLICT); assertStatusCode(CONFLICT);
} }
@Test(priority = 6) @Test(priority = 7)
public void createRetentionScheduleWithMultipleTransferStep() public void createRetentionScheduleWithMultipleTransferStep()
{ {
RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY)); RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY));
@@ -223,16 +239,19 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition(); RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition();
actionDefinition1.setName(TRANSFER_STEP); actionDefinition1.setName(TRANSFER_STEP);
actionDefinition1.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId()); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId());
RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition(); RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition();
actionDefinition2.setName(TRANSFER_STEP); actionDefinition2.setName(TRANSFER_STEP);
actionDefinition2.setLocation("location");
getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId()); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId());
// Verify the status code // Verify the status code
assertStatusCode(CREATED); assertStatusCode(CREATED);
} }
@Test(priority = 7) @Test(priority = 8)
public void createRetentionScheduleStepFor201() public void createRetentionScheduleStepFor201()
{ {
//Create retention schedule action definition //Create retention schedule action definition
@@ -243,11 +262,11 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertEquals(createdRetentionActionDefinition.getName(), retentionScheduleActionDefinition.getName()); assertEquals(createdRetentionActionDefinition.getName(), retentionScheduleActionDefinition.getName());
assertEquals(createdRetentionActionDefinition.getDescription(), retentionScheduleActionDefinition.getDescription()); assertEquals(createdRetentionActionDefinition.getDescription(), retentionScheduleActionDefinition.getDescription());
assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionScheduleActionDefinition.getPeriodAmount()); assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionScheduleActionDefinition.getPeriodAmount());
assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionScheduleActionDefinition.isCombineDispositionStepConditions()); assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionScheduleActionDefinition.isCombineRetentionStepConditions());
assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent()); assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent());
} }
@Test(priority = 8) @Test(priority = 9)
public void createRetentionScheduleStepFor401() public void createRetentionScheduleStepFor401()
{ {
//Create retention schedule action definition //Create retention schedule action definition
@@ -256,7 +275,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(UNAUTHORIZED); assertStatusCode(UNAUTHORIZED);
} }
@Test(priority = 9) @Test(priority = 10)
public void createRetentionScheduleStepFor403() public void createRetentionScheduleStepFor403()
{ {
//Create retention schedule action definition //Create retention schedule action definition
@@ -265,7 +284,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(FORBIDDEN); assertStatusCode(FORBIDDEN);
} }
@Test(priority = 10) @Test(priority = 11)
public void retentionScheduleStepFor400() public void retentionScheduleStepFor400()
{ {
getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId()); getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId());
@@ -273,7 +292,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(BAD_REQUEST); assertStatusCode(BAD_REQUEST);
} }
@Test(priority = 11) @Test(priority = 12)
public void createRetentionScheduleStepFor404() public void createRetentionScheduleStepFor404()
{ {
//Create retention schedule action definition //Create retention schedule action definition
@@ -282,7 +301,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(NOT_FOUND); assertStatusCode(NOT_FOUND);
} }
@Test(priority = 12) @Test(priority = 13)
public void retentionScheduleStepFor403() public void retentionScheduleStepFor403()
{ {
// Get retention schedule steps with user having no rights // Get retention schedule steps with user having no rights
@@ -291,7 +310,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(FORBIDDEN); assertStatusCode(FORBIDDEN);
} }
@Test(priority = 13) @Test(priority = 14)
public void retentionScheduleStepFor401() public void retentionScheduleStepFor401()
{ {
getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId()); getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId());
@@ -299,7 +318,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertStatusCode(UNAUTHORIZED); assertStatusCode(UNAUTHORIZED);
} }
@Test(priority = 14) @Test(priority = 15)
public void retentionScheduleStepWith200() public void retentionScheduleStepWith200()
{ {
RetentionScheduleStepCollection receiveRetentionStepCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(createdRetentionSchedule.getId()); RetentionScheduleStepCollection receiveRetentionStepCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(createdRetentionSchedule.getId());
@@ -315,7 +334,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
assertEquals(createdRetentionActionDefinition.getDescription(), retentionActionDef.getDescription()); assertEquals(createdRetentionActionDefinition.getDescription(), retentionActionDef.getDescription());
assertEquals(createdRetentionActionDefinition.getPeriod(), retentionActionDef.getPeriod()); assertEquals(createdRetentionActionDefinition.getPeriod(), retentionActionDef.getPeriod());
assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionActionDef.getPeriodAmount()); assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionActionDef.getPeriodAmount());
assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionActionDef.isCombineDispositionStepConditions()); assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionActionDef.isCombineRetentionStepConditions());
assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionActionDef.isEligibleOnFirstCompleteEvent()); assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionActionDef.isEligibleOnFirstCompleteEvent());
}); });
} }
@@ -341,7 +360,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest
actionDefinition.setPeriodAmount(PERIOD_AMOUNT); actionDefinition.setPeriodAmount(PERIOD_AMOUNT);
actionDefinition.setPeriodProperty(PERIOD_PROPERTY); actionDefinition.setPeriodProperty(PERIOD_PROPERTY);
actionDefinition.setPeriod(PERIOD); actionDefinition.setPeriod(PERIOD);
actionDefinition.setCombineDispositionStepConditions(false); actionDefinition.setCombineRetentionStepConditions(false);
actionDefinition.setEligibleOnFirstCompleteEvent(true); actionDefinition.setEligibleOnFirstCompleteEvent(true);
actionDefinition.setEvents(EVENTS); actionDefinition.setEvents(EVENTS);
return actionDefinition; return actionDefinition;

View File

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

View File

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

View File

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

View File

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

View File

@@ -939,7 +939,7 @@ public class ApiNodesModelFactory
{ {
RetentionSchedule retentionSchedule = new RetentionSchedule(); RetentionSchedule retentionSchedule = new RetentionSchedule();
retentionSchedule.setId(dispositionSchedule.getNodeRef().getId()); retentionSchedule.setId(dispositionSchedule.getNodeRef().getId());
if(dispositionSchedule.getNodeRef() != null) { if (dispositionSchedule.getNodeRef() != null) {
NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef(); NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef();
retentionSchedule.setParentId(parent.getId()); retentionSchedule.setParentId(parent.getId());
} }
@@ -984,7 +984,7 @@ public class ApiNodesModelFactory
retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent()); retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent());
if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null) if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null)
{ {
retentionScheduleActionDefinition.setCombineDispositionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS)); retentionScheduleActionDefinition.setCombineRetentionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
} }
retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation()); retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation());
if (dispositionActionDefinition.getGhostOnDestroy() != null) if (dispositionActionDefinition.getGhostOnDestroy() != null)
@@ -1001,7 +1001,7 @@ public class ApiNodesModelFactory
*/ */
private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition) private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
{ {
if(dispositionActionDefinition.getPeriodProperty() != null) if (dispositionActionDefinition.getPeriodProperty() != null)
{ {
retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService)); retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService));
} }
@@ -1078,10 +1078,20 @@ public class ApiNodesModelFactory
public Map<QName, Serializable> createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo) public Map<QName, Serializable> createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo)
{ {
Map<QName, Serializable> actionDefinitionParams= new HashMap<>(); Map<QName, Serializable> actionDefinitionParams= new HashMap<>();
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, nodeInfo.getName());
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()); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, nodeInfo.getDescription());
StringBuilder retentionPeriod = new StringBuilder(nodeInfo.getPeriod()).append("|"); StringBuilder retentionPeriod = new StringBuilder(nodeInfo.getPeriod()).append("|");
if(isPeriodAmountApplicable(nodeInfo.getPeriod()))
if (isPeriodAmountApplicable(nodeInfo.getPeriod()))
{ {
retentionPeriod.append(nodeInfo.getPeriodAmount()); retentionPeriod.append(nodeInfo.getPeriodAmount());
} }
@@ -1090,17 +1100,22 @@ public class ApiNodesModelFactory
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD_PROPERTY, periodProperty); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD_PROPERTY, periodProperty);
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT_COMBINATION, actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT_COMBINATION,
nodeInfo.isEligibleOnFirstCompleteEvent()); nodeInfo.isEligibleOnFirstCompleteEvent());
actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, boolean combineConditions = nodeInfo.getName().equals(RetentionSteps.ACCESSION.stepName) && nodeInfo.isCombineRetentionStepConditions();
nodeInfo.isCombineDispositionStepConditions()); actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, combineConditions);
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION,
nodeInfo.getLocation()); if(nodeInfo.getLocation() != null && nodeInfo.getName().equals(RetentionSteps.TRANSFER.stepName))
{
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION,
nodeInfo.getLocation());
}
List<String> inputEvents = nodeInfo.getEvents(); List<String> inputEvents = nodeInfo.getEvents();
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents);
if (RetentionSteps.DESTROY.stepName.equals(nodeInfo.getName()) && nodeInfo.isRetainRecordMetadataAfterDestruction())
if (RetentionSteps.DESTROY_CONTENT.stepName.equals(nodeInfo.getName()))
{ {
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost"); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost");
} }
else else if (RetentionSteps.DESTROY_NODE.stepName.equals(nodeInfo.getName()))
{ {
actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "delete"); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "delete");
} }

View File

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

View File

@@ -38,13 +38,13 @@ public class RetentionScheduleActionDefinition
{ {
private String id; private String id;
private String name; private String name;
private String description;
private int periodAmount; private int periodAmount;
private String period; private String period;
private String periodProperty; private String periodProperty;
private boolean combineDispositionStepConditions; private boolean combineRetentionStepConditions;
private List<String> events; private List<String> events;
private boolean eligibleOnFirstCompleteEvent; private boolean eligibleOnFirstCompleteEvent;
private String description;
private boolean retainRecordMetadataAfterDestruction; private boolean retainRecordMetadataAfterDestruction;
private String location; private String location;
private int index; private int index;

View File

@@ -35,7 +35,8 @@ public enum RetentionSteps
CUTOFF("cutoff"), CUTOFF("cutoff"),
TRANSFER("transfer"), TRANSFER("transfer"),
ACCESSION("accession"), ACCESSION("accession"),
DESTROY("destroy"); DESTROY_CONTENT("destroyContent"),
DESTROY_NODE("destroyNode");
public final String stepName; public final String stepName;

View File

@@ -146,6 +146,11 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
*/ */
private void retentionScheduleStepValidation(NodeRef retentionScheduleNodeRef, RetentionScheduleActionDefinition retentionScheduleActionDefinition) 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); List<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
Set<String> completedActions = new HashSet<>(); Set<String> completedActions = new HashSet<>();
if (!actions.isEmpty()) if (!actions.isEmpty())
@@ -155,9 +160,9 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
if (completedActions.contains(RetentionSteps.DESTROY.stepName)) if (completedActions.contains("destroy"))
{ {
throw new ConstraintViolatedException("Invalid Step - destroy action is already added . No other action is allowed after Destroy."); throw new ConstraintViolatedException("Invalid Step - destroy action is already added. No other action is allowed after Destroy.");
} }
if (checkStepAlreadyExists(completedActions, retentionScheduleActionDefinition.getName())) if (checkStepAlreadyExists(completedActions, retentionScheduleActionDefinition.getName()))
@@ -176,6 +181,11 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
} }
} }
private boolean checkStepNameIsEmpty(String name)
{
return name == null || name.isEmpty();
}
/** /**
* this method is used to validate the request of the retention schedule * this method is used to validate the request of the retention schedule
* @param retentionScheduleActionDefinition retention schedule action definition * @param retentionScheduleActionDefinition retention schedule action definition
@@ -187,16 +197,34 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
{ {
throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName()); throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName());
} }
// period value validation
if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod())) validatePeriodAndPeriodProperty(retentionScheduleActionDefinition);
{
throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod());
}
// event name validation // event name validation
if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents())) if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents()))
{ {
throw new InvalidArgumentException("event value is invalid: " + 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 // periodProperty validation
List<String> validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf"); List<String> validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf");
if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals)) if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals))
@@ -205,6 +233,19 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
} }
} }
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) private boolean checkStepAlreadyExists(Set<String> completedActions, String stepName)
{ {
return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName); return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName);

View File

@@ -26,9 +26,12 @@
*/ */
package org.alfresco.rm.rest.api.retentionschedule; 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.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.rest.framework.WebApiDescription; 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.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
@@ -37,10 +40,12 @@ import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils; import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.RetentionSchedule; import org.alfresco.rm.rest.api.model.RetentionSchedule;
import org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource; 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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@@ -96,6 +101,11 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea
mandatory("entity", nodeInfos); mandatory("entity", nodeInfos);
mandatory("parameters", parameters); mandatory("parameters", parameters);
NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordCategoryId); 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<>(); List<RetentionSchedule> result = new ArrayList<>();
// Create the disposition schedule // Create the disposition schedule
Map<QName, Serializable> dsProps = new HashMap<>(); Map<QName, Serializable> dsProps = new HashMap<>();
@@ -108,6 +118,14 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea
return result; 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 @Override
@WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'") @WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'")
public CollectionWithPagingInfo<RetentionSchedule> readAll(String recordCategoryId, Parameters parameters) public CollectionWithPagingInfo<RetentionSchedule> readAll(String recordCategoryId, Parameters parameters)

View File

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

View File

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

View File

@@ -2683,6 +2683,8 @@ paths:
description: recordCategoryId does not exist description: recordCategoryId does not exist
'409': '409':
description: Retention schedule already exist for the given recordCategoryId 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: default:
description: Unexpected error description: Unexpected error
schema: schema:
@@ -2742,13 +2744,13 @@ paths:
```JSON ```JSON
{ {
"name":"accession", "name":"accession",
"description":"Step Description",
"periodAmount": 2, "periodAmount": 2,
"period":"month", "period":"month",
"periodProperty":"cm:created", "periodProperty":"cm:created",
"combineDispositionStepConditions": false, "combineRetentionStepConditions": false,
"events":["versioned"], "events":["versioned"],
"eligibleOnFirstCompleteEvent": true, "eligibleOnFirstCompleteEvent": true
"description":"Step Description"
} }
``` ```
operationId: createRetentionScheduleAction operationId: createRetentionScheduleAction
@@ -4534,20 +4536,20 @@ definitions:
type: string type: string
name: name:
type: string type: string
description:
type: string
periodAmount: periodAmount:
type: integer type: integer
period: period:
type: string type: string
periodProperty: periodProperty:
type: string type: string
combineDispositionStepConditions: combineRetentionStepConditions:
type: boolean type: boolean
default: false default: false
eligibleOnFirstCompleteEvent: eligibleOnFirstCompleteEvent:
type: boolean type: boolean
default: true default: true
description:
type: string
retainRecordMetadataAfterDestruction: retainRecordMetadataAfterDestruction:
type: boolean type: boolean
location: location:
@@ -4560,6 +4562,9 @@ definitions:
type: integer type: integer
RetentionStepNodeBodyCreate: RetentionStepNodeBodyCreate:
type: object type: object
required:
- name
- description
properties: properties:
name: name:
type: string type: string
@@ -4569,7 +4574,15 @@ definitions:
* cutoff * cutoff
* accession * accession
* transfer * transfer
* destroy * 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: periodAmount:
type: integer type: integer
description: | description: |
@@ -4618,7 +4631,7 @@ definitions:
* cm:created = Created Date (defult value) * cm:created = Created Date (defult value)
* rma:cutOffDate = Cut Off Date * rma:cutOffDate = Cut Off Date
* rma:dispositionAsOf = Retention Action * rma:dispositionAsOf = Retention Action
combineDispositionStepConditions: combineRetentionStepConditions:
type: boolean type: boolean
description: | description: |
This property is only valid for **accession** step. This property is only valid for **accession** step.
@@ -4653,14 +4666,6 @@ definitions:
description: | description: |
* false = When all events have happened * false = When all events have happened
* true = Whichever event is earlier * true = Whichever event is earlier
description:
type: string
description: |
This property is used to provide the step description.
retainRecordMetadataAfterDestruction:
type: boolean
description: |
This property is used to retain the metadata after record destruction.
location: location:
type: string type: string
description: | description: |

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,7 @@ package org.alfresco.util;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Random; import java.util.Random;
import org.safehaus.uuid.UUIDGenerator; import com.fasterxml.uuid.Generators;
import org.alfresco.api.AlfrescoPublicApi; import org.alfresco.api.AlfrescoPublicApi;
/** /**
@@ -69,7 +69,7 @@ public final class GUID
public static String generate() public static String generate()
{ {
int randomInt = RANDOM.nextInt(SECURE_RANDOM_POOL_MAX_ITEMS); int randomInt = RANDOM.nextInt(SECURE_RANDOM_POOL_MAX_ITEMS);
return 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) == // == Not sure if we need this functionality again (derekh) ==

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

91
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"> <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> <modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.3.0.63-SNAPSHOT</version> <version>23.3.0.86-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name> <name>Alfresco Community Repo Parent</name>
@@ -51,54 +51,54 @@
<dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version> <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-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.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-core.version>5.1.3</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.3-A2</dependency.alfresco-transform-service.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.alfresco-greenmail.version>7.0</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.27</dependency.acs-event-model.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.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.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.15.2</dependency.jackson.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.opencmis.version>1.0.0-jakarta-1</dependency.opencmis.version>
<dependency.webscripts.version>9.0</dependency.webscripts.version> <dependency.webscripts.version>9.0</dependency.webscripts.version>
<dependency.bouncycastle.version>1.78.1</dependency.bouncycastle.version> <dependency.bouncycastle.version>1.78.1</dependency.bouncycastle.version>
<dependency.mockito-core.version>5.4.0</dependency.mockito-core.version> <dependency.mockito-core.version>5.12.0</dependency.mockito-core.version>
<dependency.assertj.version>3.24.2</dependency.assertj.version> <dependency.assertj.version>3.26.3</dependency.assertj.version>
<dependency.org-json.version>20231013</dependency.org-json.version> <dependency.org-json.version>20231013</dependency.org-json.version>
<dependency.commons-dbcp.version>2.9.0</dependency.commons-dbcp.version> <dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.14.0</dependency.commons-io.version> <dependency.commons-io.version>2.16.1</dependency.commons-io.version>
<dependency.gson.version>2.10.1</dependency.gson.version> <dependency.gson.version>2.11.0</dependency.gson.version>
<dependency.guava.version>32.1.2-jre</dependency.guava.version> <dependency.guava.version>33.2.1-jre</dependency.guava.version>
<dependency.httpclient.version>4.5.14</dependency.httpclient.version> <dependency.httpclient.version>4.5.14</dependency.httpclient.version>
<dependency.httpcore.version>4.4.16</dependency.httpcore.version> <dependency.httpcore.version>4.4.16</dependency.httpcore.version>
<dependency.httpcomponents-httpclient5.version>5.2.1</dependency.httpcomponents-httpclient5.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.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version> <dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>2.0.9</dependency.slf4j.version> <dependency.slf4j.version>2.0.13</dependency.slf4j.version>
<dependency.log4j.version>2.20.0</dependency.log4j.version> <dependency.log4j.version>2.23.1</dependency.log4j.version>
<dependency.groovy.version>3.0.19</dependency.groovy.version> <dependency.groovy.version>3.0.22</dependency.groovy.version>
<dependency.tika.version>2.9.2</dependency.tika.version> <dependency.tika.version>2.9.2</dependency.tika.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version> <dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>5.2.5</dependency.poi.version> <dependency.poi.version>5.2.5</dependency.poi.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.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.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.activemq.version>5.18.3</dependency.activemq.version>
<dependency.apache-compress.version>1.26.0</dependency.apache-compress.version> <dependency.apache-compress.version>1.26.2</dependency.apache-compress.version>
<dependency.awaitility.version>4.2.0</dependency.awaitility.version> <dependency.awaitility.version>4.2.1</dependency.awaitility.version>
<dependency.swagger-ui.version>4.1.3</dependency.swagger-ui.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-filtering.version>3.1.1</dependency.maven-filtering.version>
<dependency.maven-artifact.version>3.8.6</dependency.maven-artifact.version> <dependency.maven-artifact.version>3.8.6</dependency.maven-artifact.version>
<dependency.jdom2.version>2.0.6.1</dependency.jdom2.version> <dependency.jdom2.version>2.0.6.1</dependency.jdom2.version>
<dependency.pooled-jms.version>3.1.6</dependency.pooled-jms.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-api.version>4.0.2</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-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-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-soap-api.version>2.0.1</dependency.jakarta-soap-api.version>
<dependency.jakarta-annotation-api.version>2.1.1</dependency.jakarta-annotation-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-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-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-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.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-api.version>2.1.3</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-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.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.googledrive.version>4.1.0</alfresco.googledrive.version>
<alfresco.aos-module.version>3.1.0-A1</alfresco.aos-module.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 --> <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.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version> <dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>5.0.1</dependency.tas-utility.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-email.version>2.0.0</dependency.tas-email.version>
<dependency.tas-webdav.version>1.21</dependency.tas-webdav.version> <dependency.tas-webdav.version>1.21</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.19</dependency.tas-ftp.version> <dependency.tas-ftp.version>1.19</dependency.tas-ftp.version>
@@ -401,7 +401,7 @@
<dependency> <dependency>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
<version>1.2</version> <version>1.3.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-beanutils</groupId> <groupId>commons-beanutils</groupId>
@@ -442,7 +442,7 @@
<dependency> <dependency>
<groupId>commons-net</groupId> <groupId>commons-net</groupId>
<artifactId>commons-net</artifactId> <artifactId>commons-net</artifactId>
<version>3.9.0</version> <version>3.11.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
@@ -462,7 +462,7 @@
<dependency> <dependency>
<groupId>org.apache.xmlbeans</groupId> <groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId> <artifactId>xmlbeans</artifactId>
<version>5.2.0</version> <version>5.2.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
@@ -621,7 +621,7 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId> <artifactId>commons-email</artifactId>
<version>1.5</version> <version>1.6.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.alfresco.aos-module</groupId> <groupId>org.alfresco.aos-module</groupId>
@@ -700,13 +700,13 @@
<dependency> <dependency>
<groupId>com.networknt</groupId> <groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId> <artifactId>json-schema-validator</artifactId>
<version>1.0.86</version> <version>1.5.0</version>
</dependency> </dependency>
<!-- upgrade dependency from TIKA --> <!-- upgrade dependency from TIKA -->
<dependency> <dependency>
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.16.1</version> <version>1.18.1</version>
</dependency> </dependency>
<!-- upgrade dependency from TIKA --> <!-- upgrade dependency from TIKA -->
<dependency> <dependency>
@@ -851,6 +851,17 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
<version>${dependency.commons-dbcp.version}</version> <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>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
@@ -936,7 +947,7 @@
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.30</version> <version>1.18.34</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -975,7 +986,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version> <version>3.13.0</version>
<configuration> <configuration>
<compilerArgs> <compilerArgs>
<arg>-parameters</arg> <arg>-parameters</arg>
@@ -1005,7 +1016,7 @@
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version> <version>3.4.2</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-war-plugin</artifactId> <artifactId>maven-war-plugin</artifactId>
@@ -1014,7 +1025,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version> <version>3.7.0</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@@ -1024,11 +1035,11 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version> <version>3.7.1</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version> <version>3.7.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.alfresco.maven.plugin</groupId> <groupId>org.alfresco.maven.plugin</groupId>
@@ -1074,7 +1085,7 @@
<plugin> <plugin>
<groupId>org.codehaus.cargo</groupId> <groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId> <artifactId>cargo-maven3-plugin</artifactId>
<version>1.10.9</version> <version>1.10.14</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

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

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Remote API * 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. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -909,16 +909,14 @@ public class AuditImpl implements Audit
public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker) public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker)
{ {
final String applicationName = auditApplication.getKey().substring(1);
AuditQueryParameters parameters = new AuditQueryParameters(); AuditQueryParameters parameters = new AuditQueryParameters();
parameters.setApplicationName(applicationName); parameters.setApplicationName(auditApplication.getName());
parameters.setFromTime(propertyWalker.getFromTime()); parameters.setFromTime(propertyWalker.getFromTime());
parameters.setToTime(propertyWalker.getToTime()); parameters.setToTime(propertyWalker.getToTime());
parameters.setFromId(propertyWalker.getFromId()); parameters.setFromId(propertyWalker.getFromId());
parameters.setToId(propertyWalker.getToId()); parameters.setToId(propertyWalker.getToId());
parameters.setUser(propertyWalker.getCreatedByUser()); 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 ResetPasswordService resetPasswordService;
protected UserRegistrySynchronizer userRegistrySynchronizer; protected UserRegistrySynchronizer userRegistrySynchronizer;
protected Renditions renditions; protected Renditions renditions;
private Boolean allowImmutableEnabledUpdate;
private final static Map<String, QName> sort_params_to_qnames; private final static Map<String, QName> sort_params_to_qnames;
static static
@@ -202,6 +202,11 @@ public class PeopleImpl implements People
this.userRegistrySynchronizer = userRegistrySynchronizer; this.userRegistrySynchronizer = userRegistrySynchronizer;
} }
public void setAllowImmutableEnabledUpdate(Boolean allowImmutableEnabledUpdate)
{
this.allowImmutableEnabledUpdate = allowImmutableEnabledUpdate;
}
/** /**
* Validate, perform -me- substitution and canonicalize the person ID. * Validate, perform -me- substitution and canonicalize the person ID.
* *
@@ -708,16 +713,26 @@ public class PeopleImpl implements People
// if requested, update password // if requested, update password
updatePassword(isAdmin, personIdToUpdate, person); updatePassword(isAdmin, personIdToUpdate, person);
if (person.isEnabled() != null) Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
Boolean isEnabled = person.isEnabled();
if (isEnabled != null)
{ {
if (isAdminAuthority(personIdToUpdate)) if (isAdminAuthority(personIdToUpdate))
{ {
throw new PermissionDeniedException("Admin authority cannot be disabled."); throw new PermissionDeniedException("Admin authority cannot be disabled.");
} }
// note: if current user is not an admin then permission denied exception is thrown if (allowImmutableEnabledStatusUpdate(personIdToUpdate, isAdmin, immutableProperties))
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService; {
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled()); 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); NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
@@ -742,9 +757,7 @@ public class PeopleImpl implements People
properties.putAll(nodes.mapToNodeProperties(customProps)); properties.putAll(nodes.mapToNodeProperties(customProps));
} }
// MNT-21150 LDAP synced attributes can be changed using REST API // MNT-21150 LDAP synced attributes can't be changed using REST API
Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
immutableProperties.forEach(immutableProperty -> { immutableProperties.forEach(immutableProperty -> {
if (properties.containsKey(immutableProperty)) if (properties.containsKey(immutableProperty))
{ {
@@ -768,6 +781,28 @@ public class PeopleImpl implements People
return getPerson(personId); 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) private boolean checkCurrentUserOrAdmin(String personId)
{ {
boolean isAdmin = isAdminAuthority(); boolean isAdmin = isAdminAuthority();

View File

@@ -764,6 +764,7 @@
<property name="thumbnailService" ref="ThumbnailService" /> <property name="thumbnailService" ref="ThumbnailService" />
<property name="resetPasswordService" ref="resetPasswordService" /> <property name="resetPasswordService" ref="resetPasswordService" />
<property name="userRegistrySynchronizer" ref="userRegistrySynchronizer" /> <property name="userRegistrySynchronizer" ref="userRegistrySynchronizer" />
<property name="allowImmutableEnabledUpdate" value="${allow.immutable.user.enabled.status.update}" />
</bean> </bean>
<bean id="People" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="People" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -276,11 +276,10 @@ public interface AuditComponent
/** /**
* Issue an audit query to retrieve count of records for a given application and properties * 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 * @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 * @return a map containing min/max and the associated value
*/ */
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters) default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{ {
return -1; return -1;
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -956,10 +956,8 @@ public class AuditComponentImpl implements AuditComponent
return auditDAO.getAuditEntriesCountByApp(applicationId); 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(parameters);
return auditDAO.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
} }
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -190,8 +190,8 @@ public class AuditServiceImpl implements AuditService
/** /**
* {@inheritDoc} * {@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 * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain; package org.alfresco.repo.domain;
@@ -102,21 +102,22 @@ public class CrcHelper
{ {
throw new RuntimeException("UTF-8 encoding is not supported"); 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; String valueShort = null;
int valueLen = valueLowerCase.length(); String currentValue = caseSensitive ? value : valueLowerCase;
int valueLen = currentValue.length();
if (valueLen < dataLength) if (valueLen < dataLength)
{ {
valueShort = valueLowerCase; valueShort = currentValue;
} }
else if (useCharsFromStart) else if (useCharsFromStart)
{ {
valueShort = valueLowerCase.substring(0, dataLength - 1); valueShort = currentValue.substring(0, dataLength - 1);
} }
else else
{ {
valueShort = valueLowerCase.substring(valueLen - dataLength); valueShort = currentValue.substring(valueLen - dataLength);
} }
return new Pair<String, Long>(valueShort, valueCrc); return new Pair<String, Long>(valueShort, valueCrc);
} }
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -248,11 +248,10 @@ public interface AuditDAO
/** /**
* Issue an audit query to retrieve count of records for a given application and properties * 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 * @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 * @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; return -1;
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -237,7 +237,7 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
} }
@Override @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); AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters);

View File

@@ -2785,6 +2785,23 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
selectNodesWithAspects(qnameIds, minNodeId, maxNodeId, ordered, resultsCallback); 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 * @return Returns a writable copy of the cached aspects set
*/ */
@@ -4960,6 +4977,10 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
List<Long> qnameIds, List<Long> qnameIds,
Long minNodeId, Long maxNodeId, boolean ordered, Long minNodeId, Long maxNodeId, boolean ordered,
NodeRefQueryCallback resultsCallback); 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 Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex);
protected abstract int updateNodeAssoc(Long id, int assocIndex); protected abstract int updateNodeAssoc(Long id, int assocIndex);
protected abstract int deleteNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId); 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 selectMinTxInNodeIdRange(Long fromNodeId, Long toNodeId);
protected abstract Long selectMaxTxInNodeIdRange(Long fromNodeId, Long toNodeId); protected abstract Long selectMaxTxInNodeIdRange(Long fromNodeId, Long toNodeId);
protected abstract Long selectNextTxCommitTime(Long fromCommitTime); protected abstract Long selectNextTxCommitTime(Long fromCommitTime);
} }

View File

@@ -427,6 +427,22 @@ public interface NodeDAO extends NodeBulkLoader
Long minNodeId, Long maxNodeId, boolean ordered, Long minNodeId, Long maxNodeId, boolean ordered,
NodeRefQueryCallback resultsCallback); 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 * 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_MAX_ID = "alfresco.node.select_NodeMaxId";
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType"; 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 = "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 INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc"; private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
private static final String DELETE_NODE_ASSOC = "alfresco.node.delete_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); 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 @Override
protected Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex) 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_REQUIRED_KEY = "FIXED_ACL_ASYNC_REQUIRED";
public static final String FIXED_ACL_ASYNC_CALL_KEY = "FIXED_ACL_ASYNC_CALL"; 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"); 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. */ /** A set of listeners to receive callback events whenever permissions are updated by this class. */
private static Set<FixedAclUpdaterListener> listeners = Sets.newConcurrentHashSet(); private static Set<FixedAclUpdaterListener> listeners = Sets.newConcurrentHashSet();
@@ -101,6 +104,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
private int maxItemBatchSize = 100; private int maxItemBatchSize = 100;
private int numThreads = 4; private int numThreads = 4;
private boolean forceSharedACL = false; private boolean forceSharedACL = false;
private int maxItems = DEFAULT_MAX_ITEMS;
private boolean orderNodes = true;
private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate; private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
@@ -147,12 +152,22 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
this.forceSharedACL = forceSharedACL; this.forceSharedACL = forceSharedACL;
} }
public void setOrderNodes(boolean orderNodes)
{
this.orderNodes = orderNodes;
}
public void setLockTimeToLive(long lockTimeToLive) public void setLockTimeToLive(long lockTimeToLive)
{ {
this.lockTimeToLive = lockTimeToLive; this.lockTimeToLive = lockTimeToLive;
this.lockRefreshTime = lockTimeToLive / 2; this.lockRefreshTime = lockTimeToLive / 2;
} }
public void setMaxItems(int maxItems)
{
this.maxItems = maxItems > 0 ? maxItems : DEFAULT_MAX_ITEMS;
}
public void setPolicyComponent(PolicyComponent policyComponent) public void setPolicyComponent(PolicyComponent policyComponent)
{ {
this.policyComponent = policyComponent; this.policyComponent = policyComponent;
@@ -209,7 +224,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
public List<NodeRef> execute() throws Throwable public List<NodeRef> execute() throws Throwable
{ {
getNodesCallback.init(); getNodesCallback.init();
nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, true, getNodesCallback); nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, orderNodes, maxItemBatchSize, getNodesCallback);
getNodesCallback.done(); getNodesCallback.done();
return getNodesCallback.getNodes(); return getNodesCallback.getNodes();
@@ -220,6 +235,11 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
int countNodesWithAspects() 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(); final CountNodesWithAspectCallback countNodesCallback = new CountNodesWithAspectCallback();
int count = transactionService.getRetryingTransactionHelper() int count = transactionService.getRetryingTransactionHelper()
.doInTransaction(new RetryingTransactionCallback<Integer>() .doInTransaction(new RetryingTransactionCallback<Integer>()
@@ -238,6 +258,9 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
private class AclWorkProvider implements BatchProcessWorkProvider<NodeRef> private class AclWorkProvider implements BatchProcessWorkProvider<NodeRef>
{ {
private GetNodesWithAspects getNodesWithAspects; private GetNodesWithAspects getNodesWithAspects;
private long estimatedUpdatedItems;
private long execTime;
private long execBatches;
AclWorkProvider() AclWorkProvider()
{ {
@@ -259,8 +282,37 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
@Override @Override
public Collection<NodeRef> getNextWork() 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> protected class AclWorker implements BatchProcessor.BatchProcessWorker<NodeRef>
@@ -451,6 +503,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
try try
{ {
log.info("Running FixedAclUpdater. Max Items: " + maxItems + ", Impose order: " + orderNodes);
lockToken = jobLockService.getLock(LOCK_Q_NAME, lockTimeToLive, 0, 1); lockToken = jobLockService.getLock(LOCK_Q_NAME, lockTimeToLive, 0, 1);
jobLockService.refreshLock(lockToken, LOCK_Q_NAME, lockRefreshTime, jobLockRefreshCallback); 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, transactionService.getRetryingTransactionHelper(), provider, numThreads, maxItemBatchSize, applicationContext,
log, 100); log, 100);
int count = bp.process(worker, true); int count = bp.process(worker, true);
log.info("FixedAclUpdater updated " + count + ". Average query time " + provider.getAverageQueryExecutionTime() + " ms");
return count; return count;
} }
catch (LockAcquisitionException e) catch (LockAcquisitionException e)

View File

@@ -1,28 +1,28 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain.propval; package org.alfresco.repo.domain.propval;
import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.CrcHelper;
@@ -44,6 +44,7 @@ public class PropertyStringValueEntity
private String stringValue; private String stringValue;
private String stringEndLower; private String stringEndLower;
private Long stringCrc; private Long stringCrc;
private String stringLower;
public PropertyStringValueEntity() public PropertyStringValueEntity()
{ {
@@ -115,6 +116,9 @@ public class PropertyStringValueEntity
Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true); Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true);
stringEndLower = crcPair.getFirst(); stringEndLower = crcPair.getFirst();
stringCrc = crcPair.getSecond(); 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() public Long getId()
@@ -156,4 +160,14 @@ public class PropertyStringValueEntity
{ {
this.stringCrc = stringCrc; this.stringCrc = stringCrc;
} }
public String getStringLower()
{
return stringLower;
}
public void setStringLower(String stringLower)
{
this.stringLower = stringLower;
}
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -36,18 +36,13 @@ import org.springframework.beans.factory.InitializingBean;
/** /**
* Sends a message to a destination in the current thread. * 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 DirectEventSender(Event2MessageProducer event2MessageProducer)
public void afterPropertiesSet()
{ {
PropertyCheck.mandatory(this, "event2MessageProducer", event2MessageProducer); PropertyCheck.mandatory(this, "event2MessageProducer", event2MessageProducer);
}
public void setEvent2MessageProducer(Event2MessageProducer event2MessageProducer)
{
this.event2MessageProducer = event2MessageProducer; this.event2MessageProducer = event2MessageProducer;
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -46,28 +46,18 @@ public class EnqueuingEventSender extends DirectEventSender
{ {
protected static final Log LOGGER = LogFactory.getLog(EnqueuingEventSender.class); protected static final Log LOGGER = LogFactory.getLog(EnqueuingEventSender.class);
protected Executor enqueueThreadPoolExecutor; protected final Executor enqueueThreadPoolExecutor;
protected Executor dequeueThreadPoolExecutor; protected final Executor dequeueThreadPoolExecutor;
protected BlockingQueue<EventInMaking> queue = new LinkedBlockingQueue<>(); protected BlockingQueue<EventInMaking> queue = new LinkedBlockingQueue<>();
protected Runnable listener = createListener(); protected Runnable listener = createListener();
@Override public EnqueuingEventSender(Event2MessageProducer event2MessageProducer, Executor enqueueThreadPoolExecutor, Executor dequeueThreadPoolExecutor)
public void afterPropertiesSet()
{ {
super.afterPropertiesSet(); super(event2MessageProducer);
PropertyCheck.mandatory(this, "enqueueThreadPoolExecutor", enqueueThreadPoolExecutor); PropertyCheck.mandatory(this, "enqueueThreadPoolExecutor", enqueueThreadPoolExecutor);
PropertyCheck.mandatory(this, "dequeueThreadPoolExecutor", dequeueThreadPoolExecutor); PropertyCheck.mandatory(this, "dequeueThreadPoolExecutor", dequeueThreadPoolExecutor);
}
public void setEnqueueThreadPoolExecutor(Executor enqueueThreadPoolExecutor)
{
this.enqueueThreadPoolExecutor = enqueueThreadPoolExecutor; this.enqueueThreadPoolExecutor = enqueueThreadPoolExecutor;
}
public void setDequeueThreadPoolExecutor(Executor dequeueThreadPoolExecutor)
{
this.dequeueThreadPoolExecutor = 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. * 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. * @return The task in charge of dequeuing and sending events ready to be sent.

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -40,4 +40,13 @@ public interface EventSender
* @param eventProducer - callback function that creates an event * @param eventProducer - callback function that creates an event
*/ */
void accept(Callable<Optional<RepoEvent<?>>> eventProducer); 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.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; 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.ActivityEvent;
import org.alfresco.sync.events.types.Event; import org.alfresco.sync.events.types.Event;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
@@ -108,8 +111,6 @@ import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Interval; import org.joda.time.Interval;
import org.joda.time.PeriodType; import org.joda.time.PeriodType;
import org.safehaus.uuid.UUID;
import org.safehaus.uuid.UUIDGenerator;
/** /**
* QuickShare Service implementation. * QuickShare Service implementation.
@@ -435,8 +436,8 @@ public class QuickShareServiceImpl implements QuickShareService,
// If it is retura dto built from the existing properties. // If it is retura dto built from the existing properties.
if (! nodeService.getAspects(nodeRef).contains(QuickShareModel.ASPECT_QSHARE)) if (! nodeService.getAspects(nodeRef).contains(QuickShareModel.ASPECT_QSHARE))
{ {
UUID uuid = UUIDGenerator.getInstance().generateRandomBasedUUID(); UUID uuid = Generators.randomBasedGenerator().generate();
sharedId = Base64.encodeBase64URLSafeString(uuid.toByteArray()); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw) sharedId = Base64.encodeBase64URLSafeString(UUIDUtil.asByteArray(uuid)); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw)
final Map<QName, Serializable> props = new HashMap<QName, Serializable>(2); final Map<QName, Serializable> props = new HashMap<QName, Serializable>(2);
props.put(QuickShareModel.PROP_QSHARE_SHAREDID, sharedId); props.put(QuickShareModel.PROP_QSHARE_SHAREDID, sharedId);
@@ -1246,7 +1247,7 @@ public class QuickShareServiceImpl implements QuickShareService,
} }
// Create the expiry action // 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"); "QuickShare link expiry action");
// Create the persisted schedule // Create the persisted schedule
final ScheduledPersistedAction schedule = scheduledPersistedActionService.createSchedule(expiryAction); 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.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User; import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantService; 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -49,12 +53,30 @@ public class AuthenticationContextImpl implements AuthenticationContext
private final Log logger = LogFactory.getLog(getClass()); private final Log logger = LogFactory.getLog(getClass());
private TenantService tenantService; private TenantService tenantService;
private PersonService personService;
private AuthenticationService authenticationService;
private Boolean allowImmutableEnabledUpdate;
public void setTenantService(TenantService tenantService) public void setTenantService(TenantService tenantService)
{ {
this.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. * 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 // Apply the same validation that ACEGI would have to the user details - we may be going through a 'back
// door'. // door'.
if (!ud.isEnabled()) if (isDisabled(userId, ud))
{ {
throw new DisabledException("User is disabled"); 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() public Authentication setSystemUserAsCurrentUser()
{ {
return setSystemUserAsCurrentUser(TenantService.DEFAULT_DOMAIN); return setSystemUserAsCurrentUser(TenantService.DEFAULT_DOMAIN);

View File

@@ -1,32 +1,33 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.security.person; package org.alfresco.repo.security.person;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.UUID;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.batch.BatchProcessor; import org.alfresco.repo.batch.BatchProcessor;
@@ -41,7 +42,6 @@ import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.safehaus.uuid.UUID;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
/** /**
@@ -168,7 +168,7 @@ public class SplitPersonCleanupBootstrapBean extends AbstractLifecycleBean
try try
{ {
@SuppressWarnings("unused") @SuppressWarnings("unused")
UUID id = new UUID(guidString); UUID id = UUID.fromString(guidString);
// We have a valid guid. // We have a valid guid.
return true; return true;
} }
@@ -188,7 +188,7 @@ public class SplitPersonCleanupBootstrapBean extends AbstractLifecycleBean
try try
{ {
@SuppressWarnings("unused") @SuppressWarnings("unused")
UUID id = new UUID(guidString); UUID id = UUID.fromString(guidString);
// We have a valid guid. // We have a valid guid.
return true; return true;
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -256,11 +256,10 @@ public interface AuditService
/** /**
* Issue an audit query to retrieve min / max audit record id for a given application and properties * 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 * @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 * @return a map containing min/max and the associated value
*/ */
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters) default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
{ {
return -1; return -1;
} }

View File

@@ -274,6 +274,15 @@
<property name="tenantService"> <property name="tenantService">
<ref bean="tenantService" /> <ref bean="tenantService" />
</property> </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> </bean>
<!-- Simple Authentication component that rejects all authentication requests --> <!-- Simple Authentication component that rejects all authentication requests -->

View File

@@ -41,7 +41,7 @@
<property name="transactionService" ref="transactionService"/> <property name="transactionService" ref="transactionService"/>
<property name="personService" ref="personService"/> <property name="personService" ref="personService"/>
<property name="nodeResourceHelper" ref="nodeResourceHelper"/> <property name="nodeResourceHelper" ref="nodeResourceHelper"/>
<property name="eventSender" ref="#{ ${repo.event2.queue.skip} == true ? 'directEventSender' : 'enqueuingEventSender' }"/> <property name="eventSender" ref="eventSender"/>
<property name="nodeDAO" ref="nodeDAO"/> <property name="nodeDAO" ref="nodeDAO"/>
<property name="enabled" value="${repo.event2.enabled}"/> <property name="enabled" value="${repo.event2.enabled}"/>
</bean> </bean>
@@ -55,18 +55,17 @@
<property name="permissionService" ref="permissionService"/> <property name="permissionService" ref="permissionService"/>
</bean> </bean>
<bean id="baseEventSender" abstract="true">
<constructor-arg ref="event2MessageProducer"/>
<constructor-arg ref="eventAsyncEnqueueThreadPool"/>
<constructor-arg ref="eventAsyncDequeueThreadPool"/>
</bean>
<bean id="nodeResourceHelper" class="org.alfresco.repo.event2.NodeResourceHelper" parent="baseNodeResourceHelper"/> <bean id="nodeResourceHelper" class="org.alfresco.repo.event2.NodeResourceHelper" parent="baseNodeResourceHelper"/>
<bean id="eventGeneratorV2" class="org.alfresco.repo.event2.EventGenerator" parent="baseEventGeneratorV2"/> <bean id="eventGeneratorV2" class="org.alfresco.repo.event2.EventGenerator" parent="baseEventGeneratorV2"/>
<bean id="directEventSender" class="org.alfresco.repo.event2.DirectEventSender"> <bean id="eventSender" class="org.alfresco.repo.event2.EventSenderFactoryBean" autowire="constructor" parent="baseEventSender" />
<property name="event2MessageProducer" ref="event2MessageProducer"/>
</bean>
<bean id="enqueuingEventSender" class="org.alfresco.repo.event2.EnqueuingEventSender" parent="directEventSender" lazy-init="true">
<property name="enqueueThreadPoolExecutor" ref="eventAsyncEnqueueThreadPool"/>
<property name="dequeueThreadPoolExecutor" ref="eventAsyncDequeueThreadPool"/>
</bean>
<bean id="eventAsyncEnqueueThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean"> <bean id="eventAsyncEnqueueThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName"> <property name="poolName">

View File

@@ -782,6 +782,25 @@
<if test="ordered == true">order by node.id ASC</if> <if test="ordered == true">order by node.id ASC</if>
</select> </select>
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="result_NodeRef" >
select
node.id as id,
store.protocol as protocol,
store.identifier as identifier,
node.uuid as uuid
from
alf_node_aspects na
join alf_node node on (na.node_id = node.id)
left join alf_store store on (store.id = node.store_id)
where
<![CDATA[na.node_id >= #{idOne}]]>
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
and na.qname_id in
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
<if test="ordered == true">order by node.id ASC</if>
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
</select>
<!-- Common results for result_NodeAssoc --> <!-- Common results for result_NodeAssoc -->
<sql id="select_NodeAssoc_Results"> <sql id="select_NodeAssoc_Results">
select select

View File

@@ -121,6 +121,8 @@
<property name="maxItemBatchSize" value="${system.fixedACLsUpdater.maxItemBatchSize}"/> <property name="maxItemBatchSize" value="${system.fixedACLsUpdater.maxItemBatchSize}"/>
<property name="numThreads" value="${system.fixedACLsUpdater.numThreads}"/> <property name="numThreads" value="${system.fixedACLsUpdater.numThreads}"/>
<property name="forceSharedACL" value="${system.fixedACLsUpdater.forceSharedACL}"/> <property name="forceSharedACL" value="${system.fixedACLsUpdater.forceSharedACL}"/>
<property name="maxItems" value="${system.fixedACLsUpdater.maxItems}"/>
<property name="orderNodes" value="${system.fixedACLsUpdater.orderNodes}"/>
<property name="lockTimeToLive" value="${system.fixedACLsUpdater.lockTTL}"/> <property name="lockTimeToLive" value="${system.fixedACLsUpdater.lockTTL}"/>
<property name="policyComponent" ref="policyComponent"/> <property name="policyComponent" ref="policyComponent"/>
<property name="policyIgnoreUtil" ref="policyIgnoreUtil"/> <property name="policyIgnoreUtil" ref="policyIgnoreUtil"/>

View File

@@ -435,6 +435,9 @@ repo.remote.endpoint=/service
# persisted. # persisted.
create.missing.people=${server.transaction.allow-writes} create.missing.people=${server.transaction.allow-writes}
# Allow an immutable user to have its enabled status changed
allow.immutable.user.enabled.status.update=false
# Create home folders (unless disabled, see next property) as people are created (true) or create them lazily (false) # Create home folders (unless disabled, see next property) as people are created (true) or create them lazily (false)
home.folder.creation.eager=true home.folder.creation.eager=true
# Disable home folder creation - if true then home folders are not created (neither eagerly nor lazily) # Disable home folder creation - if true then home folders are not created (neither eagerly nor lazily)
@@ -1104,7 +1107,11 @@ system.fixedACLsUpdater.numThreads=4
# fixedACLsUpdater - Force shared ACL to propagate through children even if there is an unexpected ACL # fixedACLsUpdater - Force shared ACL to propagate through children even if there is an unexpected ACL
system.fixedACLsUpdater.forceSharedACL=false system.fixedACLsUpdater.forceSharedACL=false
# fixedACLsUpdater cron expression - fire at midnight every day # fixedACLsUpdater cron expression - fire at midnight every day
system.fixedACLsUpdater.cronExpression=0 0 0 * * ? system.fixedACLsUpdater.cronExpression=0 0 0 * * ?
# fixedACLsUpdater - maximum number of pending ACLs to process overall
system.fixedACLsUpdater.maxItems=-1
# fixedACLsUpdater - Impose the order by in the query. If false, it may not process all the results but should do the queries faster
system.fixedACLsUpdater.orderNodes=true
cmis.disable.hidden.leading.period.files=false cmis.disable.hidden.leading.period.files=false
@@ -1229,7 +1236,10 @@ repo.event2.filter.childAssocTypes=rn:rendition
repo.event2.filter.users= repo.event2.filter.users=
# Topic name # Topic name
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2 repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
# Specifies the strategy for sending the events
repo.event2.send.strategy=
# Specifies if messages should be enqueued in in-memory queue or sent directly to the topic # Specifies if messages should be enqueued in in-memory queue or sent directly to the topic
# Deprecated. Please use repo.event2.send.strategy
repo.event2.queue.skip=false repo.event2.queue.skip=false
#repo.event2.topic.endpoint=amqp:topic:VirtualTopic.alfresco.repo.event2 #repo.event2.topic.endpoint=amqp:topic:VirtualTopic.alfresco.repo.event2
# Thread pool for async enqueue of repo events # Thread pool for async enqueue of repo events

View File

@@ -44,11 +44,6 @@ import org.junit.runners.Suite;
@RunWith(Categories.class) @RunWith(Categories.class)
@Categories.ExcludeCategory({DBTests.class, NonBuildTests.class}) @Categories.ExcludeCategory({DBTests.class, NonBuildTests.class})
@Suite.SuiteClasses({ @Suite.SuiteClasses({
// Requires a running ActiveMQ
org.alfresco.repo.rawevents.EventBehaviourTest.class,
org.alfresco.repo.rawevents.TransactionAwareEventProducerTest.class,
org.alfresco.repo.event2.RepoEvent2ITSuite.class,
// Requires running transformers // Requires running transformers
org.alfresco.transform.registry.LocalTransformServiceRegistryConfigTest.class, org.alfresco.transform.registry.LocalTransformServiceRegistryConfigTest.class,
org.alfresco.repo.rendition2.RenditionService2IntegrationTest.class, org.alfresco.repo.rendition2.RenditionService2IntegrationTest.class,
@@ -71,7 +66,12 @@ import org.junit.runners.Suite;
org.alfresco.repo.blog.BlogServiceImplTest.class, org.alfresco.repo.blog.BlogServiceImplTest.class,
org.alfresco.repo.action.scheduled.ScheduledPersistedActionServiceTest.class, org.alfresco.repo.action.scheduled.ScheduledPersistedActionServiceTest.class,
org.alfresco.repo.rendition2.RenditionDefinitionTest.class org.alfresco.repo.rendition2.RenditionDefinitionTest.class,
// Requires a running ActiveMQ
org.alfresco.repo.rawevents.EventBehaviourTest.class,
org.alfresco.repo.rawevents.TransactionAwareEventProducerTest.class,
org.alfresco.repo.event2.RepoEvent2ITSuite.class,
}) })
public class AppContext06TestSuite public class AppContext06TestSuite
{ {

View File

@@ -104,9 +104,9 @@ public class FixedAclUpdaterTest
private ContentService contentService; private ContentService contentService;
private AuthorityService authorityService; private AuthorityService authorityService;
private static final long MAX_TRANSACTION_TIME_DEFAULT = 10; private static final long MAX_TRANSACTION_TIME_DEFAULT = 10;
private static final int LARGE_TRANSACTION_TIME = 86_400_000;
private static final int[] filesPerLevelMoreFolders = { 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; private static final int[] filesPerLevelMoreFolders = { 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
private static final int[] filesPerLevelMoreFiles = { 5, 100 }; private static final int[] filesPerLevelMoreFiles = { 5, 100 };
private long maxTransactionTime;
private static HashMap<Integer, Class<?>> errors; private static HashMap<Integer, Class<?>> errors;
private static String TEST_GROUP_NAME = "FixedACLUpdaterTest"; private static String TEST_GROUP_NAME = "FixedACLUpdaterTest";
private static String TEST_GROUP_NAME_FULL = PermissionService.GROUP_PREFIX + TEST_GROUP_NAME; private static String TEST_GROUP_NAME_FULL = PermissionService.GROUP_PREFIX + TEST_GROUP_NAME;
@@ -134,8 +134,11 @@ public class FixedAclUpdaterTest
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
homeFolderNodeRef = repository.getCompanyHome(); homeFolderNodeRef = repository.getCompanyHome();
maxTransactionTime = MAX_TRANSACTION_TIME_DEFAULT; setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, MAX_TRANSACTION_TIME_DEFAULT);
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
fixedAclUpdater.setForceSharedACL(false);
fixedAclUpdater.setMaxItems(-1);
fixedAclUpdater.setOrderNodes(true);
} }
@After @After
@@ -155,8 +158,7 @@ public class FixedAclUpdaterTest
try try
{ {
maxTransactionTime = 86400000; setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, LARGE_TRANSACTION_TIME);
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
setPermissionsOnTree(folderRef, false, false); setPermissionsOnTree(folderRef, false, false);
aclComparator.compareACLs(); aclComparator.compareACLs();
@@ -164,6 +166,7 @@ public class FixedAclUpdaterTest
} }
finally finally
{ {
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, MAX_TRANSACTION_TIME_DEFAULT);
deleteNodes(folderRef); deleteNodes(folderRef);
} }
} }
@@ -344,8 +347,7 @@ public class FixedAclUpdaterTest
try try
{ {
maxTransactionTime = 86400000; setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, LARGE_TRANSACTION_TIME);
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
// Set permissions on target folder // Set permissions on target folder
txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> { txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
@@ -386,6 +388,7 @@ public class FixedAclUpdaterTest
} }
finally finally
{ {
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, MAX_TRANSACTION_TIME_DEFAULT);
deleteNodes(originalRef); deleteNodes(originalRef);
deleteNodes(targetRefBase); deleteNodes(targetRefBase);
} }
@@ -1438,6 +1441,79 @@ public class FixedAclUpdaterTest
} }
} }
/*
* Test with maxItems limit
*/
@Test
@RetryAtMost(3)
public void testWithLimits()
{
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testWithLimitsFolder");
try
{
int maxItems = 200;
setPermissionsOnTree(folderRef, true, true);
// Get the current amount of pending ACls
int initialPendingAcls = getNodesCountWithPendingFixedAclAspect();
// We need at least maxItems+1 pending ACLs
while (initialPendingAcls <= maxItems && initialPendingAcls > 0)
{
// Trigger the job a single round each time to create new pendings until we have enough
triggerFixedACLJob(false,true,maxItems,1);
initialPendingAcls = getNodesCountWithPendingFixedAclAspect();
}
assertTrue("We don't have enough pending acls to test", initialPendingAcls > 0);
// Increase transaction time to not create new pending ACLs
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, LARGE_TRANSACTION_TIME);
// Trigger job in single round without timeout
triggerFixedACLJob(false,true,maxItems,1);
int finalPendingAcls = getNodesCountWithPendingFixedAclAspect();
assertTrue("Processed ACLs should not have exceeded 200", (initialPendingAcls - finalPendingAcls) <= maxItems);
}
finally
{
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, MAX_TRANSACTION_TIME_DEFAULT);
deleteNodes(folderRef);
}
}
/*
* Test without imposing the order by
*/
@Test
@RetryAtMost(3)
public void testUnordered()
{
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testWithLimitsFolder");
try
{
setPermissionsOnTree(folderRef, true, true);
int initialPendingAcls = getNodesCountWithPendingFixedAclAspect();
assertTrue("We don't have enough pending acls to test", initialPendingAcls > 0);
triggerFixedACLJob(false,true,-1,30);
int finalPendingAcls = getNodesCountWithPendingFixedAclAspect();
assertEquals("Not all ACls were processed",0, finalPendingAcls);
}
finally
{
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, MAX_TRANSACTION_TIME_DEFAULT);
deleteNodes(folderRef);
}
}
private Long getChild(Long parentId) private Long getChild(Long parentId)
{ {
List<FileInfo> children = fileFolderService.list(nodeDAO.getNodePair(parentId).getSecond()); List<FileInfo> children = fileFolderService.list(nodeDAO.getNodePair(parentId).getSecond());
@@ -1601,13 +1677,18 @@ public class FixedAclUpdaterTest
private void triggerFixedACLJob() private void triggerFixedACLJob()
{ {
triggerFixedACLJob(false); // Trigger job 30 times max to process all nodes
triggerFixedACLJob(false, true, -1, 30);
} }
private void triggerFixedACLJob(boolean forceSharedACL) private void triggerFixedACLJob(boolean forceSharedACL)
{
triggerFixedACLJob(forceSharedACL, true, -1, 30);
}
private void triggerFixedACLJob(boolean forceSharedACL, boolean orderNodes, int maxItems, int rounds)
{ {
LOG.debug("Fixing ACL"); LOG.debug("Fixing ACL");
final int rounds = 30;
final int enoughZeros = 3; final int enoughZeros = 3;
int numberOfConsecutiveZeros = 0; int numberOfConsecutiveZeros = 0;
@@ -1615,6 +1696,8 @@ public class FixedAclUpdaterTest
{ {
int count = txnHelper.doInTransaction(() -> { int count = txnHelper.doInTransaction(() -> {
fixedAclUpdater.setForceSharedACL(forceSharedACL); fixedAclUpdater.setForceSharedACL(forceSharedACL);
fixedAclUpdater.setMaxItems(maxItems);
fixedAclUpdater.setOrderNodes(orderNodes);
return fixedAclUpdater.execute(); return fixedAclUpdater.execute();
}, false, true); }, false, true);
numberOfConsecutiveZeros = count == 0 ? numberOfConsecutiveZeros + 1 : 0; numberOfConsecutiveZeros = count == 0 ? numberOfConsecutiveZeros + 1 : 0;

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -71,14 +71,14 @@ import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.test.context.TestPropertySource;
/** /**
* @author Iulian Aftene * @author Iulian Aftene
*/ */
@TestPropertySource(properties = {"repo.event2.queue.skip=false"})
public abstract class AbstractContextAwareRepoEvent extends BaseSpringTest public abstract class AbstractContextAwareRepoEvent extends BaseSpringTest
{ {
protected static final boolean DEBUG = false; protected static final boolean DEBUG = false;
@@ -123,9 +123,6 @@ public abstract class AbstractContextAwareRepoEvent extends BaseSpringTest
@Autowired @Autowired
private NamespaceDAO namespaceDAO; private NamespaceDAO namespaceDAO;
@Value("${repo.event2.queue.skip}")
protected boolean skipEventQueue;
protected NodeRef rootNodeRef; protected NodeRef rootNodeRef;
@BeforeClass @BeforeClass

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -25,78 +25,32 @@
*/ */
package org.alfresco.repo.event2; package org.alfresco.repo.event2;
import java.util.HashSet;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.test.context.TestPropertySource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
@ContextHierarchy({ import java.util.Collection;
// Context hierarchy inherits context config from parent classes and extends it with TestConfig from this class
@ContextConfiguration(classes = DirectEventGeneratorTest.TestConfig.class) @TestPropertySource(properties = {"repo.event2.queue.skip=true"})
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
public class DirectEventGeneratorTest extends EventGeneratorTest public class DirectEventGeneratorTest extends EventGeneratorTest
{ {
@Autowired @Autowired
private InstantiatedBeansRegistry instantiatedBeansRegistry; private EventSender eventSender;
@Autowired @Autowired
private EventSender directEventSender; private Collection<EventSender> allEventSenderBeans;
@BeforeClass
public static void beforeClass()
{
System.setProperty("repo.event2.queue.skip", "true");
}
@Test @Test
public void testIfEnqueuingEventSenderIsNotInstantiated() public void testIfOnlyRequiredEventSenderIsInstantiated()
{ {
final Set<String> instantiatedBeans = this.instantiatedBeansRegistry.getBeans(); assertEquals(1, allEventSenderBeans.size());
assertTrue(allEventSenderBeans.contains(eventSender));
assertTrue(skipEventQueue);
assertFalse(instantiatedBeans.contains("enqueuingEventSender"));
} }
@Test @Test
public void testIfDirectSenderIsSetInEventGenerator() public void testIfDirectSenderIsSetInEventGenerator()
{ {
assertTrue(skipEventQueue); assertEquals(DirectEventSender.class, eventSender.getClass());
assertEquals(directEventSender, eventGenerator.getEventSender()); assertEquals(eventSender, eventGenerator.getEventSender());
}
@Configuration
public static class TestConfig
{
@Bean
public BeanPostProcessor instantiatedBeansRegistry()
{
return new InstantiatedBeansRegistry();
}
}
protected static class InstantiatedBeansRegistry implements BeanPostProcessor
{
private final Set<String> registeredBeans = new HashSet<>();
@Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException
{
registeredBeans.add(beanName);
return bean;
}
public Set<String> getBeans() {
return registeredBeans;
}
} }
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -27,9 +27,9 @@ package org.alfresco.repo.event2;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource;
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) @TestPropertySource(properties = {"repo.event2.queue.skip=false"})
public class EnqueuingEventGeneratorTest extends EventGeneratorTest public class EnqueuingEventGeneratorTest extends EventGeneratorTest
{ {
@Autowired @Autowired
@@ -38,7 +38,7 @@ public class EnqueuingEventGeneratorTest extends EventGeneratorTest
@Test @Test
public void testIfEnqueuingSenderIsSetInEventGenerator() public void testIfEnqueuingSenderIsSetInEventGenerator()
{ {
assertFalse(skipEventQueue); assertEquals(EnqueuingEventSender.class, enqueuingEventSender.getClass());
assertEquals(enqueuingEventSender, eventGenerator.getEventSender()); assertEquals(enqueuingEventSender, eventGenerator.getEventSender());
} }
} }

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -65,15 +65,11 @@ public class EnqueuingEventSenderUnitTest
@Before @Before
public void setup() public void setup()
{ {
eventSender = new EnqueuingEventSender();
enqueuePool = newThreadPool();
eventSender.setEnqueueThreadPoolExecutor(enqueuePool);
dequeuePool = newThreadPool();
eventSender.setDequeueThreadPoolExecutor(dequeuePool);
bus = mock(Event2MessageProducer.class); bus = mock(Event2MessageProducer.class);
eventSender.setEvent2MessageProducer(bus); enqueuePool = newThreadPool();
dequeuePool = newThreadPool();
eventSender = new EnqueuingEventSender(bus, enqueuePool, dequeuePool);
eventSender.initialize();
events = new HashMap<>(); events = new HashMap<>();

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -49,7 +49,6 @@ import org.apache.activemq.command.ActiveMQTopic;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
public abstract class EventGeneratorTest extends AbstractContextAwareRepoEvent public abstract class EventGeneratorTest extends AbstractContextAwareRepoEvent
@@ -60,12 +59,6 @@ public abstract class EventGeneratorTest extends AbstractContextAwareRepoEvent
private ActiveMQConnection connection; private ActiveMQConnection connection;
protected List<RepoEvent<?>> receivedEvents; protected List<RepoEvent<?>> receivedEvents;
@BeforeClass
public static void beforeClass()
{
System.setProperty("repo.event2.queue.skip", "false");
}
@Before @Before
public void startupTopicListener() throws Exception public void startupTopicListener() throws Exception
{ {

View File

@@ -37,7 +37,10 @@ import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.UUID;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.UUIDUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.QuickShareModel; import org.alfresco.model.QuickShareModel;
import org.alfresco.repo.model.Repository; import org.alfresco.repo.model.Repository;
@@ -83,8 +86,6 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import org.junit.rules.RuleChain; import org.junit.rules.RuleChain;
import org.safehaus.uuid.UUID;
import org.safehaus.uuid.UUIDGenerator;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
/** /**
@@ -420,8 +421,8 @@ public class QuickShareServiceIntegrationTest
@Test(expected=InvalidSharedIdException.class) public void getMetadataFromShareIdWithInvalidId() @Test(expected=InvalidSharedIdException.class) public void getMetadataFromShareIdWithInvalidId()
{ {
UUID uuid = UUIDGenerator.getInstance().generateRandomBasedUUID(); UUID uuid = Generators.randomBasedGenerator().generate();
String sharedId = Base64.encodeBase64URLSafeString(uuid.toByteArray()); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw) String sharedId = Base64.encodeBase64URLSafeString(UUIDUtil.asByteArray(uuid)); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw)
Map<String, Object> metadata = quickShareService.getMetaData(sharedId); Map<String, Object> metadata = quickShareService.getMetaData(sharedId);
} }
@@ -884,7 +885,7 @@ public class QuickShareServiceIntegrationTest
{ {
// Create a private site // Create a private site
AuthenticationUtil.setFullyAuthenticatedUser(user1.getUsername()); AuthenticationUtil.setFullyAuthenticatedUser(user1.getUsername());
String randomUUID = UUIDGenerator.getInstance().generateRandomBasedUUID().toString(); String randomUUID = Generators.randomBasedGenerator().generate().toString();
String siteName = "testSite" + randomUUID; String siteName = "testSite" + randomUUID;
siteService.createSite("site-dashboard", siteName, "Title for " + siteName, siteService.createSite("site-dashboard", siteName, "Title for " + siteName,
"Description for " + siteName, SiteVisibility.PRIVATE); "Description for " + siteName, SiteVisibility.PRIVATE);