mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a12a31120d | ||
|
bf2e53344d | ||
|
aa4570c895 | ||
|
6e2e3f705f | ||
|
462625165f | ||
|
d341a3bab8 | ||
|
ecf658dd82 | ||
|
feba13d274 | ||
|
b2023bed63 | ||
|
2c1203f1f5 | ||
|
0edebd7df1 | ||
|
e059aa060a | ||
|
bd92569cec | ||
|
2b521fd5a7 | ||
|
1ecfa6c18e | ||
|
60eb7d2630 | ||
|
65a70c64c5 | ||
|
d23279227a |
184
.github/workflows/ci.yml
vendored
184
.github/workflows/ci.yml
vendored
@@ -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.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.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.16.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.16.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@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/veracode@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/veracode@v8.16.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@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/github-download-file@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/github-download-file@v8.16.0
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repository: "Alfresco/veracode-baseline-archive"
|
||||
@@ -142,9 +142,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@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- uses: Alfresco/ya-pmd-scan@v4.1.0
|
||||
with:
|
||||
classpath-build-command: "mvn test-compile -ntp -Pags -pl \"-:alfresco-community-repo-docker\""
|
||||
@@ -175,14 +175,14 @@ jobs:
|
||||
testAttributes: "-Dtest=AllMmtUnitTestSuite"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testModule }}
|
||||
@@ -213,7 +213,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -255,9 +255,9 @@ jobs:
|
||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
@@ -270,7 +270,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }}
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -334,9 +334,9 @@ jobs:
|
||||
version: ['10.2.18', '10.4', '10.5']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: Run MariaDB ${{ matrix.version }} database
|
||||
@@ -345,7 +345,7 @@ jobs:
|
||||
MARIADB_VERSION: ${{ matrix.version }}
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.version }}
|
||||
@@ -376,7 +376,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -405,9 +405,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run MariaDB 10.6 database"
|
||||
@@ -416,7 +416,7 @@ jobs:
|
||||
MARIADB_VERSION: 10.6
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -447,7 +447,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -476,9 +476,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run MySQL 8 database"
|
||||
@@ -487,7 +487,7 @@ jobs:
|
||||
MYSQL_VERSION: 8
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -518,7 +518,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -546,9 +546,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 13.12 database"
|
||||
@@ -557,7 +557,7 @@ jobs:
|
||||
POSTGRES_VERSION: 13.12
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -588,7 +588,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -616,9 +616,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 14.9 database"
|
||||
@@ -627,7 +627,7 @@ jobs:
|
||||
POSTGRES_VERSION: 14.9
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -658,7 +658,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -686,9 +686,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 15.4 database"
|
||||
@@ -697,7 +697,7 @@ jobs:
|
||||
POSTGRES_VERSION: 15.4
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -728,7 +728,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -754,16 +754,16 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -794,7 +794,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -854,9 +854,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@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Set transformers tag"
|
||||
@@ -879,7 +879,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }} ${{ matrix.idp }}
|
||||
@@ -910,7 +910,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -968,9 +968,9 @@ jobs:
|
||||
REQUIRES_LOCAL_IMAGES: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
@@ -986,7 +986,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.test-name }}
|
||||
@@ -1024,7 +1024,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.tests.outcome }}
|
||||
@@ -1050,16 +1050,16 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run Postgres 15.4 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -1090,7 +1090,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -1124,9 +1124,9 @@ jobs:
|
||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
@@ -1134,7 +1134,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (PostgreSQL) ${{ matrix.test-name }}
|
||||
@@ -1170,9 +1170,9 @@ jobs:
|
||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
@@ -1180,7 +1180,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (MySQL) ${{ matrix.test-name }}
|
||||
@@ -1212,9 +1212,9 @@ jobs:
|
||||
REQUIRES_LOCAL_IMAGES: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
@@ -1228,7 +1228,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@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
|
||||
id: rp-prepare
|
||||
with:
|
||||
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
|
||||
@@ -1260,7 +1260,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
- name: "Summarize Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v7.1.0
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
|
||||
id: rp-summarize
|
||||
with:
|
||||
tests-outcome: ${{ steps.run-tests.outcome }}
|
||||
@@ -1302,9 +1302,9 @@ jobs:
|
||||
!contains(github.event.head_commit.message, '[force]')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Build"
|
||||
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
|
||||
run: |
|
||||
|
16
.github/workflows/master_release.yml
vendored
16
.github/workflows/master_release.yml
vendored
@@ -34,12 +34,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.16.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@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v7.1.0
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.16.0
|
||||
with:
|
||||
username: ${{ env.GIT_USERNAME }}
|
||||
email: ${{ env.GIT_EMAIL }}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -33,14 +33,15 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO;
|
||||
import org.alfresco.repo.domain.propval.PropertyStringValueEntity;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO;
|
||||
import org.alfresco.repo.domain.propval.PropertyStringValueEntity;
|
||||
|
||||
/**
|
||||
* RM V3.3 Hold audit entries values patch unit test
|
||||
*
|
||||
@@ -55,7 +56,6 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
|
||||
@InjectMocks
|
||||
private RMv33HoldAuditEntryValuesPatch patch;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
@@ -93,15 +93,15 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
|
||||
verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity);
|
||||
|
||||
assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue());
|
||||
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringLower());
|
||||
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringEndLower());
|
||||
assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc());
|
||||
|
||||
assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue());
|
||||
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringLower());
|
||||
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringEndLower());
|
||||
assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc());
|
||||
|
||||
assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue());
|
||||
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringLower());
|
||||
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringEndLower());
|
||||
assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc());
|
||||
}
|
||||
|
||||
@@ -123,5 +123,3 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
|
||||
verify(mockedRecordsManagementQueryDAO, times(0)).updatePropertyStringValueEntity(any());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<!-- Resource defaultTransactionIsolation="-1" defaultAutoCommit="false" maxActive="100" initialSize="10" password="alfresco" username="alfresco" url="jdbc:mysql:///alfresco" driverClassName="org.gjt.mm.mysql.Driver" type="javax.sql.DataSource" auth="Container" name="jdbc/dataSource"/-->
|
||||
<Environment override="false" type="java.lang.Boolean" name="properties/startup.enable" description="A flag that globally enables or disables startup of the major Alfresco subsystems." value="true"/>
|
||||
<Environment override="false" type="java.lang.String" name="properties/dir.root" description="The filesystem directory below which content and index data is stored. Should be on a shared disk if this is a clustered installation."/>
|
||||
<Environment override="false" type="java.lang.String" name="properties/hibernate.dialect" description="The fully qualified name of a org.hibernate.dialect.Dialect subclass that allows Hibernate to generate SQL optimized for a particular relational database. Choose from org.hibernate.dialect.DerbyDialect, org.hibernate.dialect.MySQLInnoDBDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect, org.hibernate.dialect.PostgreSQLDialect"/>
|
||||
<Environment override="false" type="java.lang.String" name="properties/hibernate.dialect" description="The fully qualified name of a org.hibernate.dialect.Dialect subclass that allows Hibernate to generate SQL optimized for a particular relational database. Choose from org.hibernate.dialect.DerbyDialect, org.hibernate.dialect.MySQLInnoDBDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect, org.alfresco.repo.domain.hibernate.dialect.SQLServerDialect, org.hibernate.dialect.PostgreSQLDialect"/>
|
||||
<Environment override="false" type="java.lang.String" name="properties/hibernate.query.substitutions" description="Mapping from tokens in Hibernate queries to SQL tokens. For PostgreSQL, set this to "true TRUE, false FALSE"."/>
|
||||
<Environment override="false" type="java.lang.Boolean" name="properties/hibernate.jdbc.use_get_generated_keys" description="Enable use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve natively generated keys after insert. Requires JDBC3+ driver. Set to false if your driver has problems with the Hibernate identifier generators. By default, tries to determine the driver capabilities using connection metadata."/>
|
||||
<Environment override="false" type="java.lang.String" name="properties/hibernate.default_schema" description="Qualify unqualified table names with the given schema/tablespace in generated SQL. It may be necessary to set this when the target database has more than one schema."/>
|
||||
|
@@ -500,7 +500,7 @@
|
||||
org.hibernate.dialect.MySQLInnoDBDialect,
|
||||
org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect,
|
||||
org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect,
|
||||
org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect, org.hibernate.dialect.PostgreSQLDialect</description>
|
||||
org.alfresco.repo.domain.hibernate.dialect.SQLServerDialect, org.hibernate.dialect.PostgreSQLDialect</description>
|
||||
<env-entry-name>properties/hibernate.dialect</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value/> <!-- Empty value included for JBoss compatibility -->
|
||||
|
4
pom.xml
4
pom.xml
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||
<tag>23.5.0.1</tag>
|
||||
<tag>23.5.0.7</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
@@ -85,7 +85,7 @@ public class AuditImpl implements Audit
|
||||
|
||||
// list of equals filter's auditEntry (via where clause)
|
||||
private final static Set<String> LIST_AUDIT_ENTRY_EQUALS_QUERY_PROPERTIES = new HashSet<>(
|
||||
Arrays.asList(new String[] { CREATED_BY_USER, VALUES_KEY, VALUES_VALUE }));
|
||||
Arrays.asList(new String[]{CREATED_BY_USER, VALUES_KEY, VALUES_VALUE}));
|
||||
|
||||
// map of sort parameters for the moment one createdAt
|
||||
private final static Map<String, String> SORT_PARAMS_TO_NAMES;
|
||||
@@ -295,23 +295,29 @@ public class AuditImpl implements Audit
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasMoreItems) {
|
||||
if (q != null) {
|
||||
if (hasMoreItems)
|
||||
{
|
||||
if (q != null)
|
||||
{
|
||||
// filtering via "where" clause
|
||||
AuditEntryQueryWalker propertyWalker = new AuditEntryQueryWalker();
|
||||
QueryHelper.walk(q, propertyWalker);
|
||||
totalItems = getAuditEntriesCountByAppAndProperties(auditApplication, propertyWalker);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
totalItems = getAuditEntriesCountByApp(auditApplication);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
totalItems = totalRetrievedItems;
|
||||
}
|
||||
}
|
||||
|
||||
entriesAudit = (skipCount >= totalRetrievedItems)
|
||||
? Collections.emptyList()
|
||||
: entriesAudit.subList(skipCount, end);
|
||||
? Collections.emptyList()
|
||||
: entriesAudit.subList(skipCount, end);
|
||||
return CollectionWithPagingInfo.asPaged(paging, entriesAudit, hasMoreItems, totalItems);
|
||||
}
|
||||
|
||||
@@ -475,8 +481,7 @@ public class AuditImpl implements Audit
|
||||
final Map<String, UserInfo> mapUserInfo = new HashMap<>(10);
|
||||
|
||||
// create the callback for auditQuery method
|
||||
final AuditQueryCallback callback = new AuditQueryCallback()
|
||||
{
|
||||
final AuditQueryCallback callback = new AuditQueryCallback() {
|
||||
public boolean valuesRequired()
|
||||
{
|
||||
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
|
||||
@@ -532,7 +537,7 @@ public class AuditImpl implements Audit
|
||||
params.setApplicationName(auditApplication.getName());
|
||||
params.setFromId(auditEntryId);
|
||||
params.setToId(auditEntryId + 1);
|
||||
|
||||
|
||||
List<String> includeParam = new ArrayList<>();
|
||||
if (parameters != null)
|
||||
{
|
||||
@@ -545,8 +550,7 @@ public class AuditImpl implements Audit
|
||||
final List<AuditEntry> results = new ArrayList<>();
|
||||
|
||||
// create the callback for auditQuery method
|
||||
final AuditQueryCallback callback = new AuditQueryCallback()
|
||||
{
|
||||
final AuditQueryCallback callback = new AuditQueryCallback() {
|
||||
public boolean valuesRequired()
|
||||
{
|
||||
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
|
||||
@@ -710,8 +714,7 @@ public class AuditImpl implements Audit
|
||||
@Override
|
||||
public CollectionWithPagingInfo<AuditEntry> listAuditEntriesByNodeId(String nodeId, Parameters parameters)
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Void>() {
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
checkEnabled();
|
||||
@@ -772,8 +775,7 @@ public class AuditImpl implements Audit
|
||||
final List<AuditEntry> results = new ArrayList<>();
|
||||
|
||||
String auditAppId = "alfresco-access";
|
||||
String auditApplicationName = AuthenticationUtil.runAs(new RunAsWork<String>()
|
||||
{
|
||||
String auditApplicationName = AuthenticationUtil.runAs(new RunAsWork<String>() {
|
||||
public String doWork() throws Exception
|
||||
{
|
||||
return findAuditAppByIdOr404(auditAppId).getName();
|
||||
@@ -781,8 +783,7 @@ public class AuditImpl implements Audit
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
// create the callback for auditQuery method
|
||||
final AuditQueryCallback callback = new AuditQueryCallback()
|
||||
{
|
||||
final AuditQueryCallback callback = new AuditQueryCallback() {
|
||||
public boolean valuesRequired()
|
||||
{
|
||||
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
|
||||
@@ -808,8 +809,7 @@ public class AuditImpl implements Audit
|
||||
Long toTime = propertyWalker.getToTime();
|
||||
validateWhereBetween(nodeRef.getId(), fromTime, toTime);
|
||||
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>() {
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// QueryParameters
|
||||
@@ -820,7 +820,7 @@ public class AuditImpl implements Audit
|
||||
pathParams.setFromTime(fromTime);
|
||||
pathParams.setToTime(toTime);
|
||||
pathParams.setApplicationName(auditApplicationName);
|
||||
pathParams.addSearchKey("/"+auditAppId+"/transaction/path", nodePath);
|
||||
pathParams.addSearchKey("/" + auditAppId + "/transaction/path", nodePath);
|
||||
auditService.auditQuery(callback, pathParams, limit);
|
||||
|
||||
AuditQueryParameters copyFromPathParams = new AuditQueryParameters();
|
||||
@@ -830,7 +830,7 @@ public class AuditImpl implements Audit
|
||||
copyFromPathParams.setFromTime(fromTime);
|
||||
copyFromPathParams.setToTime(toTime);
|
||||
copyFromPathParams.setApplicationName(auditApplicationName);
|
||||
copyFromPathParams.addSearchKey("/"+auditAppId+"/transaction/copy/from/path", nodePath);
|
||||
copyFromPathParams.addSearchKey("/" + auditAppId + "/transaction/copy/from/path", nodePath);
|
||||
auditService.auditQuery(callback, copyFromPathParams, limit);
|
||||
|
||||
AuditQueryParameters moveFromPathParams = new AuditQueryParameters();
|
||||
@@ -840,7 +840,7 @@ public class AuditImpl implements Audit
|
||||
moveFromPathParams.setFromTime(fromTime);
|
||||
moveFromPathParams.setToTime(toTime);
|
||||
moveFromPathParams.setApplicationName(auditApplicationName);
|
||||
moveFromPathParams.addSearchKey("/"+auditAppId+"/transaction/move/from/path", nodePath);
|
||||
moveFromPathParams.addSearchKey("/" + auditAppId + "/transaction/move/from/path", nodePath);
|
||||
auditService.auditQuery(callback, moveFromPathParams, limit);
|
||||
|
||||
return null;
|
||||
@@ -857,7 +857,7 @@ public class AuditImpl implements Audit
|
||||
|
||||
public AuditEntriesByNodeIdQueryWalker()
|
||||
{
|
||||
super(new HashSet<>(Arrays.asList(new String[] { CREATED_BY_USER })), null);
|
||||
super(new HashSet<>(Arrays.asList(new String[]{CREATED_BY_USER})), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -909,14 +909,16 @@ public class AuditImpl implements Audit
|
||||
|
||||
public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker)
|
||||
{
|
||||
final String applicationName = auditApplication.getKey().substring(1);
|
||||
|
||||
AuditQueryParameters parameters = new AuditQueryParameters();
|
||||
parameters.setApplicationName(auditApplication.getName());
|
||||
parameters.setApplicationName(applicationName);
|
||||
parameters.setFromTime(propertyWalker.getFromTime());
|
||||
parameters.setToTime(propertyWalker.getToTime());
|
||||
parameters.setFromId(propertyWalker.getFromId());
|
||||
parameters.setToId(propertyWalker.getToId());
|
||||
parameters.setUser(propertyWalker.getCreatedByUser());
|
||||
|
||||
return auditService.getAuditEntriesCountByAppAndProperties(parameters);
|
||||
return auditService.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* 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
|
||||
@@ -212,7 +212,7 @@ public class ProcessesImplTest extends TestCase implements RecognizedParamsExtra
|
||||
{
|
||||
// the tests are always run on PostgreSQL only
|
||||
// Dialect dialect = (Dialect) applicationContext.getBean("dialect");
|
||||
// if (dialect instanceof AlfrescoSQLServerDialect)
|
||||
// if (dialect instanceof SQLServerDialect)
|
||||
// {
|
||||
// REPO-1104: we do not run this test on MS SQL server because it will fail
|
||||
// until the Activiti defect related to REPO-1104 will be fixed
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.5.0.1</version>
|
||||
<version>23.5.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,286 +1,282 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.audit.model.AuditApplication;
|
||||
import org.alfresco.repo.audit.model.AuditModelRegistry;
|
||||
import org.alfresco.repo.audit.model._3.AuditPath;
|
||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||
|
||||
/**
|
||||
* The audit component. Used by the AuditService and AuditMethodInterceptor to insert audit entries.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface AuditComponent
|
||||
{
|
||||
/**
|
||||
* Determines whether audit is globally enabled or disabled.
|
||||
*
|
||||
* @return Returns <code>true</code> if audit is enabled
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean isAuditEnabled();
|
||||
|
||||
/**
|
||||
* Switch auditing on or off
|
||||
*
|
||||
* @param enable <tt>true</tt> to enable auditing or <tt>false</tt> to disable
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public void setAuditEnabled(boolean enable);
|
||||
|
||||
/**
|
||||
* @param userAuditFilter UserAuditFilter
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
|
||||
|
||||
/**
|
||||
* Get all registered audit applications, whether active or not.
|
||||
*
|
||||
* @return Returns a map of registered audit applications keyed by name
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public Map<String, AuditApplication> getAuditApplications();
|
||||
|
||||
/**
|
||||
* Determine whether the audit infrastructure expects audit values to be passed in.
|
||||
* This is a helper method to allow optimizations in the client code. Reasons why
|
||||
* this method might return <tt>false</tt> are: auditing is disabled; no audit applications
|
||||
* have been registered. Sometimes, depending on the log level, this method may always
|
||||
* return <tt>true</tt>.
|
||||
*
|
||||
*
|
||||
* @return Returns <code>true</code> if the calling code (data producers)
|
||||
* should go ahead and generate the data for
|
||||
* {@link #recordAuditValues(String, Map) recording}.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean areAuditValuesRequired();
|
||||
|
||||
/**
|
||||
* Determines if audit values are required based on whether there are any audit applications
|
||||
* registered to record data for the given path. This helper method gives data producers a
|
||||
* shortcut in the event that nothing would be recorded in any event.
|
||||
*
|
||||
* @param path the audit path
|
||||
* @return Returns <tt>true</tt> if there is at least one audit application
|
||||
* registered to handle the given path.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public boolean areAuditValuesRequired(String path);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the given application and time range
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @param fromTime the start time of entries to remove (inclusive and optional)
|
||||
* @param toTime the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
int deleteAuditEntries(String applicationName, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the given application and id range
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @param fromId the start time of entries to remove (inclusive and optional)
|
||||
* @param toId the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int deleteAuditEntriesByIdRange(String applicationName, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries based on ID
|
||||
*
|
||||
* @param auditEntryIds the audit entry IDs to delete
|
||||
* @return Returns the number of entries deleted
|
||||
*/
|
||||
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* Check if an audit path is enabled. The path will be disabled if it or any higher
|
||||
* path has been explicitly disabled. Any disabled path will not be processed when
|
||||
* data is audited.
|
||||
*
|
||||
* @param applicationName the name of the application being logged to
|
||||
* @param path the audit path to check or <tt>null</tt> to assume the
|
||||
* application's root path
|
||||
* @return Returns <tt>true</tt> if the audit path has been disabled
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean isAuditPathEnabled(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Enable auditing (if it is not already enabled) for all paths that contain the given path.
|
||||
* The path is the path as originally logged and
|
||||
* not the path that the generated data may contain - although this would be similarly
|
||||
* enabled.
|
||||
* <p>
|
||||
* If the enabled
|
||||
*
|
||||
* @param applicationName the name of the application being logged to
|
||||
* @param path the audit path to check or <tt>null</tt> to assume the
|
||||
* application's root path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void enableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Disable auditing (if it is not already disabled) for all paths that contain the given path.
|
||||
* The path is the path as originally logged and
|
||||
* not the path that the generated data may contain - although this would be similarly
|
||||
* disabled.
|
||||
* <p>
|
||||
* If the path is <b>/x/y</b> then any data paths that start with <b>/x/y</b> will be stripped
|
||||
* out <u>before</u> data generators and data recorders are applied. If the path represents
|
||||
* the root path of the application, then auditing for that application is effectively disabled.
|
||||
*
|
||||
* @param applicationName the name of the application being logged to
|
||||
* @param path the audit path to check or <tt>null</tt> to assume the
|
||||
* application's root path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void disableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Remove all disabled paths i.e. enable all per-path based auditing. Auditing may still be
|
||||
* disabled globally. This is primarily for test purposes; applications should know which
|
||||
* paths need {@link #enableAudit(String, String) enabling} or
|
||||
* {@link #disableAudit(String, String) disabled}.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void resetDisabledPaths(String applicationName);
|
||||
|
||||
/**
|
||||
* Create an audit entry for the given map of values. The map key is a path - starting with '/'
|
||||
* ({@link AuditApplication#AUDIT_PATH_SEPARATOR}) - relative to the root path provided.
|
||||
* <p/>
|
||||
* The root path and value keys are combined to produce a map of data keyed by full path. This
|
||||
* fully-pathed map is then passed through the
|
||||
* {@link AuditModelRegistry#getAuditPathMapper() audit path mapper}. The result may yield data
|
||||
* destined for several different
|
||||
* {@link AuditModelRegistry#getAuditApplicationByKey(String) audit applications}. depending on
|
||||
* the data extraction and generation defined in the applications, values (or derived values) may
|
||||
* be recorded against several audit entries (one per application represented).
|
||||
* <p/>
|
||||
* The return values reflect what was actually persisted and is controlled by the data extractors
|
||||
* defined in the audit configuration.
|
||||
* <p/>
|
||||
* A new read-write transaction is started if there are values to write that there is not a viable
|
||||
* transaction present.
|
||||
*
|
||||
* @param rootPath a base path of {@link AuditPath} key entries concatenated with the path separator
|
||||
* '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR})
|
||||
* @param values the values to audit mapped by {@link AuditPath} key relative to root path
|
||||
* (may be <tt>null</tt>)
|
||||
* @return Returns the values that were actually persisted, keyed by their full path.
|
||||
* @throws IllegalStateException if the transaction state could not be determined
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
Map<String, Serializable> recordAuditValues(String rootPath, Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* The same as {@link AuditComponent#recordAuditValues(String, Map)}, but with controlled usage of userFilter
|
||||
*
|
||||
* @param rootPath a base path of {@link AuditPath} key entries concatenated with the path separator
|
||||
* '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR})
|
||||
* @param values the values to audit mapped by {@link AuditPath} key relative to root path
|
||||
* (may be <tt>null</tt>)
|
||||
* @param useUserFilter if <tt>false</tt> the user filter is disabled.
|
||||
* @return Returns the values that were actually persisted, keyed by their full path.
|
||||
* @throws IllegalStateException if the transaction state could not be determined
|
||||
*/
|
||||
Map<String, Serializable> recordAuditValuesWithUserFilter(String rootPath, Map<String, Serializable> values, boolean useUserFilter);
|
||||
|
||||
/**
|
||||
* Find audit entries using the given parameters
|
||||
*
|
||||
* @param callback the data callback per entry
|
||||
* @param parameters the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException if maxResults less or equal to zero
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @param extremes a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application and properties
|
||||
*
|
||||
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.audit.model.AuditApplication;
|
||||
import org.alfresco.repo.audit.model.AuditModelRegistry;
|
||||
import org.alfresco.repo.audit.model._3.AuditPath;
|
||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||
|
||||
/**
|
||||
* The audit component. Used by the AuditService and AuditMethodInterceptor to insert audit entries.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface AuditComponent
|
||||
{
|
||||
/**
|
||||
* Determines whether audit is globally enabled or disabled.
|
||||
*
|
||||
* @return Returns <code>true</code> if audit is enabled
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean isAuditEnabled();
|
||||
|
||||
/**
|
||||
* Switch auditing on or off
|
||||
*
|
||||
* @param enable
|
||||
* <tt>true</tt> to enable auditing or <tt>false</tt> to disable
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public void setAuditEnabled(boolean enable);
|
||||
|
||||
/**
|
||||
* @param userAuditFilter
|
||||
* UserAuditFilter
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
|
||||
|
||||
/**
|
||||
* Get all registered audit applications, whether active or not.
|
||||
*
|
||||
* @return Returns a map of registered audit applications keyed by name
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public Map<String, AuditApplication> getAuditApplications();
|
||||
|
||||
/**
|
||||
* Determine whether the audit infrastructure expects audit values to be passed in. This is a helper method to allow optimizations in the client code. Reasons why this method might return <tt>false</tt> are: auditing is disabled; no audit applications have been registered. Sometimes, depending on the log level, this method may always return <tt>true</tt>.
|
||||
*
|
||||
*
|
||||
* @return Returns <code>true</code> if the calling code (data producers) should go ahead and generate the data for {@link #recordAuditValues(String, Map) recording}.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean areAuditValuesRequired();
|
||||
|
||||
/**
|
||||
* Determines if audit values are required based on whether there are any audit applications registered to record data for the given path. This helper method gives data producers a shortcut in the event that nothing would be recorded in any event.
|
||||
*
|
||||
* @param path
|
||||
* the audit path
|
||||
* @return Returns <tt>true</tt> if there is at least one audit application registered to handle the given path.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public boolean areAuditValuesRequired(String path);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the given application and time range
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param fromTime
|
||||
* the start time of entries to remove (inclusive and optional)
|
||||
* @param toTime
|
||||
* the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
int deleteAuditEntries(String applicationName, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the given application and id range
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param fromId
|
||||
* the start time of entries to remove (inclusive and optional)
|
||||
* @param toId
|
||||
* the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int deleteAuditEntriesByIdRange(String applicationName, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries based on ID
|
||||
*
|
||||
* @param auditEntryIds
|
||||
* the audit entry IDs to delete
|
||||
* @return Returns the number of entries deleted
|
||||
*/
|
||||
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* Check if an audit path is enabled. The path will be disabled if it or any higher path has been explicitly disabled. Any disabled path will not be processed when data is audited.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application being logged to
|
||||
* @param path
|
||||
* the audit path to check or <tt>null</tt> to assume the application's root path
|
||||
* @return Returns <tt>true</tt> if the audit path has been disabled
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean isAuditPathEnabled(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Enable auditing (if it is not already enabled) for all paths that contain the given path. The path is the path as originally logged and not the path that the generated data may contain - although this would be similarly enabled.
|
||||
* <p>
|
||||
* If the enabled
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application being logged to
|
||||
* @param path
|
||||
* the audit path to check or <tt>null</tt> to assume the application's root path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void enableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Disable auditing (if it is not already disabled) for all paths that contain the given path. The path is the path as originally logged and not the path that the generated data may contain - although this would be similarly disabled.
|
||||
* <p>
|
||||
* If the path is <b>/x/y</b> then any data paths that start with <b>/x/y</b> will be stripped out <u>before</u> data generators and data recorders are applied. If the path represents the root path of the application, then auditing for that application is effectively disabled.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application being logged to
|
||||
* @param path
|
||||
* the audit path to check or <tt>null</tt> to assume the application's root path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void disableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Remove all disabled paths i.e. enable all per-path based auditing. Auditing may still be disabled globally. This is primarily for test purposes; applications should know which paths need {@link #enableAudit(String, String) enabling} or {@link #disableAudit(String, String) disabled}.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void resetDisabledPaths(String applicationName);
|
||||
|
||||
/**
|
||||
* Create an audit entry for the given map of values. The map key is a path - starting with '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR}) - relative to the root path provided.
|
||||
* <p/>
|
||||
* The root path and value keys are combined to produce a map of data keyed by full path. This fully-pathed map is then passed through the {@link AuditModelRegistry#getAuditPathMapper() audit path mapper}. The result may yield data destined for several different {@link AuditModelRegistry#getAuditApplicationByKey(String) audit applications}. depending on the data extraction and generation defined in the applications, values (or derived values) may be recorded against several audit entries (one per application represented).
|
||||
* <p/>
|
||||
* The return values reflect what was actually persisted and is controlled by the data extractors defined in the audit configuration.
|
||||
* <p/>
|
||||
* A new read-write transaction is started if there are values to write that there is not a viable transaction present.
|
||||
*
|
||||
* @param rootPath
|
||||
* a base path of {@link AuditPath} key entries concatenated with the path separator '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR})
|
||||
* @param values
|
||||
* the values to audit mapped by {@link AuditPath} key relative to root path (may be <tt>null</tt>)
|
||||
* @return Returns the values that were actually persisted, keyed by their full path.
|
||||
* @throws IllegalStateException
|
||||
* if the transaction state could not be determined
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
Map<String, Serializable> recordAuditValues(String rootPath, Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* The same as {@link AuditComponent#recordAuditValues(String, Map)}, but with controlled usage of userFilter
|
||||
*
|
||||
* @param rootPath
|
||||
* a base path of {@link AuditPath} key entries concatenated with the path separator '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR})
|
||||
* @param values
|
||||
* the values to audit mapped by {@link AuditPath} key relative to root path (may be <tt>null</tt>)
|
||||
* @param useUserFilter
|
||||
* if <tt>false</tt> the user filter is disabled.
|
||||
* @return Returns the values that were actually persisted, keyed by their full path.
|
||||
* @throws IllegalStateException
|
||||
* if the transaction state could not be determined
|
||||
*/
|
||||
Map<String, Serializable> recordAuditValuesWithUserFilter(String rootPath, Map<String, Serializable> values, boolean useUserFilter);
|
||||
|
||||
/**
|
||||
* Find audit entries using the given parameters
|
||||
*
|
||||
* @param callback
|
||||
* the data callback per entry
|
||||
* @param parameters
|
||||
* the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults
|
||||
* the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if maxResults less or equal to zero
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param extremes
|
||||
* a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application and properties
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param parameters
|
||||
* audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,197 +1,209 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||
import org.alfresco.service.cmr.audit.AuditService;
|
||||
|
||||
/**
|
||||
* The implementation of the AuditService for application auditing.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AuditServiceImpl implements AuditService
|
||||
{
|
||||
private AuditComponent auditComponent;
|
||||
|
||||
public AuditServiceImpl()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public void setAuditComponent(AuditComponent auditComponent)
|
||||
{
|
||||
this.auditComponent = auditComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.4
|
||||
*/
|
||||
public boolean isAuditEnabled()
|
||||
{
|
||||
return auditComponent.isAuditEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public void setAuditEnabled(boolean enable)
|
||||
{
|
||||
auditComponent.setAuditEnabled(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public Map<String, AuditApplication> getAuditApplications()
|
||||
{
|
||||
Map<String, org.alfresco.repo.audit.model.AuditApplication> apps = auditComponent.getAuditApplications();
|
||||
|
||||
Map<String, AuditApplication> ret = new TreeMap<String, AuditApplication>();
|
||||
for (String app : apps.keySet())
|
||||
{
|
||||
String name = app;
|
||||
String key = org.alfresco.repo.audit.model.AuditApplication.AUDIT_PATH_SEPARATOR + apps.get(app).getApplicationKey();
|
||||
boolean enabled = auditComponent.isAuditPathEnabled(app, key);
|
||||
AuditApplication auditApplication = new AuditApplication(name, key, enabled);
|
||||
ret.put(name, auditApplication);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.2
|
||||
*/
|
||||
public boolean isAuditEnabled(String applicationName, String path)
|
||||
{
|
||||
return auditComponent.isAuditPathEnabled(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.2
|
||||
*/
|
||||
public void enableAudit(String applicationName, String path)
|
||||
{
|
||||
auditComponent.enableAudit(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.2
|
||||
*/
|
||||
public void disableAudit(String applicationName, String path)
|
||||
{
|
||||
auditComponent.disableAudit(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.2
|
||||
*/
|
||||
public int clearAudit(String applicationName)
|
||||
{
|
||||
Long now = Long.valueOf(System.currentTimeMillis());
|
||||
return auditComponent.deleteAuditEntries(applicationName, null, now);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public int clearAudit(String applicationName, Long fromTime, Long toTime)
|
||||
{
|
||||
toTime = (toTime == null) ? Long.valueOf(System.currentTimeMillis()) : toTime;
|
||||
return auditComponent.deleteAuditEntries(applicationName, fromTime, toTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 5.2.2
|
||||
*/
|
||||
@Override
|
||||
public int clearAuditByIdRange(String applicationName, Long fromId, Long toId)
|
||||
{
|
||||
return auditComponent.deleteAuditEntriesByIdRange(applicationName, fromId, toId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public int clearAudit(List<Long> auditEntryIds)
|
||||
{
|
||||
return auditComponent.deleteAuditEntries(auditEntryIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.3
|
||||
*/
|
||||
public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults)
|
||||
{
|
||||
auditComponent.auditQuery(callback, parameters, maxResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes)
|
||||
{
|
||||
return auditComponent.getAuditMinMaxByApp(applicationName, extremes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return auditComponent.getAuditEntriesCountByApp(applicationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override public int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
|
||||
{
|
||||
return auditComponent.getAuditEntriesCountByAppAndProperties(parameters);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||
import org.alfresco.service.cmr.audit.AuditService;
|
||||
|
||||
/**
|
||||
* The implementation of the AuditService for application auditing.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AuditServiceImpl implements AuditService
|
||||
{
|
||||
private AuditComponent auditComponent;
|
||||
|
||||
public AuditServiceImpl()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public void setAuditComponent(AuditComponent auditComponent)
|
||||
{
|
||||
this.auditComponent = auditComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public boolean isAuditEnabled()
|
||||
{
|
||||
return auditComponent.isAuditEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public void setAuditEnabled(boolean enable)
|
||||
{
|
||||
auditComponent.setAuditEnabled(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public Map<String, AuditApplication> getAuditApplications()
|
||||
{
|
||||
Map<String, org.alfresco.repo.audit.model.AuditApplication> apps = auditComponent.getAuditApplications();
|
||||
|
||||
Map<String, AuditApplication> ret = new TreeMap<String, AuditApplication>();
|
||||
for (String app : apps.keySet())
|
||||
{
|
||||
String name = app;
|
||||
String key = org.alfresco.repo.audit.model.AuditApplication.AUDIT_PATH_SEPARATOR + apps.get(app).getApplicationKey();
|
||||
boolean enabled = auditComponent.isAuditPathEnabled(app, key);
|
||||
AuditApplication auditApplication = new AuditApplication(name, key, enabled);
|
||||
ret.put(name, auditApplication);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public boolean isAuditEnabled(String applicationName, String path)
|
||||
{
|
||||
return auditComponent.isAuditPathEnabled(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public void enableAudit(String applicationName, String path)
|
||||
{
|
||||
auditComponent.enableAudit(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public void disableAudit(String applicationName, String path)
|
||||
{
|
||||
auditComponent.disableAudit(applicationName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public int clearAudit(String applicationName)
|
||||
{
|
||||
Long now = Long.valueOf(System.currentTimeMillis());
|
||||
return auditComponent.deleteAuditEntries(applicationName, null, now);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public int clearAudit(String applicationName, Long fromTime, Long toTime)
|
||||
{
|
||||
toTime = (toTime == null) ? Long.valueOf(System.currentTimeMillis()) : toTime;
|
||||
return auditComponent.deleteAuditEntries(applicationName, fromTime, toTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
@Override
|
||||
public int clearAuditByIdRange(String applicationName, Long fromId, Long toId)
|
||||
{
|
||||
return auditComponent.deleteAuditEntriesByIdRange(applicationName, fromId, toId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
@Override
|
||||
public int clearAudit(List<Long> auditEntryIds)
|
||||
{
|
||||
return auditComponent.deleteAuditEntries(auditEntryIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults)
|
||||
{
|
||||
auditComponent.auditQuery(callback, parameters, maxResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes)
|
||||
{
|
||||
return auditComponent.getAuditMinMaxByApp(applicationName, extremes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return auditComponent.getAuditEntriesCountByApp(applicationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
|
||||
{
|
||||
return auditComponent.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
|
||||
}
|
||||
}
|
||||
|
@@ -1,123 +1,116 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.domain;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Helper class to calculate CRC values for string persistence.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class CrcHelper
|
||||
{
|
||||
public static final String EMPTY_STRING = ".empty";
|
||||
|
||||
/**
|
||||
* Calculate a persistable, unique pair of values that can be persisted in a database unique
|
||||
* key and guarantee correct case-sensitivity.
|
||||
* <p>
|
||||
* While the short-string version of the value is always lowercase, the CRC is
|
||||
* calculated from the virgin string if case-sensitivity is enforced; in the case-insensitive
|
||||
* case, the CRC is calculated from a lowercase version of the string.
|
||||
* <p>
|
||||
* If the value is an empty string, then {@link #EMPTY_STRING} is used instead. This ensures
|
||||
* that persisted values don't fall foul of the Oracle empty string comparison "behaviour" i.e
|
||||
* you should never persist an empty string in Oracle as it equates to a SQL <b>NULL</b>.
|
||||
*
|
||||
* @param value the raw value that will be persisted
|
||||
* @param dataLength the maximum number of characters that can be persisted
|
||||
* @param useCharsFromStart <tt>true</tt> if the shortened string value must be made from
|
||||
* the first characters of the string or <tt>false</tt> to use
|
||||
* characters from the end of the string.
|
||||
* @param caseSensitive <tt>true</tt> if the resulting pair must be case-sensitive or
|
||||
* <tt>false</tt> if the pair must be case-insensitive.
|
||||
* @return Return the persistable pair. The result will never be <tt>null</tt>,
|
||||
* but the individual pair values will be <tt>null</tt> if the
|
||||
* value given is <tt>null</tt>
|
||||
*/
|
||||
public static Pair<String, Long> getStringCrcPair(
|
||||
String value,
|
||||
int dataLength,
|
||||
boolean useCharsFromStart,
|
||||
boolean caseSensitive)
|
||||
{
|
||||
String valueLowerCase;
|
||||
if (value == null)
|
||||
{
|
||||
return new Pair<String, Long>(null, null);
|
||||
}
|
||||
else if (value.length() == 0)
|
||||
{
|
||||
value = CrcHelper.EMPTY_STRING;
|
||||
valueLowerCase = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
valueLowerCase = value.toLowerCase();
|
||||
}
|
||||
Long valueCrc;
|
||||
try
|
||||
{
|
||||
CRC32 crc = new CRC32();
|
||||
if (caseSensitive)
|
||||
{
|
||||
crc.update(value.getBytes("UTF-8"));
|
||||
}
|
||||
else
|
||||
{
|
||||
crc.update(valueLowerCase.getBytes("UTF-8"));
|
||||
}
|
||||
valueCrc = crc.getValue();
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new RuntimeException("UTF-8 encoding is not supported");
|
||||
}
|
||||
// Crc Value will change based on the case-sensitive, So we need to get the short value based on case-sensitive
|
||||
String valueShort = null;
|
||||
String currentValue = caseSensitive ? value : valueLowerCase;
|
||||
int valueLen = currentValue.length();
|
||||
if (valueLen < dataLength)
|
||||
{
|
||||
valueShort = currentValue;
|
||||
}
|
||||
else if (useCharsFromStart)
|
||||
{
|
||||
valueShort = currentValue.substring(0, dataLength - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueShort = currentValue.substring(valueLen - dataLength);
|
||||
}
|
||||
return new Pair<String, Long>(valueShort, valueCrc);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.domain;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Helper class to calculate CRC values for string persistence.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class CrcHelper
|
||||
{
|
||||
public static final String EMPTY_STRING = ".empty";
|
||||
|
||||
/**
|
||||
* Calculate a persistable, unique pair of values that can be persisted in a database unique key and guarantee correct case-sensitivity.
|
||||
* <p>
|
||||
* While the short-string version of the value is always lowercase, the CRC is calculated from the virgin string if case-sensitivity is enforced; in the case-insensitive case, the CRC is calculated from a lowercase version of the string.
|
||||
* <p>
|
||||
* If the value is an empty string, then {@link #EMPTY_STRING} is used instead. This ensures that persisted values don't fall foul of the Oracle empty string comparison "behaviour" i.e you should never persist an empty string in Oracle as it equates to a SQL <b>NULL</b>.
|
||||
*
|
||||
* @param value
|
||||
* the raw value that will be persisted
|
||||
* @param dataLength
|
||||
* the maximum number of characters that can be persisted
|
||||
* @param useCharsFromStart
|
||||
* <tt>true</tt> if the shortened string value must be made from the first characters of the string or <tt>false</tt> to use characters from the end of the string.
|
||||
* @param caseSensitive
|
||||
* <tt>true</tt> if the resulting pair must be case-sensitive or <tt>false</tt> if the pair must be case-insensitive.
|
||||
* @return Return the persistable pair. The result will never be <tt>null</tt>, but the individual pair values will be <tt>null</tt> if the value given is <tt>null</tt>
|
||||
*/
|
||||
public static Pair<String, Long> getStringCrcPair(
|
||||
String value,
|
||||
int dataLength,
|
||||
boolean useCharsFromStart,
|
||||
boolean caseSensitive)
|
||||
{
|
||||
String valueLowerCase;
|
||||
if (value == null)
|
||||
{
|
||||
return new Pair<String, Long>(null, null);
|
||||
}
|
||||
else if (value.length() == 0)
|
||||
{
|
||||
value = CrcHelper.EMPTY_STRING;
|
||||
valueLowerCase = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
valueLowerCase = value.toLowerCase();
|
||||
}
|
||||
Long valueCrc;
|
||||
try
|
||||
{
|
||||
CRC32 crc = new CRC32();
|
||||
if (caseSensitive)
|
||||
{
|
||||
crc.update(value.getBytes("UTF-8"));
|
||||
}
|
||||
else
|
||||
{
|
||||
crc.update(valueLowerCase.getBytes("UTF-8"));
|
||||
}
|
||||
valueCrc = crc.getValue();
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new RuntimeException("UTF-8 encoding is not supported");
|
||||
}
|
||||
// Get the short value (case-sensitive or not)
|
||||
String valueShort = null;
|
||||
int valueLen = valueLowerCase.length();
|
||||
if (valueLen < dataLength)
|
||||
{
|
||||
valueShort = valueLowerCase;
|
||||
}
|
||||
else if (useCharsFromStart)
|
||||
{
|
||||
valueShort = valueLowerCase.substring(0, dataLength - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueShort = valueLowerCase.substring(valueLen - dataLength);
|
||||
}
|
||||
return new Pair<String, Long>(valueShort, valueCrc);
|
||||
}
|
||||
}
|
||||
|
@@ -1,258 +1,285 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* DAO services for <b>alf_audit_XXX</b> tables.
|
||||
* <p>
|
||||
* The older methods are supported by a different implementation and will eventually
|
||||
* be deprecated and phased out.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public interface AuditDAO
|
||||
{
|
||||
/*
|
||||
* V3.2 methods after here only, please
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about the audit application to be passed in an out of the interface.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public static class AuditApplicationInfo
|
||||
{
|
||||
private Long id;
|
||||
private String name;
|
||||
private Long modelId;
|
||||
private Long disabledPathsId;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("AuditApplicationInfo ")
|
||||
.append("[ id=").append(id)
|
||||
.append(", name=").append(name)
|
||||
.append(", modelId=").append(modelId)
|
||||
.append(", disabledPathsId=").append(disabledPathsId)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
public void setname(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
public Long getModelId()
|
||||
{
|
||||
return modelId;
|
||||
}
|
||||
public void setModelId(Long modelId)
|
||||
{
|
||||
this.modelId = modelId;
|
||||
}
|
||||
public Long getDisabledPathsId()
|
||||
{
|
||||
return disabledPathsId;
|
||||
}
|
||||
public void setDisabledPathsId(Long disabledPathsId)
|
||||
{
|
||||
this.disabledPathsId = disabledPathsId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new audit model entry or finds an existing one
|
||||
*
|
||||
* @param url the URL of the configuration
|
||||
* @return Returns the ID of the config matching the input stream and the
|
||||
* content storage details
|
||||
* @since 3.2
|
||||
*/
|
||||
Pair<Long, ContentData> getOrCreateAuditModel(URL url);
|
||||
|
||||
/**
|
||||
* Get the audit application details.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @return Returns details of an existing application or <tt>null</tt> if it doesn't exist
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
AuditApplicationInfo getAuditApplication(String applicationName);
|
||||
|
||||
/**
|
||||
* Creates a new audit application. The application name must be unique.
|
||||
*
|
||||
* @param application the name of the application
|
||||
* @param modelId the ID of the model configuration
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
AuditApplicationInfo createAuditApplication(String application, Long modelId);
|
||||
|
||||
/**
|
||||
* Update the audit application to refer to a new model.
|
||||
* If the model did not change, then nothing will be done.
|
||||
*
|
||||
* @param id the ID of the audit application
|
||||
* @param modelId the ID of the new model
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void updateAuditApplicationModel(Long id, Long modelId);
|
||||
|
||||
/**
|
||||
* Update the audit application to hold a new set of disabled paths.
|
||||
* If the value did not change, then nothing will be done.
|
||||
*
|
||||
* @param id the ID of the audit application
|
||||
* @param disabledPaths the new disabled paths
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void updateAuditApplicationDisabledPaths(Long id, Set<String> disabledPaths);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the application, possibly limiting the time range.
|
||||
*
|
||||
* @param applicationId an existing audit application ID
|
||||
* @param fromTime the minimum entry time (inclusive, optional)
|
||||
* @param toTime the maximum entry time (exclusive, optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
int deleteAuditEntries(Long applicationId, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the application for given id range.
|
||||
*
|
||||
* @param applicationId an existing audit application ID
|
||||
* @param fromId the minimum fromId (inclusive, optional)
|
||||
* @param toId the maximum toId (exclusive, optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries. Duplicate entries are collapsed
|
||||
* and the number of entries deleted will match the count of unique IDs in
|
||||
* the list; otherwise a concurrency condition has occured and an exception
|
||||
* will be generated.
|
||||
*
|
||||
* @param auditEntryIds the IDs of all audit entries to delete
|
||||
* @return Returns the number of entries deleted
|
||||
*/
|
||||
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* Create a new audit entry with the given map of values.
|
||||
*
|
||||
* @param applicationId an existing audit application ID
|
||||
* @param time the time (ms since epoch) to log the entry against
|
||||
* @param username the authenticated user (<tt>null</tt> if not present)
|
||||
* @param values the values to record
|
||||
* @return Returns the unique entry ID
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* Find audit entries using the given parameters, any of which may be null
|
||||
*
|
||||
* @param callback the data callback per entry
|
||||
* @param parameters the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException if maxResults less or equal to zero
|
||||
*/
|
||||
void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
org.alfresco.service.cmr.audit.AuditQueryParameters parameters,
|
||||
int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param appId the database id of the application
|
||||
* @param extremes a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application.
|
||||
*
|
||||
* @param applicationId the database id of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(long applicationId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application and properties
|
||||
*
|
||||
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* DAO services for <b>alf_audit_XXX</b> tables.
|
||||
* <p>
|
||||
* The older methods are supported by a different implementation and will eventually be deprecated and phased out.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public interface AuditDAO
|
||||
{
|
||||
/* V3.2 methods after here only, please */
|
||||
|
||||
/**
|
||||
* Information about the audit application to be passed in an out of the interface.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public static class AuditApplicationInfo
|
||||
{
|
||||
private Long id;
|
||||
private String name;
|
||||
private Long modelId;
|
||||
private Long disabledPathsId;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("AuditApplicationInfo ")
|
||||
.append("[ id=").append(id)
|
||||
.append(", name=").append(name)
|
||||
.append(", modelId=").append(modelId)
|
||||
.append(", disabledPathsId=").append(disabledPathsId)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setname(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getModelId()
|
||||
{
|
||||
return modelId;
|
||||
}
|
||||
|
||||
public void setModelId(Long modelId)
|
||||
{
|
||||
this.modelId = modelId;
|
||||
}
|
||||
|
||||
public Long getDisabledPathsId()
|
||||
{
|
||||
return disabledPathsId;
|
||||
}
|
||||
|
||||
public void setDisabledPathsId(Long disabledPathsId)
|
||||
{
|
||||
this.disabledPathsId = disabledPathsId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new audit model entry or finds an existing one
|
||||
*
|
||||
* @param url
|
||||
* the URL of the configuration
|
||||
* @return Returns the ID of the config matching the input stream and the content storage details
|
||||
* @since 3.2
|
||||
*/
|
||||
Pair<Long, ContentData> getOrCreateAuditModel(URL url);
|
||||
|
||||
/**
|
||||
* Get the audit application details.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @return Returns details of an existing application or <tt>null</tt> if it doesn't exist
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
AuditApplicationInfo getAuditApplication(String applicationName);
|
||||
|
||||
/**
|
||||
* Creates a new audit application. The application name must be unique.
|
||||
*
|
||||
* @param application
|
||||
* the name of the application
|
||||
* @param modelId
|
||||
* the ID of the model configuration
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
AuditApplicationInfo createAuditApplication(String application, Long modelId);
|
||||
|
||||
/**
|
||||
* Update the audit application to refer to a new model. If the model did not change, then nothing will be done.
|
||||
*
|
||||
* @param id
|
||||
* the ID of the audit application
|
||||
* @param modelId
|
||||
* the ID of the new model
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void updateAuditApplicationModel(Long id, Long modelId);
|
||||
|
||||
/**
|
||||
* Update the audit application to hold a new set of disabled paths. If the value did not change, then nothing will be done.
|
||||
*
|
||||
* @param id
|
||||
* the ID of the audit application
|
||||
* @param disabledPaths
|
||||
* the new disabled paths
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void updateAuditApplicationDisabledPaths(Long id, Set<String> disabledPaths);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the application, possibly limiting the time range.
|
||||
*
|
||||
* @param applicationId
|
||||
* an existing audit application ID
|
||||
* @param fromTime
|
||||
* the minimum entry time (inclusive, optional)
|
||||
* @param toTime
|
||||
* the maximum entry time (exclusive, optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
int deleteAuditEntries(Long applicationId, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Delete audit entries for the application for given id range.
|
||||
*
|
||||
* @param applicationId
|
||||
* an existing audit application ID
|
||||
* @param fromId
|
||||
* the minimum fromId (inclusive, optional)
|
||||
* @param toId
|
||||
* the maximum toId (exclusive, optional)
|
||||
* @return Returns the number of entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries. Duplicate entries are collapsed and the number of entries deleted will match the count of unique IDs in the list; otherwise a concurrency condition has occured and an exception will be generated.
|
||||
*
|
||||
* @param auditEntryIds
|
||||
* the IDs of all audit entries to delete
|
||||
* @return Returns the number of entries deleted
|
||||
*/
|
||||
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* Create a new audit entry with the given map of values.
|
||||
*
|
||||
* @param applicationId
|
||||
* an existing audit application ID
|
||||
* @param time
|
||||
* the time (ms since epoch) to log the entry against
|
||||
* @param username
|
||||
* the authenticated user (<tt>null</tt> if not present)
|
||||
* @param values
|
||||
* the values to record
|
||||
* @return Returns the unique entry ID
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* Find audit entries using the given parameters, any of which may be null
|
||||
*
|
||||
* @param callback
|
||||
* the data callback per entry
|
||||
* @param parameters
|
||||
* the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults
|
||||
* the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if maxResults less or equal to zero
|
||||
*/
|
||||
void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
org.alfresco.service.cmr.audit.AuditQueryParameters parameters,
|
||||
int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param appId
|
||||
* the database id of the application
|
||||
* @param extremes
|
||||
* a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application.
|
||||
*
|
||||
* @param applicationId
|
||||
* the database id of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(long applicationId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve count of records for a given application and properties
|
||||
*
|
||||
* @param applicationName
|
||||
* name of the application to be queried
|
||||
* @param parameters
|
||||
* audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(String applicationName, org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -1,316 +1,315 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.audit.ibatis;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
|
||||
import org.alfresco.repo.domain.audit.AuditApplicationEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditDeleteParameters;
|
||||
import org.alfresco.repo.domain.audit.AuditEntryEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditModelEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditQueryParameters;
|
||||
import org.alfresco.repo.domain.audit.AuditQueryResult;
|
||||
import org.alfresco.repo.domain.propval.PropertyValueDAO.PropertyFinderCallback;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
|
||||
/**
|
||||
* iBatis-specific implementation of the DAO for <b>alf_audit_XXX</b> tables.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AuditDAOImpl extends AbstractAuditDAOImpl
|
||||
{
|
||||
private static final String SELECT_MODEL_BY_CRC = "alfresco.audit.select_AuditModelByCrc";
|
||||
private static final String INSERT_MODEL = "alfresco.audit.insert.insert_AuditModel";
|
||||
|
||||
private static final String SELECT_APPLICATION_BY_ID = "alfresco.audit.select_AuditApplicationById";
|
||||
private static final String SELECT_APPLICATION_BY_NAME_ID = "alfresco.audit.select_AuditApplicationByNameId";
|
||||
private static final String INSERT_APPLICATION = "alfresco.audit.insert.insert_AuditApplication";
|
||||
private static final String UPDATE_APPLICATION = "alfresco.audit.update_AuditApplication";
|
||||
|
||||
private static final String DELETE_ENTRIES = "alfresco.audit.delete_AuditEntries";
|
||||
private static final String DELETE_ENTRIES_BY_ID = "alfresco.audit.delete_AuditEntriesById";
|
||||
private static final String INSERT_ENTRY = "alfresco.audit.insert.insert_AuditEntry";
|
||||
private static final String SELECT_MINMAX_ENTRY_FOR_APP = "alfresco.audit.select_MinMaxAuditEntryId";
|
||||
private static final String SELECT_COUNT_ENTRIES_FOR_APP = "alfresco.audit.select_CountAuditEntryId";
|
||||
private static final String SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES = "select_CountAuditEntryIdWithWhereClause";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String SELECT_ENTRIES_SIMPLE = "alfresco.audit.select_AuditEntriesSimple";
|
||||
private static final String SELECT_ENTRIES_WITH_VALUES = "alfresco.audit.select_AuditEntriesWithValues";
|
||||
private static final String SELECT_ENTRIES_WITHOUT_VALUES = "alfresco.audit.select_AuditEntriesWithoutValues";
|
||||
|
||||
private SqlSessionTemplate template;
|
||||
|
||||
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
|
||||
{
|
||||
this.template = sqlSessionTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditModelEntity getAuditModelByCrc(long crc)
|
||||
{
|
||||
AuditModelEntity entity = new AuditModelEntity();
|
||||
entity.setContentCrc(crc);
|
||||
entity = template.selectOne(
|
||||
SELECT_MODEL_BY_CRC,
|
||||
entity);
|
||||
// Done
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditModelEntity createAuditModel(Long contentDataId, long crc)
|
||||
{
|
||||
AuditModelEntity entity = new AuditModelEntity();
|
||||
entity.setContentDataId(contentDataId);
|
||||
entity.setContentCrc(crc);
|
||||
template.insert(INSERT_MODEL, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity getAuditApplicationById(Long id)
|
||||
{
|
||||
Map<String, Object> params = new HashMap<String, Object>(11);
|
||||
params.put("id", id);
|
||||
AuditApplicationEntity entity = template.selectOne(
|
||||
SELECT_APPLICATION_BY_ID,
|
||||
params);
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Searched for audit application ID " + id + " and found: " + entity);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity getAuditApplicationByName(String appName)
|
||||
{
|
||||
// Resolve the name as a property ID
|
||||
Pair<Long, Serializable> appNamePair = propertyValueDAO.getPropertyValue(appName);
|
||||
if (appNamePair == null)
|
||||
{
|
||||
// There will be no results
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> params = new HashMap<String, Object>(11);
|
||||
params.put("id", appNamePair.getFirst());
|
||||
AuditApplicationEntity entity = template.selectOne(
|
||||
SELECT_APPLICATION_BY_NAME_ID,
|
||||
params);
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Searched for audit application '" + appName + "' and found: " + entity);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity createAuditApplication(Long appNameId, Long modelId, Long disabledPathsId)
|
||||
{
|
||||
AuditApplicationEntity entity = new AuditApplicationEntity();
|
||||
entity.setVersion((short)0);
|
||||
entity.setApplicationNameId(appNameId);
|
||||
entity.setAuditModelId(modelId);
|
||||
entity.setDisabledPathsId(disabledPathsId);
|
||||
template.insert(INSERT_APPLICATION, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity updateAuditApplication(AuditApplicationEntity entity)
|
||||
{
|
||||
AuditApplicationEntity updateEntity = new AuditApplicationEntity();
|
||||
updateEntity.setId(entity.getId());
|
||||
updateEntity.setVersion(entity.getVersion());
|
||||
updateEntity.incrementVersion();
|
||||
updateEntity.setApplicationNameId(entity.getApplicationNameId());
|
||||
updateEntity.setAuditModelId(entity.getAuditModelId());
|
||||
updateEntity.setDisabledPathsId(entity.getDisabledPathsId());
|
||||
|
||||
int updated = template.update(UPDATE_APPLICATION, updateEntity);
|
||||
if (updated != 1)
|
||||
{
|
||||
// unexpected number of rows affected
|
||||
throw new ConcurrencyFailureException("Incorrect number of rows affected for updateAuditApplication: " + updateEntity + ": expected 1, actual " + updated);
|
||||
}
|
||||
|
||||
// Done
|
||||
return updateEntity;
|
||||
}
|
||||
|
||||
public int deleteAuditEntries(Long applicationId, Long from, Long to)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditApplicationId(applicationId);
|
||||
params.setAuditFromTime(from);
|
||||
params.setAuditToTime(to);
|
||||
return template.delete(DELETE_ENTRIES, params);
|
||||
}
|
||||
|
||||
public int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditApplicationId(applicationId);
|
||||
params.setAuditFromId(fromId);
|
||||
params.setAuditToId(toId);
|
||||
return template.delete(DELETE_ENTRIES, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int deleteAuditEntriesImpl(List<Long> auditEntryIds)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditEntryIds(auditEntryIds);
|
||||
return template.delete(DELETE_ENTRIES_BY_ID, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId)
|
||||
{
|
||||
AuditEntryEntity entity = new AuditEntryEntity();
|
||||
entity.setAuditApplicationId(applicationId);
|
||||
entity.setAuditTime(time);
|
||||
entity.setAuditUserId(usernameId);
|
||||
entity.setAuditValuesId(valuesId);
|
||||
template.insert(INSERT_ENTRY, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes)
|
||||
{
|
||||
// Build parameters to be used in the query. Filter the duplicates when inserting into map
|
||||
Map<String, Object> params = extremes.stream().collect(Collectors.toMap(s -> s, s -> Boolean.TRUE, (s1, s2) -> s1));
|
||||
params.put("auditAppId", appId);
|
||||
|
||||
HashMap<String, Long> result = template.selectOne(SELECT_MINMAX_ENTRY_FOR_APP, params);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAuditEntriesCountByApp(long applicationId)
|
||||
{
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("auditAppId", applicationId);
|
||||
|
||||
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP, params);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
|
||||
{
|
||||
AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters);
|
||||
|
||||
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES, dbParameters);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void findAuditEntries(
|
||||
final AuditQueryRowHandler rowHandler,
|
||||
int maxResults,
|
||||
org.alfresco.service.cmr.audit.AuditQueryParameters restParameters)
|
||||
{
|
||||
AuditQueryParameters params = convertFromRestAuditQueryParameters(restParameters);
|
||||
if (params==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxResults > 0)
|
||||
{
|
||||
// Query without getting the values. We gather all the results and batch-fetch the audited
|
||||
// values afterwards.
|
||||
final Map<Long, AuditQueryResult> resultsByValueId = new HashMap<Long, AuditQueryResult>(173);
|
||||
PropertyFinderCallback propertyFinderCallback = new PropertyFinderCallback()
|
||||
{
|
||||
public void handleProperty(Long id, Serializable value)
|
||||
{
|
||||
// get the row
|
||||
AuditQueryResult row = resultsByValueId.get(id);
|
||||
try
|
||||
{
|
||||
row.setAuditValue((Map<String, Serializable>) value);
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
// The handler will deal with the entry
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
List<AuditQueryResult> rows = template.selectList(SELECT_ENTRIES_WITHOUT_VALUES, params, new RowBounds(0, maxResults));
|
||||
for (AuditQueryResult row : rows)
|
||||
{
|
||||
resultsByValueId.put(row.getAuditValuesId(), row);
|
||||
if (resultsByValueId.size() >= 100)
|
||||
{
|
||||
// Fetch values for the results. The treemap is ordered.
|
||||
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
|
||||
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
|
||||
// Clear and continue
|
||||
resultsByValueId.clear();
|
||||
}
|
||||
}
|
||||
// Process any remaining results
|
||||
if (resultsByValueId.size() > 0)
|
||||
{
|
||||
// Fetch values for the results. The treemap is ordered.
|
||||
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
|
||||
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
|
||||
}
|
||||
// Now pass the filled-out results to the row handler (order-preserved)
|
||||
for (AuditQueryResult row : rows)
|
||||
{
|
||||
rowHandler.processResult(row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("maxResults must be greater than 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.audit.ibatis;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
|
||||
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
|
||||
import org.alfresco.repo.domain.audit.AuditApplicationEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditDeleteParameters;
|
||||
import org.alfresco.repo.domain.audit.AuditEntryEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditModelEntity;
|
||||
import org.alfresco.repo.domain.audit.AuditQueryParameters;
|
||||
import org.alfresco.repo.domain.audit.AuditQueryResult;
|
||||
import org.alfresco.repo.domain.propval.PropertyValueDAO.PropertyFinderCallback;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* iBatis-specific implementation of the DAO for <b>alf_audit_XXX</b> tables.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AuditDAOImpl extends AbstractAuditDAOImpl
|
||||
{
|
||||
private static final String SELECT_MODEL_BY_CRC = "alfresco.audit.select_AuditModelByCrc";
|
||||
private static final String INSERT_MODEL = "alfresco.audit.insert.insert_AuditModel";
|
||||
|
||||
private static final String SELECT_APPLICATION_BY_ID = "alfresco.audit.select_AuditApplicationById";
|
||||
private static final String SELECT_APPLICATION_BY_NAME_ID = "alfresco.audit.select_AuditApplicationByNameId";
|
||||
private static final String INSERT_APPLICATION = "alfresco.audit.insert.insert_AuditApplication";
|
||||
private static final String UPDATE_APPLICATION = "alfresco.audit.update_AuditApplication";
|
||||
|
||||
private static final String DELETE_ENTRIES = "alfresco.audit.delete_AuditEntries";
|
||||
private static final String DELETE_ENTRIES_BY_ID = "alfresco.audit.delete_AuditEntriesById";
|
||||
private static final String INSERT_ENTRY = "alfresco.audit.insert.insert_AuditEntry";
|
||||
private static final String SELECT_MINMAX_ENTRY_FOR_APP = "alfresco.audit.select_MinMaxAuditEntryId";
|
||||
private static final String SELECT_COUNT_ENTRIES_FOR_APP = "alfresco.audit.select_CountAuditEntryId";
|
||||
private static final String SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES = "select_CountAuditEntryIdWithWhereClause";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String SELECT_ENTRIES_SIMPLE = "alfresco.audit.select_AuditEntriesSimple";
|
||||
private static final String SELECT_ENTRIES_WITH_VALUES = "alfresco.audit.select_AuditEntriesWithValues";
|
||||
private static final String SELECT_ENTRIES_WITHOUT_VALUES = "alfresco.audit.select_AuditEntriesWithoutValues";
|
||||
|
||||
private SqlSessionTemplate template;
|
||||
|
||||
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
|
||||
{
|
||||
this.template = sqlSessionTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditModelEntity getAuditModelByCrc(long crc)
|
||||
{
|
||||
AuditModelEntity entity = new AuditModelEntity();
|
||||
entity.setContentCrc(crc);
|
||||
entity = template.selectOne(
|
||||
SELECT_MODEL_BY_CRC,
|
||||
entity);
|
||||
// Done
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditModelEntity createAuditModel(Long contentDataId, long crc)
|
||||
{
|
||||
AuditModelEntity entity = new AuditModelEntity();
|
||||
entity.setContentDataId(contentDataId);
|
||||
entity.setContentCrc(crc);
|
||||
template.insert(INSERT_MODEL, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity getAuditApplicationById(Long id)
|
||||
{
|
||||
Map<String, Object> params = new HashMap<String, Object>(11);
|
||||
params.put("id", id);
|
||||
AuditApplicationEntity entity = template.selectOne(
|
||||
SELECT_APPLICATION_BY_ID,
|
||||
params);
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Searched for audit application ID " + id + " and found: " + entity);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity getAuditApplicationByName(String appName)
|
||||
{
|
||||
// Resolve the name as a property ID
|
||||
Pair<Long, Serializable> appNamePair = propertyValueDAO.getPropertyValue(appName);
|
||||
if (appNamePair == null)
|
||||
{
|
||||
// There will be no results
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> params = new HashMap<String, Object>(11);
|
||||
params.put("id", appNamePair.getFirst());
|
||||
AuditApplicationEntity entity = template.selectOne(
|
||||
SELECT_APPLICATION_BY_NAME_ID,
|
||||
params);
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Searched for audit application '" + appName + "' and found: " + entity);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity createAuditApplication(Long appNameId, Long modelId, Long disabledPathsId)
|
||||
{
|
||||
AuditApplicationEntity entity = new AuditApplicationEntity();
|
||||
entity.setVersion((short) 0);
|
||||
entity.setApplicationNameId(appNameId);
|
||||
entity.setAuditModelId(modelId);
|
||||
entity.setDisabledPathsId(disabledPathsId);
|
||||
template.insert(INSERT_APPLICATION, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditApplicationEntity updateAuditApplication(AuditApplicationEntity entity)
|
||||
{
|
||||
AuditApplicationEntity updateEntity = new AuditApplicationEntity();
|
||||
updateEntity.setId(entity.getId());
|
||||
updateEntity.setVersion(entity.getVersion());
|
||||
updateEntity.incrementVersion();
|
||||
updateEntity.setApplicationNameId(entity.getApplicationNameId());
|
||||
updateEntity.setAuditModelId(entity.getAuditModelId());
|
||||
updateEntity.setDisabledPathsId(entity.getDisabledPathsId());
|
||||
|
||||
int updated = template.update(UPDATE_APPLICATION, updateEntity);
|
||||
if (updated != 1)
|
||||
{
|
||||
// unexpected number of rows affected
|
||||
throw new ConcurrencyFailureException("Incorrect number of rows affected for updateAuditApplication: " + updateEntity + ": expected 1, actual " + updated);
|
||||
}
|
||||
|
||||
// Done
|
||||
return updateEntity;
|
||||
}
|
||||
|
||||
public int deleteAuditEntries(Long applicationId, Long from, Long to)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditApplicationId(applicationId);
|
||||
params.setAuditFromTime(from);
|
||||
params.setAuditToTime(to);
|
||||
return template.delete(DELETE_ENTRIES, params);
|
||||
}
|
||||
|
||||
public int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditApplicationId(applicationId);
|
||||
params.setAuditFromId(fromId);
|
||||
params.setAuditToId(toId);
|
||||
return template.delete(DELETE_ENTRIES, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int deleteAuditEntriesImpl(List<Long> auditEntryIds)
|
||||
{
|
||||
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||
params.setAuditEntryIds(auditEntryIds);
|
||||
return template.delete(DELETE_ENTRIES_BY_ID, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId)
|
||||
{
|
||||
AuditEntryEntity entity = new AuditEntryEntity();
|
||||
entity.setAuditApplicationId(applicationId);
|
||||
entity.setAuditTime(time);
|
||||
entity.setAuditUserId(usernameId);
|
||||
entity.setAuditValuesId(valuesId);
|
||||
template.insert(INSERT_ENTRY, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes)
|
||||
{
|
||||
// Build parameters to be used in the query. Filter the duplicates when inserting into map
|
||||
Map<String, Object> params = extremes.stream().collect(Collectors.toMap(s -> s, s -> Boolean.TRUE, (s1, s2) -> s1));
|
||||
params.put("auditAppId", appId);
|
||||
|
||||
HashMap<String, Long> result = template.selectOne(SELECT_MINMAX_ENTRY_FOR_APP, params);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAuditEntriesCountByApp(long applicationId)
|
||||
{
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("auditAppId", applicationId);
|
||||
|
||||
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP, params);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAuditEntriesCountByAppAndProperties(String applicationName, org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
|
||||
{
|
||||
AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters);
|
||||
|
||||
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES, dbParameters);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void findAuditEntries(
|
||||
final AuditQueryRowHandler rowHandler,
|
||||
int maxResults,
|
||||
org.alfresco.service.cmr.audit.AuditQueryParameters restParameters)
|
||||
{
|
||||
AuditQueryParameters params = convertFromRestAuditQueryParameters(restParameters);
|
||||
if (params == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxResults > 0)
|
||||
{
|
||||
// Query without getting the values. We gather all the results and batch-fetch the audited
|
||||
// values afterwards.
|
||||
final Map<Long, AuditQueryResult> resultsByValueId = new HashMap<Long, AuditQueryResult>(173);
|
||||
PropertyFinderCallback propertyFinderCallback = new PropertyFinderCallback() {
|
||||
public void handleProperty(Long id, Serializable value)
|
||||
{
|
||||
// get the row
|
||||
AuditQueryResult row = resultsByValueId.get(id);
|
||||
try
|
||||
{
|
||||
row.setAuditValue((Map<String, Serializable>) value);
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
// The handler will deal with the entry
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
List<AuditQueryResult> rows = template.selectList(SELECT_ENTRIES_WITHOUT_VALUES, params, new RowBounds(0, maxResults));
|
||||
for (AuditQueryResult row : rows)
|
||||
{
|
||||
resultsByValueId.put(row.getAuditValuesId(), row);
|
||||
if (resultsByValueId.size() >= 100)
|
||||
{
|
||||
// Fetch values for the results. The treemap is ordered.
|
||||
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
|
||||
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
|
||||
// Clear and continue
|
||||
resultsByValueId.clear();
|
||||
}
|
||||
}
|
||||
// Process any remaining results
|
||||
if (resultsByValueId.size() > 0)
|
||||
{
|
||||
// Fetch values for the results. The treemap is ordered.
|
||||
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
|
||||
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
|
||||
}
|
||||
// Now pass the filled-out results to the row handler (order-preserved)
|
||||
for (AuditQueryResult row : rows)
|
||||
{
|
||||
rowHandler.processResult(row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("maxResults must be greater than 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,173 +1,158 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.propval;
|
||||
|
||||
import org.alfresco.repo.domain.CrcHelper;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Entity bean for <b>alf_prop_string_value</b> table.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class PropertyStringValueEntity
|
||||
{
|
||||
public static final String EMPTY_STRING = "";
|
||||
public static final String EMPTY_STRING_REPLACEMENT = ".empty";
|
||||
|
||||
private Long id;
|
||||
private String stringValue;
|
||||
private String stringEndLower;
|
||||
private Long stringCrc;
|
||||
private String stringLower;
|
||||
|
||||
public PropertyStringValueEntity()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return (stringValue == null ? 0 : stringValue.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && obj instanceof PropertyStringValueEntity)
|
||||
{
|
||||
PropertyStringValueEntity that = (PropertyStringValueEntity) obj;
|
||||
return EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("PropertyStringValueEntity")
|
||||
.append("[ ID=").append(id)
|
||||
.append(", stringValue=").append(stringValue)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Pair<Long, String> getEntityPair()
|
||||
{
|
||||
if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT))
|
||||
{
|
||||
return new Pair<Long, String>(id, PropertyStringValueEntity.EMPTY_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Pair<Long, String>(id, stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the string and string-end values
|
||||
*/
|
||||
public void setValue(String value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Null strings cannot be persisted");
|
||||
}
|
||||
if (value != null && value.equals(PropertyStringValueEntity.EMPTY_STRING))
|
||||
{
|
||||
// Oracle: We can't insert empty strings into the column.
|
||||
value = PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT;
|
||||
}
|
||||
stringValue = value;
|
||||
// Calculate the crc value from the original value
|
||||
Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true);
|
||||
stringEndLower = crcPair.getFirst();
|
||||
stringCrc = crcPair.getSecond();
|
||||
// Calculate the crc value with case-insensitive
|
||||
Pair<String, Long> crcPairWithCaseInSensitive = CrcHelper.getStringCrcPair(value, 16, false, false);
|
||||
stringLower = crcPairWithCaseInSensitive.getFirst();
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStringValue()
|
||||
{
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
public void setStringValue(String stringValue)
|
||||
{
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public String getStringEndLower()
|
||||
{
|
||||
return stringEndLower;
|
||||
}
|
||||
|
||||
public void setStringEndLower(String stringEndLower)
|
||||
{
|
||||
this.stringEndLower = stringEndLower;
|
||||
}
|
||||
|
||||
public Long getStringCrc()
|
||||
{
|
||||
return stringCrc;
|
||||
}
|
||||
|
||||
public void setStringCrc(Long stringCrc)
|
||||
{
|
||||
this.stringCrc = stringCrc;
|
||||
}
|
||||
|
||||
public String getStringLower()
|
||||
{
|
||||
return stringLower;
|
||||
}
|
||||
|
||||
public void setStringLower(String stringLower)
|
||||
{
|
||||
this.stringLower = stringLower;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.propval;
|
||||
|
||||
import org.alfresco.repo.domain.CrcHelper;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Entity bean for <b>alf_prop_string_value</b> table.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
public class PropertyStringValueEntity
|
||||
{
|
||||
public static final String EMPTY_STRING = "";
|
||||
public static final String EMPTY_STRING_REPLACEMENT = ".empty";
|
||||
|
||||
private Long id;
|
||||
private String stringValue;
|
||||
private String stringEndLower;
|
||||
private Long stringCrc;
|
||||
|
||||
public PropertyStringValueEntity()
|
||||
{}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return (stringValue == null ? 0 : stringValue.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && obj instanceof PropertyStringValueEntity)
|
||||
{
|
||||
PropertyStringValueEntity that = (PropertyStringValueEntity) obj;
|
||||
return EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("PropertyStringValueEntity")
|
||||
.append("[ ID=").append(id)
|
||||
.append(", stringValue=").append(stringValue)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Pair<Long, String> getEntityPair()
|
||||
{
|
||||
if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT))
|
||||
{
|
||||
return new Pair<Long, String>(id, PropertyStringValueEntity.EMPTY_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Pair<Long, String>(id, stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the string and string-end values
|
||||
*/
|
||||
public void setValue(String value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Null strings cannot be persisted");
|
||||
}
|
||||
if (value != null && value.equals(PropertyStringValueEntity.EMPTY_STRING))
|
||||
{
|
||||
// Oracle: We can't insert empty strings into the column.
|
||||
value = PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT;
|
||||
}
|
||||
stringValue = value;
|
||||
// Calculate the crc value from the original value
|
||||
Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true);
|
||||
stringEndLower = crcPair.getFirst();
|
||||
stringCrc = crcPair.getSecond();
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStringValue()
|
||||
{
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
public void setStringValue(String stringValue)
|
||||
{
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public String getStringEndLower()
|
||||
{
|
||||
return stringEndLower;
|
||||
}
|
||||
|
||||
public void setStringEndLower(String stringEndLower)
|
||||
{
|
||||
this.stringEndLower = stringEndLower;
|
||||
}
|
||||
|
||||
public Long getStringCrc()
|
||||
{
|
||||
return stringCrc;
|
||||
}
|
||||
|
||||
public void setStringCrc(Long stringCrc)
|
||||
{
|
||||
this.stringCrc = stringCrc;
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -42,6 +42,9 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event.v1.model.ContentInfo;
|
||||
@@ -50,6 +53,7 @@ import org.alfresco.repo.event.v1.model.UserInfo;
|
||||
import org.alfresco.repo.event2.filter.EventFilterRegistry;
|
||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||
import org.alfresco.repo.node.MLPropertyInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
@@ -68,9 +72,6 @@ import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.PathUtil;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Helper for {@link NodeResource} objects.
|
||||
@@ -81,14 +82,15 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(NodeResourceHelper.class);
|
||||
|
||||
protected NodeService nodeService;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected PersonService personService;
|
||||
protected NodeService nodeService;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected PersonService personService;
|
||||
protected EventFilterRegistry eventFilterRegistry;
|
||||
protected NamespaceService namespaceService;
|
||||
protected PermissionService permissionService;
|
||||
protected NamespaceService namespaceService;
|
||||
protected PermissionService permissionService;
|
||||
protected PropertyMapper propertyMapper;
|
||||
|
||||
private NodeAspectFilter nodeAspectFilter;
|
||||
private NodeAspectFilter nodeAspectFilter;
|
||||
private NodePropertyFilter nodePropertyFilter;
|
||||
|
||||
@Override
|
||||
@@ -100,6 +102,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
PropertyCheck.mandatory(this, "eventFilterRegistry", eventFilterRegistry);
|
||||
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
||||
PropertyCheck.mandatory(this, "permissionService", permissionService);
|
||||
PropertyCheck.mandatory(this, "propertyMapper", propertyMapper);
|
||||
|
||||
this.nodeAspectFilter = eventFilterRegistry.getNodeAspectFilter();
|
||||
this.nodePropertyFilter = eventFilterRegistry.getNodePropertyFilter();
|
||||
@@ -124,7 +127,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
|
||||
// To make IntelliJ stop complaining about unused method!
|
||||
@SuppressWarnings("unused")
|
||||
public void setEventFilterRegistry(EventFilterRegistry eventFilterRegistry)
|
||||
@@ -137,6 +140,11 @@ public class NodeResourceHelper implements InitializingBean
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public void setPropertyMapper(PropertyMapper propertyMapper)
|
||||
{
|
||||
this.propertyMapper = propertyMapper;
|
||||
}
|
||||
|
||||
public NodeResource.Builder createNodeResourceBuilder(NodeRef nodeRef)
|
||||
{
|
||||
final QName type = nodeService.getType(nodeRef);
|
||||
@@ -148,22 +156,22 @@ public class NodeResourceHelper implements InitializingBean
|
||||
Map<String, UserInfo> mapUserCache = new HashMap<>(2);
|
||||
|
||||
return NodeResource.builder()
|
||||
.setId(nodeRef.getId())
|
||||
.setName((String) properties.get(ContentModel.PROP_NAME))
|
||||
.setNodeType(getQNamePrefixString(type))
|
||||
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
||||
.setCreatedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_CREATED)))
|
||||
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
||||
.setModifiedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_MODIFIED)))
|
||||
.setContent(getContentInfo(properties))
|
||||
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
||||
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
||||
.setProperties(mapToNodeProperties(properties))
|
||||
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
||||
.setAspectNames(getMappedAspects(nodeRef))
|
||||
.setSecondaryParents(getSecondaryParents(nodeRef));
|
||||
.setId(nodeRef.getId())
|
||||
.setName((String) properties.get(ContentModel.PROP_NAME))
|
||||
.setNodeType(getQNamePrefixString(type))
|
||||
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
||||
.setCreatedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_CREATED)))
|
||||
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
||||
.setModifiedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_MODIFIED)))
|
||||
.setContent(getContentInfo(properties))
|
||||
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
||||
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
||||
.setProperties(mapToNodeProperties(properties))
|
||||
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
||||
.setAspectNames(getMappedAspects(nodeRef))
|
||||
.setSecondaryParents(getSecondaryParents(nodeRef));
|
||||
}
|
||||
|
||||
private boolean isSubClass(QName className, QName ofClassQName)
|
||||
@@ -171,17 +179,18 @@ public class NodeResourceHelper implements InitializingBean
|
||||
return dictionaryService.isSubClass(className, ofClassQName);
|
||||
}
|
||||
|
||||
private String getPrimaryAssocQName(NodeRef nodeRef)
|
||||
private String getPrimaryAssocQName(NodeRef nodeRef)
|
||||
{
|
||||
String result = null;
|
||||
try
|
||||
try
|
||||
{
|
||||
ChildAssociationRef primaryParent = nodeService.getPrimaryParent(nodeRef);
|
||||
if(primaryParent != null && primaryParent.getQName() != null)
|
||||
if (primaryParent != null && primaryParent.getQName() != null)
|
||||
{
|
||||
result = primaryParent.getQName().getPrefixedQName(namespaceService).getPrefixString();
|
||||
}
|
||||
} catch (NamespaceException namespaceException)
|
||||
}
|
||||
catch (NamespaceException namespaceException)
|
||||
{
|
||||
LOGGER.error("Cannot return a valid primary association QName: " + namespaceException.getMessage());
|
||||
}
|
||||
@@ -215,8 +224,8 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
v = ((MLText) v).getDefaultValue();
|
||||
}
|
||||
|
||||
filteredProps.put(getQNamePrefixString(k), v);
|
||||
Serializable mappedValue = propertyMapper.map(k, v);
|
||||
filteredProps.put(getQNamePrefixString(k), mappedValue);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -232,7 +241,10 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
final MLText mlTextValue = (MLText) v;
|
||||
final HashMap<String, String> localizedValues = new HashMap<>(mlTextValue.size());
|
||||
mlTextValue.forEach((locale, text) -> localizedValues.put(locale.toString(), text));
|
||||
mlTextValue.forEach((locale, text) -> {
|
||||
Serializable mappedValue = propertyMapper.map(k, text);
|
||||
localizedValues.put(locale.toString(), (String) mappedValue);
|
||||
});
|
||||
filteredProps.put(getQNamePrefixString(k), localizedValues);
|
||||
}
|
||||
});
|
||||
@@ -259,7 +271,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
String sysUserName = AuthenticationUtil.getSystemUserName();
|
||||
if (userName.equals(sysUserName) || (AuthenticationUtil.isMtEnabled()
|
||||
&& userName.startsWith(sysUserName + "@")))
|
||||
&& userName.startsWith(sysUserName + "@")))
|
||||
{
|
||||
userInfo = new UserInfo(userName, userName, "");
|
||||
}
|
||||
@@ -306,11 +318,11 @@ public class NodeResourceHelper implements InitializingBean
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix
|
||||
* returns it in the form {uri}local.
|
||||
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix returns it in the form {uri}local.
|
||||
*
|
||||
* @param k QName
|
||||
* @return a String representing the QName in the format prefix:local or {uri}local.
|
||||
* @param k
|
||||
* QName
|
||||
* @return a String representing the QName in the format prefix:local or {uri}local.
|
||||
*/
|
||||
public String getQNamePrefixString(QName k)
|
||||
{
|
||||
@@ -342,7 +354,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
|
||||
public QName getNodeType(NodeRef nodeRef)
|
||||
{
|
||||
return nodeService.getType(nodeRef);
|
||||
return nodeService.getType(nodeRef);
|
||||
}
|
||||
|
||||
public Serializable getProperty(NodeRef nodeRef, QName qName)
|
||||
@@ -352,13 +364,14 @@ public class NodeResourceHelper implements InitializingBean
|
||||
|
||||
public Map<QName, Serializable> getProperties(NodeRef nodeRef)
|
||||
{
|
||||
//We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
||||
// We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
||||
final boolean toRestore = MLPropertyInterceptor.isMLAware();
|
||||
MLPropertyInterceptor.setMLAware(true);
|
||||
try
|
||||
{
|
||||
return nodeService.getProperties(nodeRef);
|
||||
} finally
|
||||
}
|
||||
finally
|
||||
{
|
||||
MLPropertyInterceptor.setMLAware(toRestore);
|
||||
}
|
||||
@@ -377,7 +390,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
}
|
||||
|
||||
static Map<String, Map<String, String>> getLocalizedPropertiesBefore(Map<String, Map<String, String>> locPropsBefore,
|
||||
Map<String, Map<String, String>> locPropsAfter)
|
||||
Map<String, Map<String, String>> locPropsAfter)
|
||||
{
|
||||
final Map<String, Map<String, String>> result = new HashMap<>(locPropsBefore.size());
|
||||
|
||||
@@ -410,7 +423,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
return mapToNodeAspects(nodeService.getAspects(nodeRef));
|
||||
}
|
||||
|
||||
|
||||
public List<String> getPrimaryHierarchy(NodeRef nodeRef, boolean showLeaf)
|
||||
{
|
||||
final Path path = nodeService.getPath(nodeRef);
|
||||
@@ -420,16 +433,17 @@ public class NodeResourceHelper implements InitializingBean
|
||||
/**
|
||||
* Gathers node's secondary parents.
|
||||
*
|
||||
* @param nodeRef - node reference
|
||||
* @param nodeRef
|
||||
* - node reference
|
||||
* @return a list of node's secondary parents.
|
||||
*/
|
||||
public List<String> getSecondaryParents(final NodeRef nodeRef)
|
||||
{
|
||||
return nodeService.getParentAssocs(nodeRef).stream()
|
||||
.filter(not(ChildAssociationRef::isPrimary))
|
||||
.map(ChildAssociationRef::getParentRef)
|
||||
.map(NodeRef::getId)
|
||||
.collect(Collectors.toList());
|
||||
.filter(not(ChildAssociationRef::isPrimary))
|
||||
.map(ChildAssociationRef::getParentRef)
|
||||
.map(NodeRef::getId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public PermissionService getPermissionService()
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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,160 +26,50 @@
|
||||
package org.alfresco.repo.event2.filter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Abstract {@link EventFilter} implementation, containing common event filtering
|
||||
* functionality for the {@link QName} type.
|
||||
* Abstract {@link EventFilter} implementation, containing common event filtering functionality for the {@link QName} type.
|
||||
*
|
||||
* @author Jamal Kaabi-Mofrad
|
||||
*/
|
||||
public abstract class AbstractNodeEventFilter implements EventFilter<QName>
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNodeEventFilter.class);
|
||||
protected TypeDefExpander typeDefExpander;
|
||||
|
||||
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
||||
private static final String WILDCARD = "*";
|
||||
|
||||
protected DictionaryService dictionaryService;
|
||||
protected NamespaceService namespaceService;
|
||||
|
||||
private Set<QName> excludedTypes;
|
||||
private Set<String> excludedNamespaceURI;
|
||||
|
||||
public AbstractNodeEventFilter()
|
||||
{
|
||||
this.excludedTypes = new HashSet<>();
|
||||
this.excludedNamespaceURI = new HashSet<>();
|
||||
}
|
||||
private QNameMatcher qNameMatcher;
|
||||
|
||||
public final void init()
|
||||
{
|
||||
preprocessExcludedTypes(getExcludedTypes());
|
||||
qNameMatcher = new QNameMatcher(getExcludedTypes());
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
public void setTypeDefExpander(TypeDefExpander typeDefExpander)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
this.typeDefExpander = typeDefExpander;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExcluded(QName qName)
|
||||
{
|
||||
if (qName != null)
|
||||
{
|
||||
return excludedTypes.contains(qName) || excludedNamespaceURI.contains(qName.getNamespaceURI());
|
||||
}
|
||||
return false;
|
||||
return qNameMatcher.isMatching(qName);
|
||||
}
|
||||
|
||||
protected abstract Set<QName> getExcludedTypes();
|
||||
|
||||
protected List<String> parseFilterList(String unparsedFilterList)
|
||||
{
|
||||
List<String> list = new LinkedList<>();
|
||||
|
||||
StringTokenizer st = new StringTokenizer(unparsedFilterList, ",");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String entry = st.nextToken().trim();
|
||||
if (!entry.isEmpty())
|
||||
{
|
||||
if (!entry.equals("none") && !entry.contains("${"))
|
||||
{
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the user-defined list of types into valid QNames. It
|
||||
* validates them against the dictionary and also supports wildcards
|
||||
*/
|
||||
private void preprocessExcludedTypes(Set<QName> excluded)
|
||||
{
|
||||
excluded.forEach(qName -> {
|
||||
if (WILDCARD.equals(qName.getLocalName()))
|
||||
{
|
||||
//excludedPrefixes.add(getPrefix(qName));
|
||||
excludedNamespaceURI.add(qName.getNamespaceURI());
|
||||
}
|
||||
else
|
||||
{
|
||||
excludedTypes.add(qName);
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Excluded namespace URIs:" + excludedNamespaceURI);
|
||||
LOGGER.debug("Excluded types:" + excludedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private QName getQName(String type)
|
||||
{
|
||||
return QName.createQName(type, namespaceService);
|
||||
return CSVStringToListParser.parse(unparsedFilterList);
|
||||
}
|
||||
|
||||
protected Collection<QName> expandTypeDef(String typeDef)
|
||||
{
|
||||
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDef.indexOf(' ') < 0)
|
||||
{
|
||||
return Collections.singleton(getQName(typeDef));
|
||||
}
|
||||
|
||||
String[] typeDefParts = typeDef.split(" ");
|
||||
if (typeDefParts.length != 2)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
||||
{
|
||||
if (typeDefParts[0].indexOf('*') >= 0)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QName baseType;
|
||||
try
|
||||
{
|
||||
baseType = getQName(typeDefParts[0]);
|
||||
}
|
||||
catch (NamespaceException ne)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return dictionaryService.getSubTypes(baseType, true);
|
||||
}
|
||||
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
return typeDefExpander.expand(typeDef);
|
||||
}
|
||||
}
|
||||
|
@@ -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,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.event2.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -43,34 +44,37 @@ public class NodePropertyFilter extends AbstractNodeEventFilter
|
||||
// These properties are included as top-level info,
|
||||
// so exclude them from the properties object
|
||||
private static final Set<QName> EXCLUDED_TOP_LEVEL_PROPS = Set.of(ContentModel.PROP_NAME,
|
||||
ContentModel.PROP_MODIFIER,
|
||||
ContentModel.PROP_MODIFIED,
|
||||
ContentModel.PROP_CREATOR,
|
||||
ContentModel.PROP_CREATED,
|
||||
ContentModel.PROP_CONTENT);
|
||||
ContentModel.PROP_MODIFIER,
|
||||
ContentModel.PROP_MODIFIED,
|
||||
ContentModel.PROP_CREATOR,
|
||||
ContentModel.PROP_CREATED,
|
||||
ContentModel.PROP_CONTENT);
|
||||
// These properties should not be excluded from the properties object
|
||||
private static final Set<QName> ALLOWED_PROPERTIES = Set.of(ContentModel.PROP_CASCADE_TX,
|
||||
ContentModel.PROP_CASCADE_CRC);
|
||||
ContentModel.PROP_CASCADE_CRC);
|
||||
|
||||
private final List<String> nodePropertiesBlackList;
|
||||
private final List<String> nodePropertiesBlackList = new ArrayList<>();
|
||||
|
||||
public NodePropertyFilter()
|
||||
public NodePropertyFilter(String userConfiguredProperties)
|
||||
{
|
||||
this.nodePropertiesBlackList = parseFilterList(FILTERED_PROPERTIES);
|
||||
super();
|
||||
nodePropertiesBlackList.addAll(parseFilterList(FILTERED_PROPERTIES));
|
||||
nodePropertiesBlackList.addAll(parseFilterList(userConfiguredProperties));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getExcludedTypes()
|
||||
{
|
||||
Set<QName> result = new HashSet<>(EXCLUDED_TOP_LEVEL_PROPS);
|
||||
nodePropertiesBlackList.forEach(nodeProperty-> result.addAll(expandTypeDef(nodeProperty)));
|
||||
nodePropertiesBlackList.forEach(nodeProperty -> result.addAll(expandTypeDef(nodeProperty)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExcluded(QName qName)
|
||||
{
|
||||
if(qName != null && ALLOWED_PROPERTIES.contains(qName)){
|
||||
if (qName != null && ALLOWED_PROPERTIES.contains(qName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return super.isExcluded(qName);
|
||||
|
@@ -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
|
||||
@@ -31,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
@@ -41,10 +42,13 @@ import org.alfresco.service.namespace.QName;
|
||||
public class NodeTypeFilter extends AbstractNodeEventFilter
|
||||
{
|
||||
private final List<String> nodeTypesBlackList;
|
||||
private final DictionaryService dictionaryService;
|
||||
|
||||
public NodeTypeFilter(String filteredNodeTypes)
|
||||
public NodeTypeFilter(String filteredNodeTypes, DictionaryService dictionaryService)
|
||||
{
|
||||
super();
|
||||
this.nodeTypesBlackList = parseFilterList(filteredNodeTypes);
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.mapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public interface PropertyMapper
|
||||
{
|
||||
PropertyMapper NO_OP = (propertyQName, value) -> value;
|
||||
|
||||
Serializable map(QName propertyQName, Serializable value);
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.mapper;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class PropertyMapperFactory
|
||||
{
|
||||
private final TypeDefExpander typeDefExpander;
|
||||
|
||||
public PropertyMapperFactory(TypeDefExpander typeDefExpander)
|
||||
{
|
||||
this.typeDefExpander = typeDefExpander;
|
||||
}
|
||||
|
||||
public PropertyMapper createPropertyMapper(String enabled, String userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||
{
|
||||
if ("false".equalsIgnoreCase(enabled))
|
||||
{
|
||||
return PropertyMapper.NO_OP;
|
||||
}
|
||||
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.map(CSVStringToListParser::parse)
|
||||
.map(typeDefExpander::expand)
|
||||
.orElse(Set.of());
|
||||
return new ReplaceSensitivePropertyWithTextMapper(sensitiveProperties, userConfiguredReplacementText);
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.mapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class ReplaceSensitivePropertyWithTextMapper implements PropertyMapper
|
||||
{
|
||||
private static final Set<QName> DEFAULT_SENSITIVE_PROPERTIES = Set.of(
|
||||
ContentModel.PROP_PASSWORD,
|
||||
ContentModel.PROP_SALT,
|
||||
ContentModel.PROP_PASSWORD_HASH,
|
||||
TransferModel.PROP_PASSWORD);
|
||||
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||
|
||||
private final QNameMatcher qNameMatcher;
|
||||
private final String replacementText;
|
||||
|
||||
public ReplaceSensitivePropertyWithTextMapper(Set<QName> userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||
{
|
||||
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||
.filter(Predicate.not(Collection::isEmpty))
|
||||
.orElse(DEFAULT_SENSITIVE_PROPERTIES);
|
||||
qNameMatcher = new QNameMatcher(sensitiveProperties);
|
||||
replacementText = Optional.ofNullable(userConfiguredReplacementText)
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.filter(userInput -> !userInput.contains("${"))
|
||||
.orElse(DEFAULT_REPLACEMENT_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable map(QName propertyQName, Serializable value)
|
||||
{
|
||||
if (qNameMatcher.isMatching(propertyQName))
|
||||
{
|
||||
return replacementText;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.shared;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public final class CSVStringToListParser
|
||||
{
|
||||
private CSVStringToListParser()
|
||||
{}
|
||||
|
||||
public static List<String> parse(String userInputCSV)
|
||||
{
|
||||
List<String> list = new LinkedList<>();
|
||||
|
||||
StringTokenizer st = new StringTokenizer(userInputCSV, ",");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String entry = st.nextToken().trim();
|
||||
if (!entry.isEmpty() && !entry.equals("none") && !entry.contains("${"))
|
||||
{
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.shared;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class QNameMatcher
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(QNameMatcher.class);
|
||||
private static final String WILDCARD = "*";
|
||||
|
||||
private final Set<QName> matchingTypes;
|
||||
private final Set<String> matchingNamespaceURIs;
|
||||
|
||||
public QNameMatcher(Set<QName> qNamesToMatch)
|
||||
{
|
||||
matchingTypes = new HashSet<>();
|
||||
matchingNamespaceURIs = new HashSet<>();
|
||||
|
||||
qNamesToMatch.forEach(qName -> {
|
||||
if (WILDCARD.equals(qName.getLocalName()))
|
||||
{
|
||||
matchingNamespaceURIs.add(qName.getNamespaceURI());
|
||||
}
|
||||
else
|
||||
{
|
||||
matchingTypes.add(qName);
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Matching namespace URIs:" + matchingNamespaceURIs);
|
||||
LOGGER.debug("Matching types:" + matchingTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMatching(QName qName)
|
||||
{
|
||||
if (qName != null)
|
||||
{
|
||||
return matchingTypes.contains(qName) || matchingNamespaceURIs.contains(qName.getNamespaceURI());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class TypeDefExpander
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TypeDefExpander.class);
|
||||
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
||||
|
||||
private final DictionaryService dictionaryService;
|
||||
private final NamespaceService namespaceService;
|
||||
|
||||
public TypeDefExpander(DictionaryService dictionaryService, NamespaceService namespaceService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public Set<QName> expand(Collection<String> types)
|
||||
{
|
||||
Set<QName> result = new HashSet<>();
|
||||
types.forEach(type -> result.addAll(expand(type)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<QName> expand(String typeDef)
|
||||
{
|
||||
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDef.indexOf(' ') < 0)
|
||||
{
|
||||
return Collections.singleton(getQName(typeDef));
|
||||
}
|
||||
|
||||
String[] typeDefParts = typeDef.split(" ");
|
||||
if (typeDefParts.length != 2)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
||||
{
|
||||
if (typeDefParts[0].indexOf('*') >= 0)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QName baseType;
|
||||
try
|
||||
{
|
||||
baseType = getQName(typeDefParts[0]);
|
||||
}
|
||||
catch (NamespaceException ne)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return dictionaryService.getSubTypes(baseType, true);
|
||||
}
|
||||
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private QName getQName(String type)
|
||||
{
|
||||
return QName.createQName(type, namespaceService);
|
||||
}
|
||||
}
|
@@ -28,11 +28,17 @@ package org.alfresco.repo.workflow.activiti.script;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.delegate.VariableScope;
|
||||
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.activiti.engine.impl.context.Context;
|
||||
import org.activiti.engine.impl.el.Expression;
|
||||
import org.activiti.engine.impl.persistence.entity.DeploymentEntity;
|
||||
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.workflow.WorkflowDeployer;
|
||||
@@ -45,13 +51,12 @@ import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
|
||||
/**
|
||||
* Base class for execution scripts, using {@link ScriptService} as part of
|
||||
* activiti workflow.
|
||||
* Base class for execution scripts, using {@link ScriptService} as part of activiti workflow.
|
||||
*
|
||||
* @author Frederik Heremans
|
||||
* @since 3.4.e
|
||||
*/
|
||||
public class ActivitiScriptBase
|
||||
public class ActivitiScriptBase
|
||||
{
|
||||
protected static final String PERSON_BINDING_NAME = "person";
|
||||
protected static final String USERHOME_BINDING_NAME = "userhome";
|
||||
@@ -61,17 +66,19 @@ public class ActivitiScriptBase
|
||||
protected Expression runAs;
|
||||
protected Expression scriptProcessor;
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ActivitiScriptBase.class);
|
||||
|
||||
protected Object executeScript(String theScript, Map<String, Object> model, String scriptProcessorName, String runAsUser)
|
||||
{
|
||||
String user = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
|
||||
|
||||
Object scriptResult = null;
|
||||
if (runAsUser == null && user != null)
|
||||
{
|
||||
// Just execute the script using the current user
|
||||
scriptResult = executeScript(theScript, model, scriptProcessorName);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (runAsUser != null)
|
||||
{
|
||||
@@ -87,26 +94,25 @@ public class ActivitiScriptBase
|
||||
}
|
||||
return scriptResult;
|
||||
}
|
||||
|
||||
|
||||
protected Object executeScriptAsUser(final String theScript, final Map<String, Object> model, final String scriptProcessorName, final String runAsUser)
|
||||
{
|
||||
// execute as specified runAsUser
|
||||
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
return executeScript(theScript, model, scriptProcessorName);
|
||||
}
|
||||
}, runAsUser);
|
||||
}
|
||||
|
||||
|
||||
protected Object executeScript(String theScript, Map<String, Object> model, String scriptProcessorName)
|
||||
{
|
||||
// Execute the script using the appropriate processor
|
||||
Object scriptResult = null;
|
||||
|
||||
// Checks if current workflow is secure
|
||||
boolean secure = isSecure();
|
||||
boolean secure = isSecure(model);
|
||||
|
||||
if (scriptProcessorName != null)
|
||||
{
|
||||
@@ -117,11 +123,11 @@ public class ActivitiScriptBase
|
||||
// Use default script-processor
|
||||
scriptResult = getServiceRegistry().getScriptService().executeScriptString(theScript, model, secure);
|
||||
}
|
||||
|
||||
|
||||
return scriptResult;
|
||||
}
|
||||
|
||||
protected String getStringValue(Expression expression, VariableScope scope)
|
||||
|
||||
protected String getStringValue(Expression expression, VariableScope scope)
|
||||
{
|
||||
if (expression != null)
|
||||
{
|
||||
@@ -133,15 +139,15 @@ public class ActivitiScriptBase
|
||||
protected ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();
|
||||
if (config != null)
|
||||
if (config != null)
|
||||
{
|
||||
// Fetch the registry that is injected in the activiti spring-configuration
|
||||
ServiceRegistry registry = (ServiceRegistry) config.getBeans().get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
|
||||
if (registry == null)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"Service-registry not present in ProcessEngineConfiguration beans, expected ServiceRegistry with key" +
|
||||
ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
|
||||
"Service-registry not present in ProcessEngineConfiguration beans, expected ServiceRegistry with key" +
|
||||
ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
@@ -149,42 +155,136 @@ public class ActivitiScriptBase
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the workflow must be considered secure or not - based on {@link DeploymentEntity} category.
|
||||
* If it is not considered secure, the workflow will be executed in sandbox context with more restrictions
|
||||
* Checks whether the workflow must be considered secure or not - based on {@link DeploymentEntity} category. If it is not considered secure, the workflow will be executed in sandbox context with more restrictions
|
||||
*
|
||||
* @return true if workflow is considered secure, false otherwise
|
||||
*/
|
||||
private boolean isSecure()
|
||||
private boolean isSecure(Map<String, Object> model)
|
||||
{
|
||||
String category = getDeploymentCategory(model);
|
||||
|
||||
// iF The deployment category matches the condition (either internal or full access) the workflow is considered secure
|
||||
return category != null && (WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL.equals(category) || WorkflowDeployer.CATEGORY_FULL_ACCESS.equals(category));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the deployment category from the execution context. If no execution context is available, a query to obtain the deployment is performed so the category can be returned.
|
||||
*
|
||||
* @param model
|
||||
* a map with workflow model
|
||||
* @return the deployment category
|
||||
*/
|
||||
private String getDeploymentCategory(Map<String, Object> model)
|
||||
{
|
||||
String category = getDeploymentCategoryFromContext();
|
||||
|
||||
if (category == null)
|
||||
{
|
||||
String deploymentId = null;
|
||||
String processDefinitionId = null;
|
||||
|
||||
if (model != null && model.containsKey(EXECUTION_BINDING_NAME) && model.get(EXECUTION_BINDING_NAME) instanceof ExecutionEntity)
|
||||
{
|
||||
ExecutionEntity executionEntity = (ExecutionEntity) model.get(EXECUTION_BINDING_NAME);
|
||||
deploymentId = executionEntity.getDeploymentId();
|
||||
processDefinitionId = executionEntity.getProcessDefinitionId();
|
||||
}
|
||||
|
||||
category = getDeploymentCategoryFromQuery(deploymentId, processDefinitionId);
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the deployment category from current execution context
|
||||
*
|
||||
* @return the category for current execution deployment, otherwise null
|
||||
*/
|
||||
private String getDeploymentCategoryFromContext()
|
||||
{
|
||||
String category = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (Context.isExecutionContextActive())
|
||||
{
|
||||
category = Context.getExecutionContext().getDeployment().getCategory();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("No execution context available");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// No action required
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Could not obtain deployment category from execution context: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// If the workflow is considered secure, the deployment entity category matches the condition (either internal or full access)
|
||||
return category != null && (WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL.equals(category) || WorkflowDeployer.CATEGORY_FULL_ACCESS.equals(category));
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified 'runAs' field
|
||||
* specifies a valid username.
|
||||
* Obtains the deployment category through a query
|
||||
*
|
||||
* @param deploymentId
|
||||
* the deployment id to obtain the category from
|
||||
* @param processDefinitionId
|
||||
* if no deployment id is provided, the process definition id can be used to obtain the deployment
|
||||
* @return the category for the obtained deployment, otherwise null
|
||||
*/
|
||||
private void validateRunAsUser(final String runAsUser)
|
||||
private String getDeploymentCategoryFromQuery(String deploymentId, String processDefinitionId)
|
||||
{
|
||||
Boolean runAsExists = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
|
||||
String category = null;
|
||||
|
||||
try
|
||||
{
|
||||
RepositoryService repositoryService = Context.getProcessEngineConfiguration().getRepositoryService();
|
||||
|
||||
if (deploymentId == null && processDefinitionId != null)
|
||||
{
|
||||
ProcessDefinition processDefnition = repositoryService.getProcessDefinition(processDefinitionId);
|
||||
if (processDefnition != null)
|
||||
{
|
||||
deploymentId = processDefnition.getDeploymentId();
|
||||
}
|
||||
}
|
||||
|
||||
if (deploymentId != null)
|
||||
{
|
||||
DeploymentEntity deployment = (DeploymentEntity) repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
|
||||
if (deployment != null)
|
||||
{
|
||||
category = deployment.getCategory();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Could not obtain deployment category through a query: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified 'runAs' field specifies a valid username.
|
||||
*/
|
||||
private void validateRunAsUser(final String runAsUser)
|
||||
{
|
||||
Boolean runAsExists = AuthenticationUtil.runAs(new RunAsWork<Boolean>() {
|
||||
// Validate using System user to ensure sufficient permissions available to access person node.
|
||||
|
||||
public Boolean doWork() throws Exception
|
||||
@Override
|
||||
public Boolean doWork() throws Exception
|
||||
{
|
||||
return getServiceRegistry().getPersonService().personExists(runAsUser);
|
||||
}
|
||||
@@ -195,21 +295,21 @@ public class ActivitiScriptBase
|
||||
throw new WorkflowException("runas user '" + runAsUser + "' does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ActivitiScriptNode getPersonNode(String runAsUser)
|
||||
{
|
||||
String userName = null;
|
||||
if (runAsUser != null)
|
||||
if (runAsUser != null)
|
||||
{
|
||||
userName = runAsUser;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
userName = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
|
||||
|
||||
// The "System" user is a special case, which has no person object associated with it.
|
||||
if(userName != null && !AuthenticationUtil.SYSTEM_USER_NAME.equals(userName))
|
||||
if (userName != null && !AuthenticationUtil.SYSTEM_USER_NAME.equals(userName))
|
||||
{
|
||||
ServiceRegistry services = getServiceRegistry();
|
||||
PersonService personService = services.getPersonService();
|
||||
@@ -221,18 +321,18 @@ public class ActivitiScriptBase
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setScript(Expression script)
|
||||
|
||||
public void setScript(Expression script)
|
||||
{
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
public void setRunAs(Expression runAs)
|
||||
public void setRunAs(Expression runAs)
|
||||
{
|
||||
this.runAs = runAs;
|
||||
}
|
||||
|
||||
public void setScriptProcessor(Expression scriptProcessor)
|
||||
public void setScriptProcessor(Expression scriptProcessor)
|
||||
{
|
||||
this.scriptProcessor = scriptProcessor;
|
||||
}
|
||||
|
@@ -1,266 +1,298 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.service.cmr.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The public API by which applications can query the audit logs and enable or disable auditing.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface AuditService
|
||||
{
|
||||
/**
|
||||
* @return Returns <tt>true</tt> if auditing is globally enabled
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
boolean isAuditEnabled();
|
||||
|
||||
/**
|
||||
* Enable or disable the global auditing state
|
||||
*
|
||||
* @param enable <tt>true</tt> to enable auditing globally or <tt>false</tt> to disable
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
void setAuditEnabled(boolean enable);
|
||||
|
||||
/**
|
||||
* Helper bean to carry information about an audit application.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.4
|
||||
*/
|
||||
public static class AuditApplication
|
||||
{
|
||||
private final String name;
|
||||
private final String key;
|
||||
private final boolean enabled;
|
||||
/**
|
||||
* Constructor for final variables
|
||||
*/
|
||||
public AuditApplication(String name, String key, boolean enabled)
|
||||
{
|
||||
this.name = name;
|
||||
this.key = key;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered audit applications
|
||||
*
|
||||
* @return Returns a map of audit applications keyed by their name
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
Map<String, AuditApplication> getAuditApplications();
|
||||
|
||||
/**
|
||||
* @param applicationName the name of the application to check
|
||||
* @param path the path to check
|
||||
* @return Returns <tt>true</tt> if auditing is enabled for the given path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean isAuditEnabled(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Enable auditing for an application path
|
||||
*
|
||||
* @param applicationName the name of the application to check
|
||||
* @param path the path to enable
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void enableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Disable auditing for an application path
|
||||
*
|
||||
* @param applicationName the name of the application to check
|
||||
* @param path the path to disable
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void disableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Remove all audit entries for the given application
|
||||
*
|
||||
* @param applicationName the name of the application for which to remove entries
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @deprecated Use {@link #clearAudit(String, Long, Long)}
|
||||
*/
|
||||
int clearAudit(String applicationName);
|
||||
|
||||
/**
|
||||
* Remove audit entries for the given application between the time ranges. If no start
|
||||
* time is given then entries are deleted as far back as they exist. If no end time is
|
||||
* given then entries are deleted up until the current time.
|
||||
*
|
||||
* @param applicationName the name of the application for which to remove entries
|
||||
* @param fromTime the start time of entries to remove (inclusive and optional)
|
||||
* @param toTime the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
int clearAudit(String applicationName, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Remove audit entries for the given application between the audit entry ids.
|
||||
*
|
||||
* @param applicationName the name of the application for which to remove entries
|
||||
* @param fromId the start time of entries to remove (inclusive and optional)
|
||||
* @param toId the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int clearAuditByIdRange(String applicationName, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries.
|
||||
* <p/>
|
||||
* This method should not be called <i>while</i> processing
|
||||
* {@link #auditQuery(AuditQueryCallback, AuditQueryParameters, int) query results}.
|
||||
*
|
||||
* @param auditEntryIds the IDs of all audit entries to delete
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
int clearAudit(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* The interface that will be used to give query results to the calling code.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static interface AuditQueryCallback
|
||||
{
|
||||
/**
|
||||
* Determines whether this callback requires the values argument to be populated when {@link #handleAuditEntry}
|
||||
* is called.
|
||||
*
|
||||
* @return <code>true</code> if this callback requires the values argument to be populated
|
||||
*/
|
||||
boolean valuesRequired();
|
||||
|
||||
/**
|
||||
* Handle a row of audit entry data.
|
||||
*
|
||||
* @param entryId the unique audit entry ID
|
||||
* @param applicationName the name of the application
|
||||
* @param user the user that logged the entry
|
||||
* @param time the time of the entry
|
||||
* @param values the values map as created
|
||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||
*/
|
||||
boolean handleAuditEntry(
|
||||
Long entryId,
|
||||
String applicationName,
|
||||
String user,
|
||||
long time,
|
||||
Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* Handle audit entry failures
|
||||
*
|
||||
* @param entryId the entry ID
|
||||
* @param errorMsg the error message
|
||||
* @param error the exception causing the error (may be <tt>null</tt>)
|
||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||
*/
|
||||
boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query using the given parameters and consuming results in the callback.
|
||||
* Results are returned in entry order, corresponding to time order.
|
||||
*
|
||||
* @param callback the callback that will handle results
|
||||
* @param parameters the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException if maxResults less or equal to zero
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @param extremes a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName the name of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application and properties
|
||||
*
|
||||
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.service.cmr.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The public API by which applications can query the audit logs and enable or disable auditing.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface AuditService
|
||||
{
|
||||
/**
|
||||
* @return Returns <tt>true</tt> if auditing is globally enabled
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
boolean isAuditEnabled();
|
||||
|
||||
/**
|
||||
* Enable or disable the global auditing state
|
||||
*
|
||||
* @param enable
|
||||
* <tt>true</tt> to enable auditing globally or <tt>false</tt> to disable
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
void setAuditEnabled(boolean enable);
|
||||
|
||||
/**
|
||||
* Helper bean to carry information about an audit application.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.4
|
||||
*/
|
||||
public static class AuditApplication
|
||||
{
|
||||
private final String name;
|
||||
private final String key;
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Constructor for final variables
|
||||
*/
|
||||
public AuditApplication(String name, String key, boolean enabled)
|
||||
{
|
||||
this.name = name;
|
||||
this.key = key;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered audit applications
|
||||
*
|
||||
* @return Returns a map of audit applications keyed by their name
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
Map<String, AuditApplication> getAuditApplications();
|
||||
|
||||
/**
|
||||
* @param applicationName
|
||||
* the name of the application to check
|
||||
* @param path
|
||||
* the path to check
|
||||
* @return Returns <tt>true</tt> if auditing is enabled for the given path
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean isAuditEnabled(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Enable auditing for an application path
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application to check
|
||||
* @param path
|
||||
* the path to enable
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void enableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Disable auditing for an application path
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application to check
|
||||
* @param path
|
||||
* the path to disable
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
void disableAudit(String applicationName, String path);
|
||||
|
||||
/**
|
||||
* Remove all audit entries for the given application
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application for which to remove entries
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @deprecated Use {@link #clearAudit(String, Long, Long)}
|
||||
*/
|
||||
int clearAudit(String applicationName);
|
||||
|
||||
/**
|
||||
* Remove audit entries for the given application between the time ranges. If no start time is given then entries are deleted as far back as they exist. If no end time is given then entries are deleted up until the current time.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application for which to remove entries
|
||||
* @param fromTime
|
||||
* the start time of entries to remove (inclusive and optional)
|
||||
* @param toTime
|
||||
* the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
int clearAudit(String applicationName, Long fromTime, Long toTime);
|
||||
|
||||
/**
|
||||
* Remove audit entries for the given application between the audit entry ids.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application for which to remove entries
|
||||
* @param fromId
|
||||
* the start time of entries to remove (inclusive and optional)
|
||||
* @param toId
|
||||
* the end time of entries to remove (exclusive and optional)
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 5.2.2
|
||||
*/
|
||||
int clearAuditByIdRange(String applicationName, Long fromId, Long toId);
|
||||
|
||||
/**
|
||||
* Delete a discrete list of audit entries.
|
||||
* <p/>
|
||||
* This method should not be called <i>while</i> processing {@link #auditQuery(AuditQueryCallback, AuditQueryParameters, int) query results}.
|
||||
*
|
||||
* @param auditEntryIds
|
||||
* the IDs of all audit entries to delete
|
||||
* @return Returns the number of audit entries deleted
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
int clearAudit(List<Long> auditEntryIds);
|
||||
|
||||
/**
|
||||
* The interface that will be used to give query results to the calling code.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static interface AuditQueryCallback
|
||||
{
|
||||
/**
|
||||
* Determines whether this callback requires the values argument to be populated when {@link #handleAuditEntry} is called.
|
||||
*
|
||||
* @return <code>true</code> if this callback requires the values argument to be populated
|
||||
*/
|
||||
boolean valuesRequired();
|
||||
|
||||
/**
|
||||
* Handle a row of audit entry data.
|
||||
*
|
||||
* @param entryId
|
||||
* the unique audit entry ID
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param user
|
||||
* the user that logged the entry
|
||||
* @param time
|
||||
* the time of the entry
|
||||
* @param values
|
||||
* the values map as created
|
||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||
*/
|
||||
boolean handleAuditEntry(
|
||||
Long entryId,
|
||||
String applicationName,
|
||||
String user,
|
||||
long time,
|
||||
Map<String, Serializable> values);
|
||||
|
||||
/**
|
||||
* Handle audit entry failures
|
||||
*
|
||||
* @param entryId
|
||||
* the entry ID
|
||||
* @param errorMsg
|
||||
* the error message
|
||||
* @param error
|
||||
* the exception causing the error (may be <tt>null</tt>)
|
||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||
*/
|
||||
boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query using the given parameters and consuming results in the callback. Results are returned in entry order, corresponding to time order.
|
||||
*
|
||||
* @param callback
|
||||
* the callback that will handle results
|
||||
* @param parameters
|
||||
* the parameters for the query (may not be <tt>null</tt>)
|
||||
* @param maxResults
|
||||
* the maximum number of results to retrieve (must be greater than 0)
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if maxResults less or equal to zero
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param extremes
|
||||
* a list containing min/max or both
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes);
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application.
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByApp(String applicationName)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an audit query to retrieve min / max audit record id for a given application and properties
|
||||
*
|
||||
* @param applicationName
|
||||
* the name of the application
|
||||
* @param parameters
|
||||
* audit parameters provided by the <code>where</code> clause on the ReST API
|
||||
* @return a map containing min/max and the associated value
|
||||
*/
|
||||
default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -143,7 +143,7 @@
|
||||
</bean>
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.dialect.Dialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl" parent="nodeDAObase" />
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.dialect.MySQLInnoDBDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MySQL" parent="nodeDAO.org.alfresco.repo.domain.dialect.Dialect" />
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.dialect.AlfrescoSQLServerDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MSSQL" parent="nodeDAO.org.alfresco.repo.domain.dialect.Dialect" />
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.dialect.SQLServerDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MSSQL" parent="nodeDAO.org.alfresco.repo.domain.dialect.Dialect" />
|
||||
|
||||
<!-- WARNING: Experimental/unsupported - see MySQLClusterNDBDialect ! -->
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.dialect.AlfrescoMySQLClusterNDBDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MySQLClusterNDB" parent="nodeDAO.org.alfresco.repo.domain.dialect.Dialect" />
|
||||
|
@@ -3,23 +3,30 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="event2TypeDefExpander" class="org.alfresco.repo.event2.shared.TypeDefExpander">
|
||||
<constructor-arg ref="dictionaryService"/>
|
||||
<constructor-arg ref="namespaceService"/>
|
||||
</bean>
|
||||
|
||||
<!-- Event2 Filters -->
|
||||
<bean id="event2FilterRegistry" class="org.alfresco.repo.event2.filter.EventFilterRegistry"/>
|
||||
|
||||
<bean id="abstractNodeEventFilter" class="org.alfresco.repo.event2.filter.AbstractNodeEventFilter" abstract="true" init-method="init">
|
||||
<property name="dictionaryService" ref="dictionaryService"/>
|
||||
<property name="namespaceService" ref="namespaceService"/>
|
||||
<property name="typeDefExpander" ref="event2TypeDefExpander"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodeTypeFilter" class="org.alfresco.repo.event2.filter.NodeTypeFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeTypes}"/>
|
||||
<constructor-arg ref="dictionaryService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodeAspectFilter" class="org.alfresco.repo.event2.filter.NodeAspectFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeAspects}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter"/>
|
||||
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeProperties}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2UserFilter" class="org.alfresco.repo.event2.filter.EventUserFilter">
|
||||
<constructor-arg value="${repo.event2.filter.users}"/>
|
||||
@@ -31,6 +38,16 @@
|
||||
</bean>
|
||||
<!-- End of Event2 Filters -->
|
||||
|
||||
<bean id="event2PropertyMapperFactory" class="org.alfresco.repo.event2.mapper.PropertyMapperFactory">
|
||||
<constructor-arg ref="event2TypeDefExpander"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2PropertyMapper" factory-bean="event2PropertyMapperFactory" factory-method="createPropertyMapper">
|
||||
<constructor-arg value="${repo.event2.mapper.enabled}"/>
|
||||
<constructor-arg value="${repo.event2.mapper.overrideDefaultProperties}"/>
|
||||
<constructor-arg value="${repo.event2.mapper.overrideReplacementText}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="baseEventGeneratorV2" abstract="true">
|
||||
<property name="policyComponent" ref="policyComponent"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
@@ -53,6 +70,7 @@
|
||||
<property name="eventFilterRegistry" ref="event2FilterRegistry"/>
|
||||
<property name="namespaceService" ref="namespaceService"/>
|
||||
<property name="permissionService" ref="permissionService"/>
|
||||
<property name="propertyMapper" ref="event2PropertyMapper"/>
|
||||
</bean>
|
||||
|
||||
<bean id="baseEventSender" abstract="true">
|
||||
|
@@ -1234,6 +1234,10 @@ repo.event2.filter.childAssocTypes=rn:rendition
|
||||
# Comma separated list of users which should be excluded
|
||||
# Note: username's case-sensitivity depends on the {user.name.caseSensitive} setting
|
||||
repo.event2.filter.users=
|
||||
repo.event2.filter.nodeProperties=
|
||||
repo.event2.mapper.enabled=true
|
||||
repo.event2.mapper.overrideDefaultProperties=
|
||||
repo.event2.mapper.overrideReplacementText=
|
||||
# Topic name
|
||||
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
|
||||
# Specifies the strategy for sending the events
|
||||
@@ -1393,4 +1397,4 @@ default.async.folder.items=1000
|
||||
# Default NodeSize Thread pool
|
||||
default.nodeSize.corePoolSize=5
|
||||
default.nodeSize.maximumPoolSize=10
|
||||
default.nodeSize.workQueueSize=100
|
||||
default.nodeSize.workQueueSize=100
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 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
|
||||
@@ -53,6 +53,7 @@ import org.junit.runners.Suite;
|
||||
|
||||
// From AppContext05TestSuite
|
||||
org.alfresco.repo.domain.node.NodeDAOTest.class,
|
||||
org.alfresco.repo.domain.subscriptions.SubscriptionDAOTest.class,
|
||||
org.alfresco.repo.security.permissions.impl.AclDaoComponentTest.class,
|
||||
org.alfresco.repo.domain.contentdata.ContentDataDAOTest.class,
|
||||
org.alfresco.repo.domain.encoding.EncodingDAOTest.class,
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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
|
||||
@@ -34,6 +34,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
@@ -44,7 +48,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -53,15 +56,13 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.test.junitrules.ApplicationContextInit;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* This class contains tests for {@link ImporterActionExecuter}.
|
||||
*
|
||||
* @author abalmus
|
||||
*/
|
||||
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
|
||||
public class ImporterActionExecuterTest
|
||||
{
|
||||
// Rule to initialise the default Alfresco spring configuration
|
||||
@@ -87,8 +88,7 @@ public class ImporterActionExecuterTest
|
||||
AuthenticationUtil.setRunAsUserSystem();
|
||||
|
||||
// we need a store
|
||||
storeRef = serviceRegistry.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<StoreRef>()
|
||||
{
|
||||
storeRef = serviceRegistry.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<StoreRef>() {
|
||||
public StoreRef execute()
|
||||
{
|
||||
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
|
||||
@@ -102,8 +102,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
try
|
||||
{
|
||||
serviceRegistry.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
serviceRegistry.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
if (storeRef != null)
|
||||
@@ -125,8 +124,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
@@ -162,8 +160,7 @@ public class ImporterActionExecuterTest
|
||||
}
|
||||
|
||||
/**
|
||||
* MNT-16292: Unzipped files which have folders do not get the cm:titled
|
||||
* aspect applied
|
||||
* MNT-16292: Unzipped files which have folders do not get the cm:titled aspect applied
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@@ -172,8 +169,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
@@ -190,7 +186,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
importerActionExecuter.execute(action, zipFileNodeRef);
|
||||
|
||||
// check if import succeeded
|
||||
// check if import succeeded
|
||||
NodeRef importedFolder = nodeService.getChildByName(targetFolderNodeRef, ContentModel.ASSOC_CONTAINS, "folderCmTitledAspectArchive");
|
||||
assertNotNull("import action failed", importedFolder);
|
||||
|
||||
@@ -199,7 +195,7 @@ public class ImporterActionExecuterTest
|
||||
assertTrue("folder didn't get the cm:titled aspect applied", hasAspectTitled);
|
||||
|
||||
// MNT-17017 check ContentModel.PROP_TITLE is not set on the top level folder, just like Share
|
||||
String title = (String)nodeService.getProperty(importedFolder, ContentModel.PROP_TITLE);
|
||||
String title = (String) nodeService.getProperty(importedFolder, ContentModel.PROP_TITLE);
|
||||
assertNull("The title should not have cm:title set", title);
|
||||
}
|
||||
finally
|
||||
@@ -224,8 +220,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
@@ -270,8 +265,7 @@ public class ImporterActionExecuterTest
|
||||
{
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
@@ -306,11 +300,51 @@ public class ImporterActionExecuterTest
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnzipZipFileHavingAccentCharInFolderName() throws IOException
|
||||
{
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
|
||||
{
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
// create test data
|
||||
NodeRef zipFileNodeRef = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT).getChildRef();
|
||||
NodeRef targetFolderNodeRef = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_FOLDER).getChildRef();
|
||||
|
||||
putContent(zipFileNodeRef, "import-archive-test/accentCharTestZip.zip");
|
||||
|
||||
Action action = createAction(zipFileNodeRef, "ImporterActionExecuterTestActionDefinition", targetFolderNodeRef);
|
||||
|
||||
try
|
||||
{
|
||||
importerActionExecuter.setUncompressedBytesLimit("100000");
|
||||
importerActionExecuter.execute(action, zipFileNodeRef);
|
||||
NodeRef importedFolder = nodeService.getChildByName(targetFolderNodeRef, ContentModel.ASSOC_CONTAINS, "accentCharTestZip");
|
||||
assertNotNull("unzip action failed", importedFolder);
|
||||
assertTrue("multiple folder structure created", nodeService.getChildAssocs(importedFolder).size() == 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// clean test data
|
||||
nodeService.deleteNode(targetFolderNodeRef);
|
||||
nodeService.deleteNode(zipFileNodeRef);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void putContent(NodeRef zipFileNodeRef, String resource)
|
||||
{
|
||||
URL url = AbstractContentTransformerTest.class.getClassLoader().getResource(resource);
|
||||
final File file = new File(url.getFile());
|
||||
|
||||
|
||||
ContentWriter writer = contentService.getWriter(zipFileNodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_ZIP);
|
||||
writer.putContent(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
|
||||
@@ -41,11 +41,11 @@ import org.alfresco.service.cmr.subscriptions.SubscriptionItemTypeEnum;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.testing.category.NeverRunsTests;
|
||||
import org.alfresco.util.testing.category.DBTests;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
@Category({OwnJVMTestsCategory.class, NeverRunsTests.class})
|
||||
@Category({OwnJVMTestsCategory.class, DBTests.class})
|
||||
public class SubscriptionDAOTest extends TestCase
|
||||
{
|
||||
private ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
|
||||
public class CSVStringToListParserUnitTest
|
||||
{
|
||||
@Test
|
||||
public void shouldIgnoreEmptySpacesAndNoneValueAndTemplateStringsAndParseTheRest()
|
||||
{
|
||||
String userInputCSV = "a,,none,2,${test}, ,*";
|
||||
|
||||
List<String> result = CSVStringToListParser.parse(userInputCSV);
|
||||
|
||||
List<String> expected = List.of("a", "2", "*");
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
@@ -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
|
||||
@@ -35,6 +35,10 @@ import static org.mockito.Mockito.when;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.model.RenditionModel;
|
||||
@@ -43,14 +47,12 @@ import org.alfresco.repo.event2.filter.EventUserFilter;
|
||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||
import org.alfresco.repo.event2.filter.NodeTypeFilter;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.OneToManyHashBiMap;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
/**
|
||||
* Tests event filters.
|
||||
@@ -78,32 +80,32 @@ public class EventFilterUnitTest
|
||||
|
||||
namespaceService = new MockNamespaceServiceImpl();
|
||||
namespaceService.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX,
|
||||
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX,
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.FORUMS_MODEL_PREFIX,
|
||||
NamespaceService.FORUMS_MODEL_1_0_URI);
|
||||
NamespaceService.FORUMS_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.RENDITION_MODEL_PREFIX,
|
||||
NamespaceService.RENDITION_MODEL_1_0_URI);
|
||||
NamespaceService.RENDITION_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(ContentModel.USER_MODEL_PREFIX,
|
||||
ContentModel.USER_MODEL_URI);
|
||||
|
||||
propertyFilter = new NodePropertyFilter();
|
||||
propertyFilter.setNamespaceService(namespaceService);
|
||||
propertyFilter.setDictionaryService(dictionaryService);
|
||||
TypeDefExpander typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||
|
||||
propertyFilter = new NodePropertyFilter("usr:password");
|
||||
propertyFilter.setTypeDefExpander(typeDefExpander);
|
||||
propertyFilter.init();
|
||||
|
||||
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail");
|
||||
typeFilter.setNamespaceService(namespaceService);
|
||||
typeFilter.setDictionaryService(dictionaryService);
|
||||
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail", dictionaryService);
|
||||
typeFilter.setTypeDefExpander(typeDefExpander);
|
||||
typeFilter.init();
|
||||
|
||||
aspectFilter = new NodeAspectFilter("cm:workingcopy");
|
||||
aspectFilter.setNamespaceService(namespaceService);
|
||||
aspectFilter.setDictionaryService(dictionaryService);
|
||||
aspectFilter.setTypeDefExpander(typeDefExpander);
|
||||
aspectFilter.init();
|
||||
|
||||
childAssociationTypeFilter = new ChildAssociationTypeFilter("rn:rendition");
|
||||
childAssociationTypeFilter.setNamespaceService(namespaceService);
|
||||
childAssociationTypeFilter.setDictionaryService(dictionaryService);
|
||||
childAssociationTypeFilter.setTypeDefExpander(typeDefExpander);
|
||||
childAssociationTypeFilter.init();
|
||||
|
||||
caseInsensitive_userFilter = new EventUserFilter("System, john.doe, null", false);
|
||||
@@ -114,10 +116,12 @@ public class EventFilterUnitTest
|
||||
public void nodePropertyFilter()
|
||||
{
|
||||
assertTrue("System properties are excluded by default.",
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
||||
|
||||
assertTrue("System properties are excluded by default.",
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
||||
|
||||
assertTrue("User configured properties are excluded.", propertyFilter.isExcluded(ContentModel.PROP_PASSWORD));
|
||||
|
||||
assertFalse("Property cascadeTx is not excluded", propertyFilter.isExcluded(ContentModel.PROP_CASCADE_TX));
|
||||
assertFalse("Property cascadeCRC is not excluded", propertyFilter.isExcluded(ContentModel.PROP_CASCADE_CRC));
|
||||
@@ -129,16 +133,16 @@ public class EventFilterUnitTest
|
||||
public void nodeTypeFilter()
|
||||
{
|
||||
assertTrue("Thumbnail node type should have been filtered.",
|
||||
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
||||
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
||||
|
||||
assertTrue("System folder node types are excluded by default.",
|
||||
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
||||
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
||||
|
||||
assertTrue("System node type should have been filtered (sys:*).",
|
||||
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
||||
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
||||
|
||||
assertTrue("Forum node type should have been filtered (fm:*).",
|
||||
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
||||
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
||||
|
||||
assertFalse(typeFilter.isExcluded(ContentModel.TYPE_FOLDER));
|
||||
}
|
||||
@@ -147,7 +151,7 @@ public class EventFilterUnitTest
|
||||
public void nodeAspectFilter()
|
||||
{
|
||||
assertTrue("Working copy aspect should have been filtered.",
|
||||
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
||||
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
||||
|
||||
assertFalse(aspectFilter.isExcluded(ContentModel.ASPECT_TITLED));
|
||||
}
|
||||
@@ -160,41 +164,41 @@ public class EventFilterUnitTest
|
||||
|
||||
assertFalse(childAssociationTypeFilter.isExcluded(ContentModel.ASSOC_CONTAINS));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void userFilter_case_insensitive()
|
||||
{
|
||||
assertTrue("System user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("System"));
|
||||
caseInsensitive_userFilter.isExcluded("System"));
|
||||
|
||||
assertTrue("System user should have been filtered (case-insensitive).",
|
||||
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
||||
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
||||
|
||||
assertTrue("'null' user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("null"));
|
||||
caseInsensitive_userFilter.isExcluded("null"));
|
||||
|
||||
assertTrue("john.doe user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
||||
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
||||
|
||||
assertFalse("'jane.doe' user should not have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
||||
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userFilter_case_sensitive()
|
||||
{
|
||||
assertFalse("'system' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("system"));
|
||||
caseSensitive_userFilter.isExcluded("system"));
|
||||
assertTrue("'System' user should have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("System"));
|
||||
caseSensitive_userFilter.isExcluded("System"));
|
||||
|
||||
assertFalse("'John.Doe' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("John.Doe"));
|
||||
caseSensitive_userFilter.isExcluded("John.Doe"));
|
||||
assertTrue("'john.doe' user should have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("john.doe"));
|
||||
caseSensitive_userFilter.isExcluded("john.doe"));
|
||||
|
||||
assertFalse("'jane.doe' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("jane.doe"));
|
||||
caseSensitive_userFilter.isExcluded("jane.doe"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||
import org.alfresco.repo.event2.mapper.ReplaceSensitivePropertyWithTextMapper;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
|
||||
public class PropertyMapperUnitTest
|
||||
{
|
||||
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||
private static final String USER_CONFIGURED_REPLACEMENT_TEXT = "HIDDEN_BY_SECURITY_CONFIG";
|
||||
|
||||
private final PropertyMapper defaultPropertyMapper = new ReplaceSensitivePropertyWithTextMapper(null, null);
|
||||
private final PropertyMapper userConfiguredpropertyMapper = new ReplaceSensitivePropertyWithTextMapper(
|
||||
Set.of(ContentModel.PROP_PASSWORD, TransferModel.PROP_PASSWORD),
|
||||
USER_CONFIGURED_REPLACEMENT_TEXT);
|
||||
|
||||
@Test
|
||||
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||
{
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_SALT, UUID.randomUUID().toString()));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||
{
|
||||
assertEquals("Bob", defaultPropertyMapper.map(ContentModel.PROP_USERNAME, "Bob"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||
{
|
||||
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||
|
||||
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||
{
|
||||
String randomUuid = UUID.randomUUID().toString();
|
||||
assertEquals(randomUuid, userConfiguredpropertyMapper.map(ContentModel.PROP_SALT, randomUuid));
|
||||
assertEquals("r4nD0M_h4sH", userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class QNameMatcherUnitTest
|
||||
{
|
||||
@Test
|
||||
public void shouldMatchOnlyQNamesFromUserModelURI()
|
||||
{
|
||||
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(QName.createQName(ContentModel.USER_MODEL_URI, "*")));
|
||||
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.TYPE_USER));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_TITLE));
|
||||
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldOnlyMatchSpecificQName()
|
||||
{
|
||||
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(ContentModel.PROP_USER_USERNAME));
|
||||
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_NAME));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(null));
|
||||
}
|
||||
}
|
@@ -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
|
||||
@@ -30,12 +30,15 @@ import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ EventFilterUnitTest.class,
|
||||
EventConsolidatorUnitTest.class,
|
||||
EventJSONSchemaUnitTest.class,
|
||||
EnqueuingEventSenderUnitTest.class,
|
||||
NodeResourceHelperUnitTest.class
|
||||
@SuiteClasses({EventFilterUnitTest.class,
|
||||
EventConsolidatorUnitTest.class,
|
||||
EventJSONSchemaUnitTest.class,
|
||||
EnqueuingEventSenderUnitTest.class,
|
||||
NodeResourceHelperUnitTest.class,
|
||||
PropertyMapperUnitTest.class,
|
||||
QNameMatcherUnitTest.class,
|
||||
CSVStringToListParserUnitTest.class,
|
||||
TypeDefExpanderUnitTest.class
|
||||
})
|
||||
public class RepoEvent2UnitSuite
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 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
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.DataListModel;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class TypeDefExpanderUnitTest
|
||||
{
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private TypeDefExpander typeDefExpander;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
dictionaryService = mock(DictionaryService.class);
|
||||
namespaceService = mock(NamespaceService.class);
|
||||
typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithValidType()
|
||||
{
|
||||
String input = "usr:username";
|
||||
when(namespaceService.getNamespaceURI("usr")).thenReturn(ContentModel.USER_MODEL_URI);
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
QName expected = ContentModel.PROP_USER_USERNAME;
|
||||
assertEquals(expected, result.iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithValidTypeIncludingSubtypes()
|
||||
{
|
||||
String input = "cm:content include_subtypes";
|
||||
when(namespaceService.getNamespaceURI("cm")).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
Set<QName> subtypes = Set.of(TransferModel.TYPE_TRANSFER_RECORD, DataListModel.TYPE_EVENT, WorkflowModel.TYPE_TASK);
|
||||
when(dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true)).thenReturn(subtypes);
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
assertEquals(subtypes, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithInvalidTypes()
|
||||
{
|
||||
Set<String> input = Stream.of(null, " ", "none", "${test.prop}").collect(Collectors.toSet());
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
}
|
@@ -36,7 +36,7 @@ identity-service.enable-pkce=true
|
||||
identity-service.ignore-oauth-query-parameter=true
|
||||
identity-service.credentials.secret=
|
||||
identity-service.credentials.provider=secret
|
||||
identity-service.client-socket-timeout=1000
|
||||
identity-service.client-socket-timeout=3000
|
||||
identity-service.client-connection-timeout=3000
|
||||
identity-service.authentication.enable-username-password-authentication=true
|
||||
|
||||
|
Binary file not shown.
@@ -59,11 +59,11 @@ services:
|
||||
CLIENT_SSL_TRUST_STORE_TYPE: "JCEKS"
|
||||
keycloak:
|
||||
profiles: ["with-sso"]
|
||||
image: quay.io/keycloak/keycloak:25.0.6
|
||||
image: quay.io/keycloak/keycloak:26.1.0
|
||||
environment:
|
||||
- KEYCLOAK_ADMIN=admin
|
||||
- KEYCLOAK_ADMIN_PASSWORD=admin
|
||||
- KC_DB=dev-mem
|
||||
- KC_BOOTSTRAP_ADMIN_USERNAME=admin
|
||||
- KC_BOOTSTRAP_ADMIN_PASSWORD=admin
|
||||
- KC_DB=dev-file
|
||||
command: ["start-dev", "--import-realm", "--http-relative-path=/auth", "--hostname=localhost", "--http-enabled=true"]
|
||||
volumes:
|
||||
- ../../../repository/src/test/resources/realms/alfresco-realm.json:/opt/keycloak/data/import/alfresco-realm.json
|
||||
|
Reference in New Issue
Block a user