Merge branch 'master' of https://github.com/Alfresco/alfresco-community-repo into MNT-23926_add_sevenpass_dod_5220.22-M_ags_deletion

This commit is contained in:
Vedant Mehra
2025-02-27 13:30:42 +05:30
42 changed files with 9841 additions and 10542 deletions

View File

@@ -44,14 +44,14 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- id: changed-files
uses: Alfresco/alfresco-build-tools/.github/actions/github-list-changes@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/github-list-changes@v8.13.0
with:
write-list-to-env: true
- uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Prepare maven cache and check compilation"
@@ -69,12 +69,12 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/veracode@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/veracode@v8.13.0
continue-on-error: true
with:
srcclr-api-token: ${{ secrets.SRCCLR_API_TOKEN }}
@@ -92,10 +92,10 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/github-download-file@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/github-download-file@v8.13.0
with:
token: ${{ secrets.BOT_GITHUB_TOKEN }}
repository: "Alfresco/veracode-baseline-archive"
@@ -148,9 +148,9 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force]')
steps:
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- uses: Alfresco/ya-pmd-scan@v4.1.0
with:
classpath-build-command: "mvn test-compile -ntp -Pags -pl \"-:alfresco-community-repo-docker\""
@@ -181,14 +181,14 @@ jobs:
testAttributes: "-Dtest=AllMmtUnitTestSuite"
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testModule }}
@@ -219,7 +219,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -261,9 +261,9 @@ jobs:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
@@ -276,7 +276,7 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }}
@@ -307,7 +307,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -340,9 +340,9 @@ jobs:
version: ['10.5', '10.6']
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: Run MariaDB ${{ matrix.version }} database
@@ -351,7 +351,7 @@ jobs:
MARIADB_VERSION: ${{ matrix.version }}
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.version }}
@@ -382,7 +382,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -411,9 +411,9 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run MariaDB 10.11 database"
@@ -422,7 +422,7 @@ jobs:
MARIADB_VERSION: 10.11
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -453,7 +453,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -482,9 +482,9 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run MySQL 8 database"
@@ -493,7 +493,7 @@ jobs:
MYSQL_VERSION: 8
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -515,7 +515,7 @@ jobs:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.cj.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
@@ -524,7 +524,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -552,9 +552,9 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run PostgreSQL 14.15 database"
@@ -563,7 +563,7 @@ jobs:
POSTGRES_VERSION: 14.15
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -594,7 +594,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -622,9 +622,9 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run PostgreSQL 15.10 database"
@@ -633,7 +633,7 @@ jobs:
POSTGRES_VERSION: 15.10
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -664,7 +664,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -692,9 +692,9 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run PostgreSQL 16.6 database"
@@ -703,7 +703,7 @@ jobs:
POSTGRES_VERSION: 16.6
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -734,7 +734,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -760,16 +760,16 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run ActiveMQ"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile activemq up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -800,7 +800,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -860,9 +860,9 @@ jobs:
mvn-options: '-Dencryption.ssl.keystore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.keystore -Dencryption.ssl.truststore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.truststore'
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Set transformers tag"
@@ -885,7 +885,7 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }} ${{ matrix.idp }}
@@ -916,7 +916,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -974,9 +974,9 @@ jobs:
REQUIRES_LOCAL_IMAGES: true
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
@@ -992,7 +992,7 @@ jobs:
run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.test-name }}
@@ -1030,7 +1030,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.tests.outcome }}
@@ -1056,16 +1056,16 @@ jobs:
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Run Postgres 16.6 database"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -1096,7 +1096,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -1130,9 +1130,9 @@ jobs:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
@@ -1140,7 +1140,7 @@ jobs:
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (PostgreSQL) ${{ matrix.test-name }}
@@ -1176,9 +1176,9 @@ jobs:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
@@ -1186,7 +1186,7 @@ jobs:
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (MySQL) ${{ matrix.test-name }}
@@ -1218,9 +1218,9 @@ jobs:
REQUIRES_LOCAL_IMAGES: true
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
@@ -1234,7 +1234,7 @@ jobs:
mvn -B install -pl :alfresco-governance-services-automation-community-rest-api -am -Pags -Pall-tas-tests -DskipTests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.13.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
@@ -1266,7 +1266,7 @@ jobs:
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.2.0
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.13.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
@@ -1308,9 +1308,9 @@ jobs:
!contains(github.event.head_commit.message, '[force]')
steps:
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Build"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |

View File

@@ -34,12 +34,12 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.13.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}
@@ -63,12 +63,12 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.13.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.13.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.2.0
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.13.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}

View File

@@ -1377,7 +1377,7 @@
"filename": "repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java",
"hashed_secret": "d033e22ae348aeb5660fc2140aec35850c4da997",
"is_verified": false,
"line_number": 118,
"line_number": 116,
"is_secret": false
}
],
@@ -1431,26 +1431,6 @@
"is_secret": false
}
],
"repository/src/test/java/org/alfresco/repo/lock/LockBehaviourImplTest.java": [
{
"type": "Secret Keyword",
"filename": "repository/src/test/java/org/alfresco/repo/lock/LockBehaviourImplTest.java",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 112,
"is_secret": false
}
],
"repository/src/test/java/org/alfresco/repo/lock/LockServiceImplTest.java": [
{
"type": "Secret Keyword",
"filename": "repository/src/test/java/org/alfresco/repo/lock/LockServiceImplTest.java",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 103,
"is_secret": false
}
],
"repository/src/test/java/org/alfresco/repo/management/JmxDumpUtilTest.java": [
{
"type": "Secret Keyword",
@@ -1888,5 +1868,5 @@
}
]
},
"generated_at": "2024-12-19T08:58:42Z"
"generated_at": "2025-02-26T15:13:52Z"
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
</parent>
<dependencies>
@@ -145,6 +145,12 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${dependency.awaitility.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
* Copyright (C) 2005-2025 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,9 @@
*/
package org.alfresco.util;
import static org.awaitility.Awaitility.await;
import java.time.Duration;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
@@ -26,11 +29,10 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import junit.framework.TestCase;
/**
* Tests for our instance of {@link java.util.concurrent.ThreadPoolExecutor}
*
@@ -39,7 +41,8 @@ import junit.framework.TestCase;
public class DynamicallySizedThreadPoolExecutorTest extends TestCase
{
private static Log logger = LogFactory.getLog(DynamicallySizedThreadPoolExecutorTest.class);
private static final Duration MAX_WAIT_TIMEOUT = Duration.ofSeconds(1);
private static final Log logger = LogFactory.getLog(DynamicallySizedThreadPoolExecutorTest.class);
private static final int DEFAULT_KEEP_ALIVE_TIME = 90;
@Override
@@ -48,9 +51,9 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
SleepUntilAllWake.reset();
}
public void testUpToCore() throws Exception
public void testUpToCore()
{
DynamicallySizedThreadPoolExecutor exec = createInstance(5,10, DEFAULT_KEEP_ALIVE_TIME);
DynamicallySizedThreadPoolExecutor exec = createInstance(5, 10, DEFAULT_KEEP_ALIVE_TIME);
assertEquals(0, exec.getPoolSize());
exec.execute(new SleepUntilAllWake());
@@ -63,13 +66,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
assertEquals(5, exec.getPoolSize());
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
waitForPoolSizeEquals(exec, 5);
assertEquals(5, exec.getPoolSize());
}
public void testPastCoreButNotHugeQueue() throws Exception
public void testPastCoreButNotHugeQueue()
{
DynamicallySizedThreadPoolExecutor exec = createInstance(5,10, DEFAULT_KEEP_ALIVE_TIME);
DynamicallySizedThreadPoolExecutor exec = createInstance(5, 10, DEFAULT_KEEP_ALIVE_TIME);
assertEquals(0, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
@@ -96,13 +99,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
assertEquals(7, exec.getQueue().size());
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
waitForPoolSizeEquals(exec, 5);
assertEquals(5, exec.getPoolSize());
}
public void testToExpandQueue() throws Exception
{
DynamicallySizedThreadPoolExecutor exec = createInstance(2,4,1);
DynamicallySizedThreadPoolExecutor exec = createInstance(2, 4, 5);
assertEquals(0, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
@@ -119,13 +122,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
// Next should add one
exec.execute(new SleepUntilAllWake());
Thread.sleep(20); // Let the new thread spin up
waitForPoolSizeEquals(exec, 3); // Let the new thread spin up
assertEquals(3, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
// And again
exec.execute(new SleepUntilAllWake());
Thread.sleep(20); // Let the new thread spin up
waitForPoolSizeEquals(exec, 4); // Let the new thread spin up
assertEquals(4, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
@@ -139,139 +142,10 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
// All threads still running, as 1 second timeout
// All threads still running, as 5 second timeout
assertEquals(4, exec.getPoolSize());
}
public void offTestToExpandThenContract() throws Exception
{
DynamicallySizedThreadPoolExecutor exec = createInstance(2,4,1);
exec.setKeepAliveTime(30, TimeUnit.MILLISECONDS);
assertEquals(0, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
assertEquals(2, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
assertEquals(2, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
// Next should add one
exec.execute(new SleepUntilAllWake());
Thread.sleep(20); // Let the new thread spin up
assertEquals(3, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
// And again
exec.execute(new SleepUntilAllWake());
Thread.sleep(20); // Let the new thread spin up
assertEquals(4, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
// But no more will be added, as we're at max
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
assertEquals(4, exec.getPoolSize());
assertEquals(6, exec.getQueue().size());
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
// Wait longer than the timeout without any work, which should
// let all the extra threads go away
// (Depending on how closely your JVM follows the specification,
// we may fall back to the core size which is correct, or we
// may go to zero which is wrong, but hey, it's the JVM...)
logger.debug("Core pool size is " + exec.getCorePoolSize());
logger.debug("Current pool size is " + exec.getPoolSize());
logger.debug("Queue size is " + exec.getQueue().size());
assertTrue(
"Pool size should be 0-2 as everything is idle, was " + exec.getPoolSize(),
exec.getPoolSize() >= 0
);
assertTrue(
"Pool size should be 0-2 as everything is idle, was " + exec.getPoolSize(),
exec.getPoolSize() <= 2
);
SleepUntilAllWake.reset();
// Add 2 new jobs, will stay/ go to at 2 threads
assertEquals(0, exec.getQueue().size());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
// Let the idle threads grab them, then check
Thread.sleep(20);
assertEquals(2, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
// 3 more, still at 2 threads
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
assertEquals(2, exec.getPoolSize());
assertEquals(3, exec.getQueue().size());
// And again wait for it all
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
assertEquals(2, exec.getPoolSize());
// Now decrease the overall pool size
// Will rise and fall to there now
exec.setCorePoolSize(1);
// Run a quick job, to ensure that the
// "can I kill one yet" logic is applied
SleepUntilAllWake.reset();
exec.execute(new SleepUntilAllWake());
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
assertEquals(1, exec.getPoolSize());
assertEquals(0, exec.getQueue().size());
SleepUntilAllWake.reset();
// Push enough on to go up to 4 active threads
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
exec.execute(new SleepUntilAllWake());
Thread.sleep(20); // Let the new threads spin up
assertEquals(4, exec.getPoolSize());
assertEquals(6, exec.getQueue().size());
// Wait for them all to finish, should drop back to 1 now
// (Or zero, if your JVM can't read the specification...)
SleepUntilAllWake.wakeAll();
Thread.sleep(100);
assertTrue(
"Pool size should be 0 or 1 as everything is idle, was " + exec.getPoolSize(),
exec.getPoolSize() >= 0
);
assertTrue(
"Pool size should be 0 or 1 as everything is idle, was " + exec.getPoolSize(),
exec.getPoolSize() <= 1
);
}
private DynamicallySizedThreadPoolExecutor createInstance(int corePoolSize, int maximumPoolSize, int keepAliveTime)
{
// We need a thread factory
@@ -291,6 +165,11 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
new ThreadPoolExecutor.CallerRunsPolicy());
}
private void waitForPoolSizeEquals(DynamicallySizedThreadPoolExecutor exec, int expectedSize)
{
await().atMost(MAX_WAIT_TIMEOUT).until(() -> exec.getPoolSize() == expectedSize);
}
public static class SleepUntilAllWake implements Runnable
{
private static ConcurrentMap<String, Thread> sleeping = new ConcurrentHashMap<String, Thread>();
@@ -299,17 +178,18 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
@Override
public void run()
{
if(allAwake) return;
if (allAwake)
return;
// Track us, and wait for the bang
logger.debug("Adding thread: " + Thread.currentThread().getName());
sleeping.put(Thread.currentThread().getName(), Thread.currentThread());
try
{
Thread.sleep(30*1000);
Thread.sleep(30 * 1000);
System.err.println("Warning - Thread finished sleeping without wake!");
}
catch(InterruptedException e)
catch (InterruptedException e)
{
logger.debug("Interrupted thread: " + Thread.currentThread().getName());
}
@@ -318,12 +198,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
public static void wakeAll()
{
allAwake = true;
for(Entry<String, Thread> t : sleeping.entrySet())
for (Entry<String, Thread> t : sleeping.entrySet())
{
logger.debug("Interrupting thread: " + t.getKey());
t.getValue().interrupt();
}
}
public static void reset()
{
logger.debug("Resetting.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2023 Alfresco Software Limited.
* Copyright (C) 2005-2025 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -20,13 +20,11 @@ package org.alfresco.util.transaction;
import java.util.NoSuchElementException;
import java.util.Objects;
import jakarta.transaction.RollbackException;
import jakarta.transaction.Status;
import jakarta.transaction.UserTransaction;
import junit.framework.TestCase;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.TransactionDefinition;
@@ -35,9 +33,8 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
import org.springframework.transaction.support.DefaultTransactionStatus;
/**
* @see org.alfresco.util.transaction.SpringAwareUserTransaction
*
* @author Derek Hulley
* @see org.alfresco.util.transaction.SpringAwareUserTransaction
*/
public class SpringAwareUserTransactionTest extends TestCase
{
@@ -245,58 +242,6 @@ public class SpringAwareUserTransactionTest extends TestCase
checkNoStatusOnThread();
}
/**
* Test for leaked transactions (no guarantee it will succeed due to reliance
* on garbage collector), so disabled by default.
*
* Also, if it succeeds, transaction call stack tracing will be enabled
* potentially hitting the performance of all subsequent tests.
*
* @throws Exception
*/
public void xtestLeakedTransactionLogging() throws Exception
{
assertFalse(SpringAwareUserTransaction.isCallStackTraced());
TrxThread t1 = new TrxThread();
t1.start();
System.gc();
Thread.sleep(1000);
TrxThread t2 = new TrxThread();
t2.start();
System.gc();
Thread.sleep(1000);
assertTrue(SpringAwareUserTransaction.isCallStackTraced());
TrxThread t3 = new TrxThread();
t3.start();
System.gc();
Thread.sleep(3000);
System.gc();
Thread.sleep(3000);
}
private class TrxThread extends Thread
{
public void run()
{
try
{
getTrx();
}
catch (Exception e) {}
}
public void getTrx() throws Exception
{
UserTransaction txn = getTxn();
txn.begin();
txn = null;
}
}
public void testConnectionPoolException() throws Exception
{
testNoTxnStatus();

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
</parent>
<dependencies>

View File

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

View File

@@ -1,5 +1,5 @@
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux9@sha256:395664f9d9be0c9f73d3b722a58fd559ee7231609b263dfe19502617652740e3
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux9@sha256:9622418e142fb4fe1c5320666ad61ea292bc5c98f3dd0b550b6add33d18f659f
# Set default docker_context.
ARG resource_path=target

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
</parent>
<properties>

View File

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

View File

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

10
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -51,14 +51,14 @@
<dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.1.6</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.6</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>5.1.7-A.3</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.7-A.1</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
<dependency.spring.version>6.2.2</dependency.spring.version>
<dependency.spring-security.version>6.3.4</dependency.spring-security.version>
<dependency.spring-security.version>6.3.7</dependency.spring-security.version>
<dependency.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.17.2</dependency.jackson.version>
<dependency.cxf.version>4.1.0</dependency.cxf.version>
@@ -86,7 +86,7 @@
<dependency.poi.version>5.3.0</dependency.poi.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
<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.117.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
<dependency.netty.version>4.1.118.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
<dependency.activemq.version>5.18.6</dependency.activemq.version>
<dependency.apache-compress.version>1.27.1</dependency.apache-compress.version>
<dependency.awaitility.version>4.2.2</dependency.awaitility.version>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.49-SNAPSHOT</version>
<version>25.1.0.61-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -26,7 +26,12 @@
package org.alfresco.repo.action;
import static java.time.Duration.ofSeconds;
import static java.util.Objects.nonNull;
import static junit.framework.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -38,6 +43,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.ActionExecuter;
import org.alfresco.repo.action.executer.ContentMetadataExtracter;
@@ -64,12 +76,6 @@ import org.alfresco.util.test.junitrules.TemporaryNodes;
import org.alfresco.util.test.junitrules.TemporarySites;
import org.alfresco.util.test.junitrules.TemporarySites.TestSiteAndMemberInfo;
import org.alfresco.util.test.junitrules.WellKnownNodes;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
/**
* @author Jamal Kaabi-Mofrad
@@ -77,13 +83,13 @@ import org.junit.Test;
*/
public class ActionServiceImpl2Test
{
private static final int MAX_WAIT_TIMEOUT = 10;
// Rule to initialise the default Alfresco spring configuration
@ClassRule
public static ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
/**
* This JUnit rule will allow us to create Share sites and users and have
* them automatically cleaned up for us.
* This JUnit rule will allow us to create Share sites and users and have them automatically cleaned up for us.
*/
@Rule
public TemporarySites temporarySites = new TemporarySites(APP_CONTEXT_INIT);
@@ -107,8 +113,6 @@ public class ActionServiceImpl2Test
private NodeRef testNode;
@BeforeClass
public static void initStaticData() throws Exception
{
@@ -132,8 +136,7 @@ public class ActionServiceImpl2Test
SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName());
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
testNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
testNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
public NodeRef execute() throws Throwable
{
// get the Document Library NodeRef
@@ -150,8 +153,7 @@ public class ActionServiceImpl2Test
@Test
public void testIncrementCounterOnDeletedNode() throws Exception
{
final NodeRef deletedNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
final NodeRef deletedNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
public NodeRef execute() throws Throwable
{
// get the Document Library NodeRef
@@ -165,8 +167,7 @@ public class ActionServiceImpl2Test
});
// before the fix that would thrown an error
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
@@ -182,8 +183,7 @@ public class ActionServiceImpl2Test
{
// Set authentication to SiteManager.
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// add the cm:countable aspect and set the value to 1
@@ -200,8 +200,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteConsumer.
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
@@ -217,7 +216,7 @@ public class ActionServiceImpl2Test
assertEquals(2, afterIncrement);
}
@Test//(expected = AccessDeniedException.class)
@Test // (expected = AccessDeniedException.class)
public void testTransform() throws Exception
{
final File file = loadAndAddQuickFileAsManager(testNode, "quick.txt", MimetypeMap.MIMETYPE_TEXT_PLAIN);
@@ -225,8 +224,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteConsumer.
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
Action action = actionService.createAction(TransformActionExecuter.NAME);
@@ -269,8 +267,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteConsumer
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// Create the action
@@ -295,8 +292,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteManager
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// Create the action
@@ -312,16 +308,15 @@ public class ActionServiceImpl2Test
}
});
//Execute script not in Data Dictionary > Scripts
// Execute script not in Data Dictionary > Scripts
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
NodeRef companyHomeRef = wellKnownNodes.getCompanyHome();
NodeRef sharedFolderRef = nodeService.getChildByName(companyHomeRef, ContentModel.ASSOC_CONTAINS,
"Shared");
final NodeRef invalidScriptRef = addTempScript("changeFileNameTest.js",
"document.properties.name = \"Invalid_Change.pdf\";\ndocument.save();",sharedFolderRef);
"document.properties.name = \"Invalid_Change.pdf\";\ndocument.save();", sharedFolderRef);
assertNotNull("Failed to add the test script.", scriptToBeExecuted);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// Create the action
@@ -349,8 +344,7 @@ public class ActionServiceImpl2Test
public void testActionResult() throws Exception
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
try
@@ -389,8 +383,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteConsumer
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// Create the action
@@ -412,8 +405,7 @@ public class ActionServiceImpl2Test
// Set authentication to SiteCollaborator
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteCollaborator);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
// Create the action
@@ -424,24 +416,23 @@ public class ActionServiceImpl2Test
}
});
Thread.sleep(3000); // Need to wait for the async extract
// Need to wait for the async extract
await().atMost(ofSeconds(MAX_WAIT_TIMEOUT))
.until(() -> nonNull(getProperty(testNode, ContentModel.PROP_DESCRIPTION)));
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
assertEquals("Pangram, fox, dog, Gym class featuring a brown fox and lazy dog",
nodeService.getProperty(testNode, ContentModel.PROP_DESCRIPTION));
return null;
}
});
assertThat(getProperty(testNode, ContentModel.PROP_DESCRIPTION))
.isEqualTo("Pangram, fox, dog, Gym class featuring a brown fox and lazy dog");
}
private Serializable getProperty(NodeRef nodeRef, QName propertyName)
{
return transactionHelper.doInTransaction(() -> nodeService.getProperty(nodeRef, propertyName));
}
private NodeRef addTempScript(final String scriptFileName, final String javaScript, final NodeRef parentRef)
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
public NodeRef execute() throws Throwable
{
@@ -466,8 +457,7 @@ public class ActionServiceImpl2Test
private NodeRef addTempScript(final String scriptFileName, final String javaScript)
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
public NodeRef execute() throws Throwable
{
@@ -490,12 +480,14 @@ public class ActionServiceImpl2Test
{
final File file = AbstractContentTransformerTest.loadNamedQuickTestFile(quickFileName);
if (file == null) { return null; }
if (file == null)
{
return null;
}
// Set authentication to SiteManager and add a file
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, quickFileName);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -26,10 +26,16 @@
package org.alfresco.repo.action.evaluator;
import java.io.Serializable;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
@@ -54,10 +60,6 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
/**
* Compare property value evaluator test
@@ -99,9 +101,9 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
// Need to create model to contain our custom type
createTestModel();
this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
this.contentService = (ContentService)this.applicationContext.getBean("contentService");
actionService = (ActionService)applicationContext.getBean("actionService");
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
actionService = (ActionService) applicationContext.getBean("actionService");
// Create the store and get the root node
this.testStoreRef = this.nodeService.createStore(
@@ -111,11 +113,10 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
this.nodeValue = this.rootNodeRef;
this.beforeDateValue = new Date();
Thread.sleep(2000);
this.dateValue = new Date();
Thread.sleep(2000);
this.afterDateValue = new Date();
var now = Instant.now();
this.beforeDateValue = Date.from(now.minusSeconds(4));
this.dateValue = Date.from(now.minusSeconds(2));
this.afterDateValue = Date.from(now);
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(PROP_TEXT, TEXT_VALUE);
@@ -132,7 +133,7 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
TEST_TYPE_QNAME,
props).getChildRef();
this.evaluator = (ComparePropertyValueEvaluator)this.applicationContext.getBean(ComparePropertyValueEvaluator.NAME);
this.evaluator = (ComparePropertyValueEvaluator) this.applicationContext.getBean(ComparePropertyValueEvaluator.NAME);
}
@Test
@@ -226,11 +227,34 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
// Ensure other operators are invalid
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{
exception.printStackTrace();
}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
}
/**
@@ -309,11 +333,34 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
// Ensure other operators are invalid
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{
exception.printStackTrace();
}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
}
/**
@@ -388,13 +435,43 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
// Ensure other operators are invalid
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{
exception.printStackTrace();
}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
}
/**
@@ -447,19 +524,70 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
// Ensure other operators are invalid
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) { exception.printStackTrace();};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{
exception.printStackTrace();
}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
try
{
this.evaluator.evaluate(condition, this.nodeRef);
fail("An exception should have been raised here.");
}
catch (ActionServiceException exception)
{}
;
}
@@ -499,7 +627,6 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_VALUE, 2);
assertFalse(this.evaluator.evaluate(condition, this.nodeRef));
}
@Test

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -23,26 +23,23 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* Copyright (C) 2005 Jesper Steen M<>ller
*
* This file is part of Alfresco
*
* 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/>.
*/
package org.alfresco.repo.action.executer;
import static org.awaitility.Awaitility.await;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.test.context.transaction.TestTransaction;
import org.springframework.transaction.annotation.Transactional;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.content.MimetypeMap;
@@ -63,17 +60,6 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.test_category.BaseSpringTestsCategory;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.test.context.transaction.TestTransaction;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* Test of the ActionExecuter for extracting metadata.
@@ -108,7 +94,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
registry = (MetadataExtracterRegistry) applicationContext.getBean("metadataExtracterRegistry");
transactionService = (TransactionService) this.applicationContext.getBean("transactionService");
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
AuthenticationComponent authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
// Create the store and get the root node
@@ -146,7 +132,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
props.remove(ContentModel.PROP_AUTHOR);
props.put(ContentModel.PROP_TITLE, "");
props.put(ContentModel.PROP_DESCRIPTION, null); // Wonder how this will
// be handled
// be handled
this.nodeService.setProperties(this.nodeRef, props);
// Make the nodeRef visible to other transactions as it will need to be in async requests
@@ -154,8 +140,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
TestTransaction.end();
// Execute the action
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
@@ -164,11 +149,13 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
}
});
Thread.sleep(3000); // Need to wait for the async extract
// Need to wait for the async extract
await().pollInSameThread()
.atMost(MAX_ASYNC_TIMEOUT)
.until(() -> nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION), Objects::nonNull);
// Check that the properties have been set
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
assertEquals(QUICK_TITLE, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
@@ -181,6 +168,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
private static final QName PROP_UNKNOWN_1 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown1");
private static final QName PROP_UNKNOWN_2 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown2");
private static class TestUnknownMetadataExtracter extends AbstractMappingMetadataExtracter
{
public TestUnknownMetadataExtracter()
@@ -190,12 +178,14 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
mappingProperties.put("unknown2", PROP_UNKNOWN_2.toString());
setMappingProperties(mappingProperties);
}
@Override
protected Map<String, Set<QName>> getDefaultMapping()
{
// No need to give anything back as we have explicitly set the mapping already
return new HashMap<String, Set<QName>>(0);
}
@Override
public boolean isSupported(String sourceMimetype)
{
@@ -242,12 +232,14 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
mappingProperties.put("description", ContentModel.PROP_DESCRIPTION.toString());
setMappingProperties(mappingProperties);
}
@Override
protected Map<String, Set<QName>> getDefaultMapping()
{
// No need to give anything back as we have explicitly set the mapping already
return new HashMap<String, Set<QName>>(0);
}
@Override
public boolean isSupported(String sourceMimetype)
{
@@ -264,9 +256,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
}
/**
* Ensure that missing raw values result in node properties being removed
* when running with {@link ContentMetadataExtracter#setCarryAspectProperties(boolean)}
* set to <tt>false</tt>.
* Ensure that missing raw values result in node properties being removed when running with {@link ContentMetadataExtracter#setCarryAspectProperties(boolean)} set to <tt>false</tt>.
*/
@Test
public void testNullExtractedValues_ALF1823()
@@ -335,8 +325,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
TestTransaction.end();
// Execute the action
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
@@ -345,11 +334,13 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
}
});
Thread.sleep(3000); // Need to wait for the async extract
// Need to wait for the async extract
await().pollInSameThread()
.atMost(MAX_ASYNC_TIMEOUT)
.until(() -> nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION), Objects::nonNull);
// Check that the properties have been preserved, but that description has been set
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
assertEquals(myTitle, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,16 +25,27 @@
*/
package org.alfresco.repo.content.caching.cleanup;
import static org.junit.Assert.*;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
import org.alfresco.repo.content.caching.CacheFileProps;
import org.alfresco.repo.content.caching.CachingContentStore;
import org.alfresco.repo.content.caching.ContentCacheImpl;
@@ -43,12 +54,6 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.testing.category.LuceneTests;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
/**
* Tests for the CachedContentCleanupJob
@@ -58,22 +63,29 @@ import org.springframework.context.ApplicationContext;
@Category(LuceneTests.class)
public class CachedContentCleanupJobTest
{
private enum UrlSource { PROPS_FILE, REVERSE_CACHE_LOOKUP, NOT_PRESENT };
private static final Duration MAX_WAIT_TIMEOUT = Duration.ofSeconds(10);
private enum UrlSource
{
PROPS_FILE, REVERSE_CACHE_LOOKUP, NOT_PRESENT
}
;
private static ApplicationContext ctx;
private CachingContentStore cachingStore;
private ContentCacheImpl cache;
private File cacheRoot;
private CachedContentCleaner cleaner;
@BeforeClass
public static void beforeClass()
{
String cleanerConf = "classpath:cachingstore/test-cleaner-context.xml";
ctx = ApplicationContextHelper.getApplicationContext(new String[] { cleanerConf });
ctx = ApplicationContextHelper.getApplicationContext(new String[]{cleanerConf});
}
@Before
public void setUp() throws IOException
{
@@ -89,7 +101,6 @@ public class CachedContentCleanupJobTest
FileUtils.cleanDirectory(cacheRoot);
}
@Test
public void filesNotInCacheAreDeleted() throws InterruptedException
{
@@ -112,11 +123,9 @@ public class CachedContentCleanupJobTest
// Run cleaner
cleaner.execute();
Thread.sleep(400);
while (cleaner.isRunning())
{
Thread.sleep(200);
}
await().pollDelay(Duration.ofMillis(100))
.atMost(MAX_WAIT_TIMEOUT)
.until(() -> !cleaner.isRunning());
// check all files deleted
for (File file : files)
@@ -128,7 +137,6 @@ public class CachedContentCleanupJobTest
assertEquals("Incorrect total size of files deleted", totalSize, cleaner.getSizeFilesDeleted());
}
@Test
public void filesNewerThanMinFileAgeMillisAreNotDeleted() throws InterruptedException
{
@@ -154,21 +162,18 @@ public class CachedContentCleanupJobTest
newFilesTotalSize += newFiles[i].length();
}
// The cleaner must finish before any of the newFiles are older than minFileAge. If the files are too
// old the test will fail and it will be necessary to rethink how to test this.
cleaner.execute();
Thread.sleep(400);
while (cleaner.isRunning())
{
Thread.sleep(200);
}
await().pollDelay(Duration.ofMillis(100))
.atMost(MAX_WAIT_TIMEOUT)
.until(() -> !cleaner.isRunning());
if (cleaner.getDurationMillis() > minFileAge)
{
fail("Test unable to complete, since cleaner took " + cleaner.getDurationMillis() + "ms" +
" which is longer than minFileAge [" + minFileAge + "ms]");
" which is longer than minFileAge [" + minFileAge + "ms]");
}
// check all 'old' files deleted
@@ -224,14 +229,13 @@ public class CachedContentCleanupJobTest
}
}
// How many were definitely deleted?
assertEquals("Wrong number of files deleted", 7 , numDeleted);
assertEquals("Wrong number of files deleted", 7, numDeleted);
// The cleaner should have recorded the correct number of deletions
assertEquals("Incorrect number of deleted files", 7, cleaner.getNumFilesDeleted());
assertEquals("Incorrect total size of files deleted", sevenFilesSize, cleaner.getSizeFilesDeleted());
}
@Test
public void standardCleanAfterAggressiveFinished() throws InterruptedException
{
@@ -239,7 +243,6 @@ public class CachedContentCleanupJobTest
final int numFiles = 30;
File[] files = new File[numFiles];
for (int i = 0; i < numFiles; i++)
{
Calendar calendar = new GregorianCalendar(2010, 11, 2, 17, i);
@@ -286,7 +289,7 @@ public class CachedContentCleanupJobTest
}
}
assertEquals("Incorrect number of deleted files", 11, cleaner.getNumFilesDeleted());
assertEquals("Incorrect total size of files deleted", (11*fileSize), cleaner.getSizeFilesDeleted());
assertEquals("Incorrect total size of files deleted", (11 * fileSize), cleaner.getSizeFilesDeleted());
}
@Test
@@ -343,7 +346,6 @@ public class CachedContentCleanupJobTest
checkFilesDeleted(file);
}
private void checkFilesDeleted(File file)
{
assertFalse("File should have been deleted: " + file, file.exists());
@@ -351,7 +353,6 @@ public class CachedContentCleanupJobTest
assertFalse("Properties file should have been deleted, cache file: " + file, props.exists());
}
private void checkWatchCountForCacheFile(File file, Integer expectedWatchCount)
{
assertTrue("File should still exist: " + file, file.exists());
@@ -360,7 +361,6 @@ public class CachedContentCleanupJobTest
assertEquals("File should contain correct deleteWatchCount", expectedWatchCount, props.getDeleteWatchCount());
}
@Test
public void filesInCacheAreNotDeleted() throws InterruptedException
{
@@ -397,8 +397,8 @@ public class CachedContentCleanupJobTest
return createCacheFile(calendar, urlSource, putInCache);
}
private File createCacheFile(Calendar calendar, /*int year, int month, int day, int hour, int minute,*/
UrlSource urlSource, boolean putInCache)
private File createCacheFile(Calendar calendar, /* int year, int month, int day, int hour, int minute, */
UrlSource urlSource, boolean putInCache)
{
File file = new File(cacheRoot, createNewCacheFilePath(calendar));
file.getParentFile().mkdirs();
@@ -410,58 +410,55 @@ public class CachedContentCleanupJobTest
cache.putIntoLookup(Key.forUrl(contentUrl), file.getAbsolutePath());
}
switch(urlSource)
switch (urlSource)
{
case NOT_PRESENT:
// cache won't be able to determine original content URL for the file
break;
case PROPS_FILE:
// file with content URL in properties file
CacheFileProps props = new CacheFileProps(file);
props.setContentUrl(contentUrl);
props.store();
break;
case REVERSE_CACHE_LOOKUP:
// file with content URL in reverse lookup cache - but not 'in the cache' (forward lookup).
cache.putIntoLookup(Key.forCacheFile(file), contentUrl);
case NOT_PRESENT:
// cache won't be able to determine original content URL for the file
break;
case PROPS_FILE:
// file with content URL in properties file
CacheFileProps props = new CacheFileProps(file);
props.setContentUrl(contentUrl);
props.store();
break;
case REVERSE_CACHE_LOOKUP:
// file with content URL in reverse lookup cache - but not 'in the cache' (forward lookup).
cache.putIntoLookup(Key.forCacheFile(file), contentUrl);
}
assertTrue("File should exist", file.exists());
return file;
}
/**
* Mimick functionality of ContentCacheImpl.createNewCacheFilePath()
* but allowing a specific date (rather than 'now') to be used.
* Mimick functionality of ContentCacheImpl.createNewCacheFilePath() but allowing a specific date (rather than 'now') to be used.
*
* @param calendar Calendar
* @param calendar
* Calendar
* @return Path to use for cache file.
*/
private String createNewCacheFilePath(Calendar calendar)
{
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // 0-based
int month = calendar.get(Calendar.MONTH) + 1; // 0-based
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
// create the URL
StringBuilder sb = new StringBuilder(20);
sb.append(year).append('/')
.append(month).append('/')
.append(day).append('/')
.append(hour).append('/')
.append(minute).append('/')
.append(GUID.generate()).append(".bin");
.append(month).append('/')
.append(day).append('/')
.append(hour).append('/')
.append(minute).append('/')
.append(GUID.generate()).append(".bin");
return sb.toString();
}
private String makeContentUrl()
{
return "protocol://some/made/up/url/" + GUID.generate();
}
private void writeSampleContent(File file)
{
try

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,6 +25,8 @@
*/
package org.alfresco.repo.imap;
import static org.alfresco.model.ContentModel.PROP_MODIFIED;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
@@ -37,7 +39,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import jakarta.mail.Address;
import jakarta.mail.Folder;
import jakarta.mail.Message;
@@ -50,7 +51,24 @@ import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.internet.MimeUtility;
import jakarta.transaction.UserTransaction;
import com.sun.mail.iap.ProtocolException;
import com.sun.mail.iap.Response;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.protocol.BODY;
import com.sun.mail.imap.protocol.FetchResponse;
import com.sun.mail.imap.protocol.IMAPProtocol;
import com.sun.mail.imap.protocol.IMAPResponse;
import com.sun.mail.imap.protocol.RFC822DATA;
import com.sun.mail.imap.protocol.UID;
import com.sun.mail.util.ASCIIUtility;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.alfresco.model.ContentModel;
import org.alfresco.model.ImapModel;
@@ -83,26 +101,6 @@ import org.alfresco.util.PropertyMap;
import org.alfresco.util.config.RepositoryFolderConfigBean;
import org.alfresco.util.testing.category.LuceneTests;
import org.alfresco.util.testing.category.RedundantTests;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.MimeMessageHelper;
import com.sun.mail.iap.ProtocolException;
import com.sun.mail.iap.Response;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.protocol.BODY;
import com.sun.mail.imap.protocol.FetchResponse;
import com.sun.mail.imap.protocol.IMAPProtocol;
import com.sun.mail.imap.protocol.IMAPResponse;
import com.sun.mail.imap.protocol.RFC822DATA;
import com.sun.mail.imap.protocol.UID;
import com.sun.mail.util.ASCIIUtility;
import static org.alfresco.model.ContentModel.PROP_MODIFIED;
@Category({OwnJVMTestsCategory.class, LuceneTests.class})
public class ImapMessageTest extends TestCase
@@ -159,7 +157,6 @@ public class ImapMessageTest extends TestCase
namespaceService = serviceRegistry.getNamespaceService();
fileFolderService = serviceRegistry.getFileFolderService();
// start the transaction
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
@@ -200,7 +197,7 @@ public class ImapMessageTest extends TestCase
ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");
imapServer = (AlfrescoImapServer) imapCtx.getBean("imapServer");
if(!imapServer.isImapServerEnabled())
if (!imapServer.isImapServerEnabled())
{
imapServer.setImapServerEnabled(true);
imapServer.setHost(HOST);
@@ -220,7 +217,6 @@ public class ImapMessageTest extends TestCase
imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME);
imapServiceImpl.setImapHome(imapHome);
// Starting IMAP
imapServiceImpl.startupInTxn(true);
@@ -228,10 +224,7 @@ public class ImapMessageTest extends TestCase
namespaceService, false);
testImapFolderNodeRef = nodeRefs.get(0);
/*
* Importing test folders: Test folder contains: "___-___folder_a" "___-___folder_a" contains: "___-___folder_a_a", "___-___file_a", "Message_485.eml" (this is IMAP
* Message) "___-___folder_a_a" contains: "____-____file_a_a"
*/
/* Importing test folders: Test folder contains: "___-___folder_a" "___-___folder_a" contains: "___-___folder_a_a", "___-___file_a", "Message_485.eml" (this is IMAP Message) "___-___folder_a_a" contains: "____-____file_a_a" */
importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);
txn.commit();
@@ -243,7 +236,7 @@ public class ImapMessageTest extends TestCase
// Get the store
this.store = session.getStore(PROTOCOL);
//this.store.connect(HOST, PORT, anotherUserName, anotherUserName);
// this.store.connect(HOST, PORT, anotherUserName, anotherUserName);
this.store.connect(imapServer.getHost(), imapServer.getPort(), anotherUserName, anotherUserName);
// Get folder
@@ -349,8 +342,7 @@ public class ImapMessageTest extends TestCase
fail("Should raise an IOException");
}
catch (IOException e)
{
}
{}
}
public void dontTestMessageCache() throws Exception
@@ -411,8 +403,7 @@ public class ImapMessageTest extends TestCase
{
Locale.setDefault(Locale.FRENCH);
String dateStr = "12-Jul-2020";
final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand()
{
final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand() {
@Override
public Object doCommand(IMAPProtocol protocol)
{
@@ -445,8 +436,7 @@ public class ImapMessageTest extends TestCase
Locale.setDefault(Locale.FRENCH);
String dateStr = "12-juil.-2020";
final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand()
{
final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand() {
@Override
public Object doCommand(IMAPProtocol protocol)
{
@@ -512,7 +502,7 @@ public class ImapMessageTest extends TestCase
// InternetAddress.toString(new Address[] {address}) - is used in the RFC822MetadataExtracter
// So, compare with that
assertFalse("Non ASCII characters in the address should be encoded", decodedAddress.equals(InternetAddress.toString(new Address[] {address})));
assertFalse("Non ASCII characters in the address should be encoded", decodedAddress.equals(InternetAddress.toString(new Address[]{address})));
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
@@ -540,7 +530,7 @@ public class ImapMessageTest extends TestCase
// triggers a metadata extract to take place in a post commit method. Previously this would have been a
// synchronous process. This is no longer true as it may now take place in a T-Engine. So, we need to wait
// for the extract to take place. There does not
long end = System.currentTimeMillis()+10000;
long end = System.currentTimeMillis() + 10000;
while (System.currentTimeMillis() <= end && origModified.equals(getModified(nodeRef)))
{
Thread.currentThread().sleep(1000);
@@ -607,8 +597,6 @@ public class ImapMessageTest extends TestCase
lfolder.appendMessages(messages);
// The search is not implemented.
// SearchTerm term = new HeaderTerm("X-Alfresco-Unique", "test8bit");
// messages = folder.search(term);
@@ -619,14 +607,13 @@ public class ImapMessageTest extends TestCase
QueryParameterDefinition[] params = new QueryParameterDefinition[1];
params[0] = new QueryParameterDefImpl(
ContentModel.PROP_TITLE,
serviceRegistry.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
true,
subject);
ContentModel.PROP_TITLE,
serviceRegistry.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
true,
subject);
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, messageXPath, params, namespaceService, true);
// does the message exist
assertEquals(1, nodeRefs.size());
@@ -646,8 +633,10 @@ public class ImapMessageTest extends TestCase
}
finally
{
if (messageFileInputStream1 != null) messageFileInputStream1.close();
if (messageFileInputStream2 != null) messageFileInputStream2.close();
if (messageFileInputStream1 != null)
messageFileInputStream1.close();
if (messageFileInputStream2 != null)
messageFileInputStream2.close();
}
// close connection
@@ -656,11 +645,9 @@ public class ImapMessageTest extends TestCase
}
private static RFC822DATA getRFC822Message(final IMAPFolder folder, final long uid) throws MessagingException
{
return (RFC822DATA) folder.doCommand(new IMAPFolder.ProtocolCommand()
{
return (RFC822DATA) folder.doCommand(new IMAPFolder.ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException
{
Response[] r = p.command("UID FETCH " + uid + " (RFC822)", null);
@@ -681,17 +668,20 @@ public class ImapMessageTest extends TestCase
/**
* Returns BODY object containing desired message fragment
*
* @param folder Folder containing the message
* @param uid Message UID
* @param from starting byte
* @param count bytes to read
* @param folder
* Folder containing the message
* @param uid
* Message UID
* @param from
* starting byte
* @param count
* bytes to read
* @return BODY containing desired message fragment
* @throws MessagingException
*/
private static BODY getMessageBodyPart(IMAPFolder folder, final Long uid, final Integer from, final Integer count) throws MessagingException
{
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
{
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException
{
Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[]<" + from + "." + count + ">)", null);
@@ -715,7 +705,8 @@ public class ImapMessageTest extends TestCase
/**
* Finds node by its path
*
* @param path String
* @param path
* String
* @return NodeRef
*/
private NodeRef findNode(String path)
@@ -727,15 +718,16 @@ public class ImapMessageTest extends TestCase
/**
* Returns the UID of the first message in folder
*
* @param folder Folder containing the message
* @param msn message sequence number
* @param folder
* Folder containing the message
* @param msn
* message sequence number
* @return UID of the first message
* @throws MessagingException
*/
private static Long getMessageUid(IMAPFolder folder, final int msn) throws MessagingException
{
return (Long) folder.doCommand(new IMAPFolder.ProtocolCommand()
{
return (Long) folder.doCommand(new IMAPFolder.ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException
{
String command = "FETCH " + msn + " (UID)";
@@ -749,38 +741,37 @@ public class ImapMessageTest extends TestCase
throw new ProtocolException("Unable to retrieve message UID");
}
for(int i = 0 ; i < r.length; i++)
for (int i = 0; i < r.length; i++)
{
if(r[i] instanceof FetchResponse)
if (r[i] instanceof FetchResponse)
{
FetchResponse fetchResponse = (FetchResponse) r[0];
UID uid = (UID) fetchResponse.getItem(UID.class);
logger.debug("SECNUM=" + uid.seqnum + ", UID="+uid.uid);
logger.debug("SECNUM=" + uid.seqnum + ", UID=" + uid.uid);
return uid.uid;
}
}
/**
* Uh-oh - this is where we would intermittently fall over with a class cast exception.
* The following code probes why we don't have a FetchResponse
*/
* Uh-oh - this is where we would intermittently fall over with a class cast exception. The following code probes why we don't have a FetchResponse
*/
StringBuffer sb = new StringBuffer();
sb.append("command="+command);
sb.append("command=" + command);
sb.append('\n');
sb.append("resp length=" + r.length);
sb.append('\n');
for(int i = 0 ; i < r.length; i++)
for (int i = 0; i < r.length; i++)
{
logger.error(r[i]);
sb.append("class=" + r[i].getClass().getName());
IMAPResponse unexpected = (IMAPResponse)r[i];
IMAPResponse unexpected = (IMAPResponse) r[i];
sb.append("key=" + unexpected.getKey());
sb.append("number=" + unexpected.getNumber());
sb.append("rest=" + unexpected.getRest());
sb.append("r[" + i + "]=" + r[i] + '\n');
}
throw new ProtocolException("getMessageUid: "+ sb.toString());
throw new ProtocolException("getMessageUid: " + sb.toString());
}
});
}
@@ -788,8 +779,10 @@ public class ImapMessageTest extends TestCase
/**
* Returns size of the message
*
* @param folder Folder containing the message
* @param uid Message UID
* @param folder
* Folder containing the message
* @param uid
* Message UID
* @return Returns size of the message
* @throws MessagingException
*/
@@ -801,15 +794,16 @@ public class ImapMessageTest extends TestCase
/**
* Returns a full message body
*
* @param folder Folder containing the message
* @param uid Message UID
* @param folder
* Folder containing the message
* @param uid
* Message UID
* @return Returns size of the message
* @throws MessagingException
*/
private static BODY getMessageBody(IMAPFolder folder, final Long uid) throws MessagingException
{
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
{
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException
{
Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[])", null);
@@ -831,7 +825,8 @@ public class ImapMessageTest extends TestCase
/**
* Simple util for logging response
*
* @param r response
* @param r
* response
*/
private static void logResponse(Response[] r)
{

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,10 +25,19 @@
*/
package org.alfresco.repo.lock;
import static org.apache.commons.lang3.RandomStringUtils.secure;
import static org.awaitility.Awaitility.await;
import java.io.Serializable;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.transaction.annotation.Transactional;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.archive.NodeArchiveService;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
@@ -48,10 +57,6 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.test_category.OwnJVMTestsCategory;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.TestWithUserUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.transaction.annotation.Transactional;
/**
* LockBehaviourImpl Unit Test.
@@ -67,10 +72,10 @@ public class LockBehaviourImplTest extends BaseSpringTest
*/
private LockService lockService;
/**
* The version service
*/
private VersionService versionService;
/**
* The version service
*/
private VersionService versionService;
/**
* The node service
@@ -109,7 +114,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
/**
* User details
*/
private static final String PWD = "password";
private static final String PWD = secure().nextAlphabetic(10);
private static final String GOOD_USER_NAME = "goodUser";
private static final String BAD_USER_NAME = "badUser";
private static final String BAD_USER_WITH_ALL_PERMS_NAME = "badUserOwns";
@@ -119,16 +124,16 @@ public class LockBehaviourImplTest extends BaseSpringTest
@Before
public void before() throws Exception
{
this.nodeService = (NodeService)applicationContext.getBean("dbNodeService");
this.lockService = (LockService)applicationContext.getBean("lockService");
this.versionService = (VersionService)applicationContext.getBean("versionService");
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("authenticationService");
this.permissionService = (PermissionService)applicationContext.getBean("permissionService");
this.copyService = (CopyService)applicationContext.getBean("copyService");
this.nodeArchiveService = (NodeArchiveService)applicationContext.getBean("nodeArchiveService");
this.nodeService = (NodeService) applicationContext.getBean("dbNodeService");
this.lockService = (LockService) applicationContext.getBean("lockService");
this.versionService = (VersionService) applicationContext.getBean("versionService");
this.authenticationService = (MutableAuthenticationService) applicationContext.getBean("authenticationService");
this.permissionService = (PermissionService) applicationContext.getBean("permissionService");
this.copyService = (CopyService) applicationContext.getBean("copyService");
this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");
// Set the authentication
AuthenticationComponent authComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
AuthenticationComponent authComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
authComponent.setSystemUserAsCurrentUser();
// Create the node properties
@@ -144,7 +149,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
// Create node
this.nodeRef = this.nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}ParentNode"),
ContentModel.TYPE_FOLDER,
nodeProperties).getChildRef();
@@ -163,13 +168,13 @@ public class LockBehaviourImplTest extends BaseSpringTest
// Create a node with no lockAspect
this.noAspectNode = this.nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}noAspectNode"),
ContentModel.TYPE_CONTAINER,
nodeProperties).getChildRef();
assertNotNull(this.noAspectNode);
// Create the users
// Create the users
TestWithUserUtils.createUser(GOOD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
TestWithUserUtils.createUser(BAD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
TestWithUserUtils.createUser(BAD_USER_WITH_ALL_PERMS_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
@@ -292,7 +297,10 @@ public class LockBehaviourImplTest extends BaseSpringTest
assertTrue(lockService.isLocked(nodeRef));
assertTrue(lockService.isLockedAndReadOnly(nodeRef));
try {Thread.sleep(2*1000); } catch (Exception e) {};
await().pollInSameThread()
.pollDelay(Duration.ofMillis(500))
.atMost(MAX_ASYNC_TIMEOUT)
.until(() -> !lockService.isLocked(nodeRef));
// Should now have expired so the node should no longer appear to be locked
this.lockService.checkForLock(this.nodeRef);
@@ -370,66 +378,64 @@ public class LockBehaviourImplTest extends BaseSpringTest
}
}
/**
* Test that the node service lock behaviour is as we expect
*
*/
/**
* Test that the node service lock behaviour is as we expect
*/
@SuppressWarnings("unused")
public void testNodeServiceLockBehaviour()
{
public void testNodeServiceLockBehaviour()
{
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Check that we can create a new node and set of it properties when no lock is present
ChildAssociationRef childAssocRef = this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
NodeRef nodeRef = childAssocRef.getChildRef();
// Check that we can create a new node and set of it properties when no lock is present
ChildAssociationRef childAssocRef = this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
NodeRef nodeRef = childAssocRef.getChildRef();
// Lets lock the parent node and check that whether we can still create a new node
this.lockService.lock(this.nodeRef, LockType.WRITE_LOCK);
ChildAssociationRef childAssocRef2 = this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
NodeRef nodeRef2 = childAssocRef.getChildRef();
// Lets lock the parent node and check that whether we can still create a new node
this.lockService.lock(this.nodeRef, LockType.WRITE_LOCK);
ChildAssociationRef childAssocRef2 = this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
NodeRef nodeRef2 = childAssocRef.getChildRef();
// Lets check that we can do other stuff with the node since we have it locked
this.nodeService.setProperty(this.nodeRef, QName.createQName("{test}prop1"), "value1");
Map<QName, Serializable> propMap = new HashMap<QName, Serializable>();
propMap.put(QName.createQName("{test}prop2"), "value2");
this.nodeService.setProperties(this.nodeRef, propMap);
this.nodeService.removeAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE);
// TODO there are various other calls that could be more vigirously checked
// Lets check that we can do other stuff with the node since we have it locked
this.nodeService.setProperty(this.nodeRef, QName.createQName("{test}prop1"), "value1");
Map<QName, Serializable> propMap = new HashMap<QName, Serializable>();
propMap.put(QName.createQName("{test}prop2"), "value2");
this.nodeService.setProperties(this.nodeRef, propMap);
this.nodeService.removeAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE);
// TODO there are various other calls that could be more vigirously checked
// Lock the node as the 'bad' user
this.lockService.unlock(this.nodeRef);
// Lock the node as the 'bad' user
this.lockService.unlock(this.nodeRef);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
this.lockService.lock(this.nodeRef, LockType.WRITE_LOCK);
this.lockService.lock(this.nodeRef, LockType.WRITE_LOCK);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Lets check that we can't create a new child
try
{
this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
fail("The parent is locked so a new child should not have been created.");
}
catch(NodeLockedException exception)
{
}
// Lets check that we can't create a new child
try
{
this.nodeService.createNode(
this.nodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER);
fail("The parent is locked so a new child should not have been created.");
}
catch (NodeLockedException exception)
{}
// TODO various other tests along these lines ...
// TODO various other tests along these lines ...
// TODO check that delete is also working
}
// TODO check that delete is also working
}
/**
* ALF-5680: It is possible to cut/paste a locked file
@@ -453,20 +459,20 @@ public class LockBehaviourImplTest extends BaseSpringTest
// Create the new container that we'll move the node to.
NodeRef newParentRef = nodeService.createNode(
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
// Now the bad user will try to move the node.
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
try
{
nodeService.moveNode(
nodeRef,
newParentRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"));
nodeRef,
newParentRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"));
fail("Shouldn't have been able to move locked node.");
}
catch (NodeLockedException e)
@@ -506,17 +512,17 @@ public class LockBehaviourImplTest extends BaseSpringTest
// Create the new container that we'll move the node to.
NodeRef newParentRefToMove = nodeService.createNode(
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
// Create the new container that we'll copy the node to.
NodeRef newParentRefToCopy = nodeService.createNode(
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
try
{
@@ -544,10 +550,10 @@ public class LockBehaviourImplTest extends BaseSpringTest
// Create the new container that we'll copy the node to.
newParentRefToCopy = nodeService.createNode(
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
parentNode,
ContentModel.ASSOC_CONTAINS,
QName.createQName("{test}nodeServiceLockTest"),
ContentModel.TYPE_CONTAINER).getChildRef();
this.lockService.lock(nodeRef, LockType.WRITE_LOCK);
@@ -569,7 +575,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
}
catch (NodeLockedException e)
{
fail("Should not have any locks.");
fail("Should not have any locks.");
}
try
{
@@ -594,7 +600,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
{
// Try to restore archived node by Not Lock Owner
archivingBehaviorNodeRef = nodeService.restoreNode(archivedNode,
this.inSpaceStoreNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}nodeServiceLockTest"));
this.inSpaceStoreNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}nodeServiceLockTest"));
}
catch (Exception e)
{
@@ -610,7 +616,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
try
{
archivingBehaviorNodeRef = nodeService.restoreNode(archivedNode,
this.inSpaceStoreNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}nodeServiceLockTest"));
this.inSpaceStoreNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}nodeServiceLockTest"));
}
catch (Exception e)
{

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,16 +25,25 @@
*/
package org.alfresco.repo.lock;
import static org.apache.commons.lang3.RandomStringUtils.secure;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.Serializable;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.test.context.transaction.TestTransaction;
import org.springframework.transaction.annotation.Transactional;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.lock.mem.Lifetime;
import org.alfresco.repo.lock.mem.LockState;
@@ -66,11 +75,6 @@ import org.alfresco.test_category.BaseSpringTestsCategory;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.TestWithUserUtils;
import org.alfresco.util.testing.category.RedundantTests;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.test.context.transaction.TestTransaction;
import org.springframework.transaction.annotation.Transactional;
/**
* Simple lock service test
@@ -100,14 +104,13 @@ public class LockServiceImplTest extends BaseSpringTest
private static final String GOOD_USER_NAME = "goodUser";
private static final String BAD_USER_NAME = "badUser";
private static final String PWD = "password";
private static final String PWD = secure().nextAlphabetic(10);
NodeRef rootNodeRef;
private StoreRef storeRef;
private PolicyComponent policyComponent;
public class LockServicePoliciesImpl implements LockServicePolicies.BeforeLock,
LockServicePolicies.BeforeUnlock
{
@@ -131,24 +134,23 @@ public class LockServiceImplTest extends BaseSpringTest
}
}
@Before
public void before() throws Exception
{
this.nodeService = (NodeService)applicationContext.getBean("dbNodeService");
this.lockService = (LockService)applicationContext.getBean("lockService");
this.nodeService = (NodeService) applicationContext.getBean("dbNodeService");
this.lockService = (LockService) applicationContext.getBean("lockService");
this.securedLockService = (LockService)applicationContext.getBean("LockService");
this.securedLockService = (LockService) applicationContext.getBean("LockService");
PermissionService permissionService = (PermissionService) applicationContext.getBean("PermissionService");
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("authenticationService");
this.authenticationService = (MutableAuthenticationService) applicationContext.getBean("authenticationService");
CheckOutCheckInService cociService = (CheckOutCheckInService) applicationContext.getBean(
"checkOutCheckInService");
"checkOutCheckInService");
this.policyComponent = (PolicyComponent)applicationContext.getBean("policyComponent");
this.policyComponent = (PolicyComponent) applicationContext.getBean("policyComponent");
// Set the authentication
AuthenticationComponent authComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
AuthenticationComponent authComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
authComponent.setSystemUserAsCurrentUser();
// Create the node properties
@@ -164,7 +166,7 @@ public class LockServiceImplTest extends BaseSpringTest
// Create node
this.parentNode = this.nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}ParentNode"),
ContentModel.TYPE_CONTAINER,
nodeProperties).getChildRef();
@@ -177,7 +179,7 @@ public class LockServiceImplTest extends BaseSpringTest
// Add some children to the node
this.childNode1 = this.nodeService.createNode(
this.parentNode,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}ChildNode1"),
ContentModel.TYPE_CONTAINER,
nodeProperties).getChildRef();
@@ -185,7 +187,7 @@ public class LockServiceImplTest extends BaseSpringTest
assertNotNull("childNode1 should not be null", this.childNode1);
this.childNode2 = this.nodeService.createNode(
this.parentNode,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}ChildNode2"),
ContentModel.TYPE_CONTAINER,
nodeProperties).getChildRef();
@@ -195,7 +197,7 @@ public class LockServiceImplTest extends BaseSpringTest
// Create a node with no lockAspect
this.noAspectNode = this.nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{}noAspectNode"),
ContentModel.TYPE_CONTAINER,
nodeProperties).getChildRef();
@@ -216,8 +218,7 @@ public class LockServiceImplTest extends BaseSpringTest
assertTrue("checkedOutNode should have checked out aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_CHECKED_OUT));
assertTrue("checkedOutNode should have lockable aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_LOCKABLE));
// Create the users
// Create the users
TestWithUserUtils.createUser(GOOD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
TestWithUserUtils.createUser(BAD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
@@ -236,13 +237,11 @@ public class LockServiceImplTest extends BaseSpringTest
{
LockServicePoliciesImpl mockedLockServicePoliciesImpl = mock(LockServicePoliciesImpl.class);
BehaviourDefinition<ClassBehaviourBinding> lockDef =
this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeLock.QNAME, ContentModel.TYPE_BASE,
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeLock"));
BehaviourDefinition<ClassBehaviourBinding> lockDef = this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeLock.QNAME, ContentModel.TYPE_BASE,
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeLock"));
BehaviourDefinition<ClassBehaviourBinding> unlockDef =
this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeUnlock.QNAME, ContentModel.TYPE_BASE,
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeUnlock"));
BehaviourDefinition<ClassBehaviourBinding> unlockDef = this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeUnlock.QNAME, ContentModel.TYPE_BASE,
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeUnlock"));
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK);
@@ -305,7 +304,7 @@ public class LockServiceImplTest extends BaseSpringTest
}
catch (UnableToAquireLockException exception)
{
if(logger.isDebugEnabled())
if (logger.isDebugEnabled())
{
logger.debug(exception.getMessage());
}
@@ -443,8 +442,7 @@ public class LockServiceImplTest extends BaseSpringTest
{
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, authenticationService);
IndexerAndSearcher indexerAndSearcher = (IndexerAndSearcher)
applicationContext.getBean("indexerAndSearcherFactory");
IndexerAndSearcher indexerAndSearcher = (IndexerAndSearcher) applicationContext.getBean("indexerAndSearcherFactory");
SearcherComponent searcher = new SearcherComponent();
searcher.setIndexerAndSearcherFactory(indexerAndSearcher);
@@ -498,7 +496,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -510,7 +508,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -525,7 +523,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -537,7 +535,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -545,11 +543,11 @@ public class LockServiceImplTest extends BaseSpringTest
/* addAspect test */
try
{
fullNodeService.addAspect(noAspectNode, ContentModel.ASPECT_AUTHOR , null);
fullNodeService.addAspect(noAspectNode, ContentModel.ASPECT_AUTHOR, null);
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -561,7 +559,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -573,7 +571,7 @@ public class LockServiceImplTest extends BaseSpringTest
fail("node should be locked");
}
catch(NodeLockedException e)
catch (NodeLockedException e)
{
// it's ok - node supposed to be locked
}
@@ -591,7 +589,7 @@ public class LockServiceImplTest extends BaseSpringTest
@Test
public void testExpiredEphemeralLockAndPersistentLock()
{
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Check that the node is not currently locked
assertEquals("noAspectNode should not be locked", LockStatus.NO_LOCK, securedLockService.getLockStatus(noAspectNode));
@@ -611,8 +609,10 @@ public class LockServiceImplTest extends BaseSpringTest
assertEquals("retrieved lock lifetime should be ephemeral", Lifetime.EPHEMERAL, lockState.getLifetime());
assertNotNull("retrieved expire date should not be null", lockState.getExpires());
// Wait for 2 seconds to give the ephemeral lock time to expire
try {Thread.sleep(2*1000);} catch (Exception exception){}
// Wait to give the ephemeral lock time to expire
await().pollInSameThread()
.atMost(MAX_ASYNC_TIMEOUT)
.until(() -> !securedLockService.isLocked(noAspectNode));
assertFalse("noAspectNode should not be locked", securedLockService.isLocked(noAspectNode));
@@ -687,7 +687,7 @@ public class LockServiceImplTest extends BaseSpringTest
{
this.lockService.unlock(this.parentNode);
// This will pass in the open workd
//fail("A user cannot unlock a node that is currently lock by another user.");
// fail("A user cannot unlock a node that is currently lock by another user.");
}
catch (UnableToReleaseLockException exception)
{
@@ -710,7 +710,7 @@ public class LockServiceImplTest extends BaseSpringTest
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
assertEquals(
"parentNode should not be locked",
"parentNode should not be locked",
LockStatus.NO_LOCK,
this.lockService.getLockStatus(this.parentNode));
assertFalse("parentNode should not be locked", lockService.isLocked(parentNode));
@@ -947,8 +947,10 @@ public class LockServiceImplTest extends BaseSpringTest
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
// Wait for 2 second before re-testing the status
try {Thread.sleep(2*1000);} catch (Exception exception){}
// Wait for lock to expire before re-testing the status
await().pollInSameThread()
.pollDelay(Duration.ofMillis(500))
.atMost(MAX_ASYNC_TIMEOUT).until(() -> lockService.getLockStatus(parentNode), LockStatus.LOCK_EXPIRED::equals);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
@@ -981,8 +983,11 @@ public class LockServiceImplTest extends BaseSpringTest
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
// Wait for 2 second before re-testing the status
try {Thread.sleep(2*1000);} catch (Exception exception){}
// Wait for lock to expire before re-testing the status
await().pollInSameThread()
.pollDelay(Duration.ofMillis(500))
.atMost(MAX_ASYNC_TIMEOUT)
.until(() -> lockService.getLockStatus(parentNode), LockStatus.LOCK_EXPIRED::equals);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
@@ -997,7 +1002,7 @@ public class LockServiceImplTest extends BaseSpringTest
public void testEphemeralExpiryThreshold()
{
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
final int origThresh = ((LockServiceImpl)lockService).getEphemeralExpiryThreshold();
final int origThresh = ((LockServiceImpl) lockService).getEphemeralExpiryThreshold();
// Check the default situation is that the threshold does not apply.
assertEquals("threshold should not apply", LockServiceImpl.MAX_EPHEMERAL_LOCK_SECONDS, origThresh);
try
@@ -1034,102 +1039,94 @@ public class LockServiceImplTest extends BaseSpringTest
private void checkLifetimeForExpiry(Lifetime expectedLifetime, int expirySecs, Lifetime requestedLifetime)
{
lockService.unlock(parentNode);
assertNotEquals("lock status should not be locked", LockStatus.LOCKED ,lockService.getLockStatus(parentNode));
assertNotEquals("lock status should not be locked", LockStatus.LOCKED, lockService.getLockStatus(parentNode));
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, requestedLifetime);
LockState lock = lockService.getLockState(parentNode);
assertEquals("lock lifetime should be the same", expectedLifetime, lock.getLifetime());
// Check that for any timeouts we test, a request for a persistent lock always yields a persistent lock.
lockService.unlock(parentNode);
assertNotEquals("lock status should not be locked", LockStatus.LOCKED ,lockService.getLockStatus(parentNode));
assertNotEquals("lock status should not be locked", LockStatus.LOCKED, lockService.getLockStatus(parentNode));
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, Lifetime.PERSISTENT);
lock = lockService.getLockState(parentNode);
assertEquals("lock lifetime should be persistent", Lifetime.PERSISTENT, lock.getLifetime());
}
/**
* Unit test to validate the behaviour of creating children of locked nodes.
* No lock - can create children
* READ_ONLY_LOCK - can't create children
* WRITE_LOCK - owner can create children
* non owner can't create children
* NODE_LOCK non owner can create children
* owner can create children
* Unit test to validate the behaviour of creating children of locked nodes. No lock - can create children READ_ONLY_LOCK - can't create children WRITE_LOCK - owner can create children non owner can't create children NODE_LOCK non owner can create children owner can create children
*/
@Test
public void testCreateChildrenOfLockedNodes() throws Exception
{
/*
* Check we can create a child of an unlocked node.
*/
assertEquals(
"parent node should not be locked",
LockStatus.NO_LOCK,
this.lockService.getLockStatus(this.parentNode));
assertFalse("parent node should not be locked", lockService.isLocked(parentNode));
/* Check we can create a child of an unlocked node. */
assertEquals(
"parent node should not be locked",
LockStatus.NO_LOCK,
this.lockService.getLockStatus(this.parentNode));
assertFalse("parent node should not be locked", lockService.isLocked(parentNode));
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildA"), ContentModel.TYPE_FOLDER);
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildA"), ContentModel.TYPE_FOLDER);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK);
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK);
// Owner can create children
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildB"), ContentModel.TYPE_FOLDER);
// Owner can create children
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildB"), ContentModel.TYPE_FOLDER);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
try
{
// Non owner can't create children with a write lock in place
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildB"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
try
{
// Non owner can't create children with a write lock in place
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildB"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
this.lockService.lock(this.parentNode, LockType.NODE_LOCK);
this.lockService.lock(this.parentNode, LockType.NODE_LOCK);
// owner can create children with a node lock
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildD"), ContentModel.TYPE_FOLDER);
// owner can create children with a node lock
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildD"), ContentModel.TYPE_FOLDER);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Non owner can create children with a node lock
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildC"), ContentModel.TYPE_FOLDER);
// Non owner can create children with a node lock
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildC"), ContentModel.TYPE_FOLDER);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
this.lockService.lock(this.parentNode, LockType.READ_ONLY_LOCK);
this.lockService.lock(this.parentNode, LockType.READ_ONLY_LOCK);
// owner should not be able to create children with a READ_ONLY_LOCK
try
{
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildD"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
// owner should not be able to create children with a READ_ONLY_LOCK
try
{
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildD"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
TestWithUserUtils.authenticateUser(BAD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Non owner should not be able to create children with READ_ONLY_LOCK
try
{
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildE"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
// Non owner should not be able to create children with READ_ONLY_LOCK
try
{
nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("ChildE"), ContentModel.TYPE_FOLDER);
fail("could create a child with a read only lock");
}
catch (NodeLockedException e)
{
logger.debug("exception while trying to create a child of a read only lock", e);
}
}
/**
@@ -1163,8 +1160,7 @@ public class LockServiceImplTest extends BaseSpringTest
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
/* create node */
final NodeRef testNode =
this.nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{}testNode"), ContentModel.TYPE_CONTAINER).getChildRef();
final NodeRef testNode = this.nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{}testNode"), ContentModel.TYPE_CONTAINER).getChildRef();
// lock it as GOOD user
this.securedLockService.lock(testNode, LockType.WRITE_LOCK, 2 * 86400, lt, null);
@@ -1189,7 +1185,7 @@ public class LockServiceImplTest extends BaseSpringTest
this.securedLockService.unlock(testNode);
fail("BAD user shouldn't be able to unlock " + lt + " lock");
}
catch(AccessDeniedException e)
catch (AccessDeniedException e)
{
// expected exception
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,6 +25,8 @@
*/
package org.alfresco.util;
import java.time.Duration;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,10 +40,7 @@ import org.springframework.test.context.junit4.SpringRunner;
/**
* Base test class providing Hibernate sessions.
* <p>
* By default this is auto-wired by type. If a this is going to
* result in a conlict the use auto-wire by name. This can be done by
* setting populateProtectedVariables to true in the constructor and
* then adding protected members with the same name as the bean you require.
* By default this is auto-wired by type. If a this is going to result in a conlict the use auto-wire by name. This can be done by setting populateProtectedVariables to true in the constructor and then adding protected members with the same name as the bean you require.
*
* @author Derek Hulley
*/
@@ -50,6 +49,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@ContextCustomizerFactories(factories = {}, mergeMode = ContextCustomizerFactories.MergeMode.REPLACE_DEFAULTS)
public abstract class BaseSpringTest extends TestCase
{
protected static final Duration MAX_ASYNC_TIMEOUT = Duration.ofSeconds(10);
public Log logger = LogFactory.getLog(getClass().getName());
@Autowired