Compare commits

..

73 Commits

Author SHA1 Message Date
alfresco-build
1e55a06512 [maven-release-plugin][skip ci] prepare release 23.4.2.1 2024-12-23 16:51:14 +00:00
Eva Vasques
ad52aac0a4 [skip tests] Prepare version 23.4.2 (#3110) 2024-12-23 16:48:21 +00:00
alfresco-build
535651a682 [maven-release-plugin][skip ci] prepare for next development iteration 2024-12-17 18:48:16 +00:00
alfresco-build
9e14db2ee6 [maven-release-plugin][skip ci] prepare release 23.4.1.1 2024-12-17 18:48:14 +00:00
Eva Vasques
2652cdaa98 Revert "[MNT-24137] Audit Issue Internal Server Error fix (#2786)" (#3100)
* Revert "[MNT-24137] Audit Issue Internal Server Error fix (#2786)"

This reverts commit cabc38b386.

* Pre-commit changes
2024-12-17 18:05:46 +00:00
Kacper Magdziarz
b595e41095 Creating hotfix branch release/23.4 for 23.4.0 ACS release [skip ci] 2024-11-20 13:35:21 +01:00
alfresco-build
0cf3eec834 [maven-release-plugin][skip ci] prepare release 23.4.0.67 2024-11-19 09:48:12 +00:00
MohinishSah
dfd855440d bumped aos version 2024-11-19 14:38:12 +05:30
alfresco-build
88d46884c4 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-17 00:08:12 +00:00
alfresco-build
e6444a1c7a [maven-release-plugin][skip ci] prepare release 23.4.0.66 2024-11-17 00:08:10 +00:00
Alfresco CI User
e215038230 [force] Force release for 2024-11-17. 2024-11-17 00:04:44 +00:00
alfresco-build
a5f8034725 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-15 09:54:37 +00:00
alfresco-build
c7dd659268 [maven-release-plugin][skip ci] prepare release 23.4.0.65 2024-11-15 09:54:35 +00:00
Sara
ffae77169e ACS-8937 Bump IE/SS to 2.0.13 (#3040) 2024-11-15 09:12:11 +00:00
alfresco-build
3bcfaf256e [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-14 18:30:28 +00:00
alfresco-build
0e8d56d7b2 [maven-release-plugin][skip ci] prepare release 23.4.0.64 2024-11-14 18:30:25 +00:00
Piotr Żurek
ef9e8d574f ACS-8935 Use GA dependencies (#3037) 2024-11-14 18:47:51 +01:00
alfresco-build
a17712b501 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-14 14:03:54 +00:00
alfresco-build
fce6d1d7eb [maven-release-plugin][skip ci] prepare release 23.4.0.63 2024-11-14 14:03:52 +00:00
mohit-singh4
867af27a96 Fix/apps 2894 node size details automation sample test file (#3036)
* Adding the test case for calculating the NodeSize.

* Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationSampleTestFile] Updating sample testfile which being used for calculating the NodeSize.

---------

Co-authored-by: kshah <kavit.shah@hyland.com>
Co-authored-by: mohit-singh4 <mohit.singh@contractors.hyland.com>
2024-11-14 18:53:27 +05:30
alfresco-build
3de74456ae [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-13 10:46:53 +00:00
alfresco-build
919880e363 [maven-release-plugin][skip ci] prepare release 23.4.0.62 2024-11-13 10:46:52 +00:00
mohit-singh4
e6ac2875b9 Fix/apps 2894 node size details automation test (#3032)
* Adding the test case for calculating the NodeSize.

* Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

* [fix/APPS-2894_NodeSizeDetails_AutomationTest] Adding the test case for calculating the NodeSize.

---------

Co-authored-by: kshah <kavit.shah@hyland.com>
Co-authored-by: mohit-singh4 <mohit.singh@contractors.hyland.com>
2024-11-13 15:32:54 +05:30
alfresco-build
4250167a28 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-10 00:07:40 +00:00
alfresco-build
312463b5e0 [maven-release-plugin][skip ci] prepare release 23.4.0.61 2024-11-10 00:07:38 +00:00
Alfresco CI User
c09f5f7cb0 [force] Force release for 2024-11-10. 2024-11-10 00:04:32 +00:00
alfresco-build
6284e9724e [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-08 14:28:59 +00:00
alfresco-build
dcf391faea [maven-release-plugin][skip ci] prepare release 23.4.0.60 2024-11-08 14:28:57 +00:00
kavitshah-gl
475f345909 Bump api explorer to 23.4.0-A1 2024-11-08 18:28:44 +05:30
alfresco-build
f42e033e40 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-08 10:48:14 +00:00
alfresco-build
546f37eded [maven-release-plugin][skip ci] prepare release 23.4.0.59 2024-11-08 10:48:12 +00:00
mohit-singh4
a35673d44f [MNT-24127] Added Endpoint To Calculate Folder Size (#2709)
* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [MNT-24127] Added Endpoint to Calculate Size of the folder with Integration Test Cases [ags][tas]

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] EndpointToCalculateFolderSize

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* [feature/MNT-24127] Endpoint Added To Calculate Folder Size

* Some Optimization for NodeSize Calculation.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding performance test case

* [feature/MNT-24127-EndpointToCalculateFolderSize] Added endpoints implementation to calculate folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Added endpoints implementation to calculate folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Added endpoints implementation to calculate folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Added endpoints implementation to calculate folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Adding endpoints to calculate and retrieve folder size

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* Changes as per the Relationship Api Framework implementation.

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Updated endpoints flow to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments related to calculate and retrieve folder size details

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments and refactoring files

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments and refactoring files

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments and refactoring files

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments and refactoring files

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments regarding Integeration testcases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments regarding Integeration testcases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Addressing review comments

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Creating Integeration test cases

* [feature/MNT-24127-EndpointToCalculateFolderSize] Some Changes in NodeSizeDetailsTests

* [feature/MNT-24127-EndpointToCalculateFolderSize] Some Changes in NodeSizeDetailsTests

* [feature/MNT-24127-EndpointToCalculateFolderSize] Some Changes in NodeSizeDetailsTests

* [feature/MNT-24127-EndpointToCalculateFolderSize] Some Changes in NodeSizeDetailsTests

* [feature/MNT-24127-EndpointToCalculateFolderSize] Checking size-details feature for solr6 subsystem

* [feature/MNT-24127-EndpointToCalculateFolderSize] Checking size-details feature for solr6 subsystem

---------

Co-authored-by: kshah <kavit.shah@globallogic.com>
Co-authored-by: mohit-singh4 <mohit.singh@contractors.hyland.com>
Co-authored-by: kshah <kavit.shah@hyland.com>
2024-11-08 15:37:27 +05:30
alfresco-build
25e9bdbdb6 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-08 06:37:38 +00:00
alfresco-build
33ab26e52b [maven-release-plugin][skip ci] prepare release 23.4.0.58 2024-11-08 06:37:36 +00:00
rrajoria
7e35abfdc8 Update aos version to 3.2.0-A2 2024-11-08 10:28:04 +05:30
alfresco-build
634e591264 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-07 18:44:42 +00:00
alfresco-build
86f66c86da [maven-release-plugin][skip ci] prepare release 23.4.0.57 2024-11-07 18:44:40 +00:00
Eva Vasques
2904535d40 MNT-24708 - Set messagesCache and loadedBundlesCache as local (#3026)
* In a cluster env these caches were always invalidating the other nodes loaded bundles, forcing them to reload
* Only resourceBundlesNamesCache should be invalidating to be able to force the cache reset if a bundle is added, removed or reloaded dynamically
* On unregister of a resource bundle, the cache wasn't being explicitly updated, so it was not invalidating the cache on the other nodes.
2024-11-07 18:03:52 +00:00
alfresco-build
e99905efbd [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-07 13:09:09 +00:00
alfresco-build
ce65de0f10 [maven-release-plugin][skip ci] prepare release 23.4.0.56 2024-11-07 13:09:07 +00:00
Piotr Żurek
29b19d4245 ACS-8936 Propagate latest Search Service (#3025) 2024-11-07 12:54:06 +01:00
alfresco-build
4eea43bddf [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-05 23:04:52 +00:00
alfresco-build
4c9282790a [maven-release-plugin][skip ci] prepare release 23.4.0.55 2024-11-05 23:04:50 +00:00
Sara
39a74e42b6 ACS-8934 Bump ATS 4.1.5-A3 (#3022) 2024-11-05 18:57:01 +00:00
alfresco-build
a298c0dcb9 [maven-release-plugin][skip ci] prepare for next development iteration 2024-11-03 00:07:36 +00:00
alfresco-build
9ee56a5d08 [maven-release-plugin][skip ci] prepare release 23.4.0.54 2024-11-03 00:07:34 +00:00
Alfresco CI User
6b80a2c39c [force] Force release for 2024-11-03. 2024-11-03 00:04:31 +00:00
alfresco-build
f6569edde1 [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-28 13:55:04 +00:00
alfresco-build
5ab9aa8cf2 [maven-release-plugin][skip ci] prepare release 23.4.0.53 2024-10-28 13:55:02 +00:00
Damian Ujma
8a171d09b5 ACS-8915 Propagate latest ATS/AIS (#3012) 2024-10-28 14:15:03 +01:00
alfresco-build
3e423a1543 [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-27 00:07:40 +00:00
alfresco-build
6351782c1d [maven-release-plugin][skip ci] prepare release 23.4.0.52 2024-10-27 00:07:38 +00:00
Alfresco CI User
4c92868efb [force] Force release for 2024-10-27. 2024-10-27 00:04:27 +00:00
alfresco-build
2cca9ea11b [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-25 11:06:31 +00:00
alfresco-build
e12001e4d1 [maven-release-plugin][skip ci] prepare release 23.4.0.51 2024-10-25 11:06:29 +00:00
dependabot[bot]
a57607f728 Bump org.springframework:spring-context from 6.1.13 to 6.1.14 (#3002)
Bumps [org.springframework:spring-context](https://github.com/spring-projects/spring-framework) from 6.1.13 to 6.1.14.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.13...v6.1.14)

---
updated-dependencies:
- dependency-name: org.springframework:spring-context
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-25 10:49:56 +02:00
dependabot[bot]
a79af2cac0 Bump org.springframework.security:spring-security-bom (#3004)
Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 6.3.3 to 6.3.4.
- [Release notes](https://github.com/spring-projects/spring-security/releases)
- [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc)
- [Commits](https://github.com/spring-projects/spring-security/compare/6.3.3...6.3.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-25 10:14:37 +02:00
alfresco-build
be807c5b19 [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-24 11:58:56 +00:00
alfresco-build
ae03e7076e [maven-release-plugin][skip ci] prepare release 23.4.0.50 2024-10-24 11:58:54 +00:00
Damian Ujma
26e394c398 ACS-6670 Change nodesSharedCache to fully-distributed (#3007) 2024-10-24 13:00:04 +02:00
alfresco-build
200aa95784 [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-20 00:07:31 +00:00
alfresco-build
4eeabb3dbd [maven-release-plugin][skip ci] prepare release 23.4.0.49 2024-10-20 00:07:29 +00:00
Alfresco CI User
227bbe4fd8 [force] Force release for 2024-10-20. 2024-10-20 00:04:38 +00:00
alfresco-build
1461a04a3d [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-16 13:08:10 +00:00
alfresco-build
52008dc139 [maven-release-plugin][skip ci] prepare release 23.4.0.48 2024-10-16 13:08:09 +00:00
rrajoria
f2a10052e4 Bump aos version 3.2.0-A1 (#2999) 2024-10-16 17:57:11 +05:30
alfresco-build
add64e0cb6 [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-13 00:07:36 +00:00
alfresco-build
14511e2621 [maven-release-plugin][skip ci] prepare release 23.4.0.47 2024-10-13 00:07:34 +00:00
Alfresco CI User
42e0c93121 [force] Force release for 2024-10-13. 2024-10-13 00:04:33 +00:00
alfresco-build
715bc273ee [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-11 12:42:44 +00:00
alfresco-build
812541870e [maven-release-plugin][skip ci] prepare release 23.4.0.46 2024-10-11 12:42:39 +00:00
dependabot[bot]
9aa5051826 Bump commons-io:commons-io from 2.16.1 to 2.17.0 (#2928)
Bumps commons-io:commons-io from 2.16.1 to 2.17.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-11 14:00:02 +02:00
alfresco-build
54580b4aeb [maven-release-plugin][skip ci] prepare for next development iteration 2024-10-10 09:55:40 +00:00
57 changed files with 5111 additions and 3007 deletions

View File

@@ -731,7 +731,7 @@
"filename": "remote-api/src/test/java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java", "filename": "remote-api/src/test/java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java",
"hashed_secret": "d033e22ae348aeb5660fc2140aec35850c4da997", "hashed_secret": "d033e22ae348aeb5660fc2140aec35850c4da997",
"is_verified": false, "is_verified": false,
"line_number": 120, "line_number": 111,
"is_secret": false "is_secret": false
} }
], ],
@@ -1888,5 +1888,5 @@
} }
] ]
}, },
"generated_at": "2024-10-02T10:18:47Z" "generated_at": "2024-10-09T09:32:52Z"
} }

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId> <artifactId>alfresco-community-repo-amps</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<modules> <modules>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId> <artifactId>alfresco-governance-services-community-parent</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<modules> <modules>

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId> <artifactId>alfresco-governance-services-community-parent</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<modules> <modules>

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.12 SOLR6_TAG=2.0.13
POSTGRES_TAG=15.4 POSTGRES_TAG=15.4
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8 ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8

View File

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

View File

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

View File

@@ -33,14 +33,15 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; 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.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; 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 * RM V3.3 Hold audit entries values patch unit test
* *
@@ -55,7 +56,6 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
@InjectMocks @InjectMocks
private RMv33HoldAuditEntryValuesPatch patch; private RMv33HoldAuditEntryValuesPatch patch;
@Before @Before
public void setUp() public void setUp()
{ {
@@ -93,15 +93,15 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity); verify(mockedRecordsManagementQueryDAO, times(1)).updatePropertyStringValueEntity(deleteHoldPropertyStringValueEntity);
assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue()); assertEquals("Add To Hold", addToHoldPropertyStringValueEntity.getStringValue());
assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringLower()); assertEquals("add to hold", addToHoldPropertyStringValueEntity.getStringEndLower());
assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc()); assertEquals(Long.valueOf(770_786_109L), addToHoldPropertyStringValueEntity.getStringCrc());
assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue()); assertEquals("Remove From Hold", removeFromHoldPropertyStringValueEntity.getStringValue());
assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringLower()); assertEquals("remove from hold", removeFromHoldPropertyStringValueEntity.getStringEndLower());
assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc()); assertEquals(Long.valueOf(2_967_613_012L), removeFromHoldPropertyStringValueEntity.getStringCrc());
assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue()); assertEquals("Delete Hold", deleteHoldPropertyStringValueEntity.getStringValue());
assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringLower()); assertEquals("delete hold", deleteHoldPropertyStringValueEntity.getStringEndLower());
assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc()); assertEquals(Long.valueOf(132_640_810L), deleteHoldPropertyStringValueEntity.getStringCrc());
} }
@@ -123,5 +123,3 @@ public class RMv33HoldAuditEntryValuesPatchUnitTest
verify(mockedRecordsManagementQueryDAO, times(0)).updatePropertyStringValueEntity(any()); verify(mockedRecordsManagementQueryDAO, times(0)).updatePropertyStringValueEntity(any());
} }
} }

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<modules> <modules>

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<dependencies> <dependencies>

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<modules> <modules>

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.12 SOLR6_TAG=2.0.13
POSTGRES_TAG=15.4 POSTGRES_TAG=15.4
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8 ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<organization> <organization>

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,141 @@
/*-
* #%L
* alfresco-tas-restapi
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.model;
import java.util.Date;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.IRestModel;
import org.alfresco.utility.model.TestModel;
public class RestSizeDetailsModel extends TestModel implements IRestModel<RestSizeDetailsModel>
{
@JsonProperty(value = "entry")
RestSizeDetailsModel model;
private String id;
private Long sizeInBytes;
private Date calculatedAt;
private Integer numberOfFiles;
private String jobId;
private STATUS status;
public enum STATUS
{
NOT_INITIATED, PENDING, IN_PROGRESS, COMPLETED, FAILED
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Long getSizeInBytes()
{
return sizeInBytes;
}
public void setSizeInBytes(Long sizeInBytes)
{
this.sizeInBytes = sizeInBytes;
}
public Date getCalculatedAt()
{
return calculatedAt;
}
public void setCalculatedAt(Date calculatedAt)
{
this.calculatedAt = calculatedAt;
}
public Integer getNumberOfFiles()
{
return numberOfFiles;
}
public void setNumberOfFiles(Integer numberOfFiles)
{
this.numberOfFiles = numberOfFiles;
}
public String getJobId()
{
return jobId;
}
public void setJobId(String jobId)
{
this.jobId = jobId;
}
public STATUS getStatus()
{
return status;
}
public void setStatus(STATUS status)
{
this.status = status;
}
@Override
public RestSizeDetailsModel onModel()
{
return model;
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
RestSizeDetailsModel that = (RestSizeDetailsModel) o;
return Objects.equals(id, that.id) && Objects.equals(sizeInBytes, that.sizeInBytes) && Objects.equals(
calculatedAt, that.calculatedAt) && Objects.equals(numberOfFiles, that.numberOfFiles)
&& Objects.equals(jobId, that.jobId) && status == that.status;
}
@Override
public int hashCode()
{
return Objects.hash(id, sizeInBytes, calculatedAt, numberOfFiles, jobId, status);
}
}

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* alfresco-tas-restapi * alfresco-tas-restapi
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -26,59 +26,34 @@
package org.alfresco.rest.requests; package org.alfresco.rest.requests;
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
import static org.springframework.http.HttpMethod.PUT; import static org.springframework.http.HttpMethod.PUT;
import jakarta.json.JsonArrayBuilder; import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import jakarta.json.JsonArrayBuilder;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.reporters.Files;
import org.alfresco.rest.core.JsonBodyGenerator; import org.alfresco.rest.core.JsonBodyGenerator;
import org.alfresco.rest.core.RestRequest; import org.alfresco.rest.core.RestRequest;
import org.alfresco.rest.core.RestResponse; import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.core.RestWrapper; import org.alfresco.rest.core.RestWrapper;
import org.alfresco.rest.exception.JsonToModelConversionException; import org.alfresco.rest.exception.JsonToModelConversionException;
import org.alfresco.rest.model.RestActionDefinitionModelsCollection; import org.alfresco.rest.model.*;
import org.alfresco.rest.model.RestCategoryLinkBodyModel;
import org.alfresco.rest.model.RestCategoryModel;
import org.alfresco.rest.model.RestCategoryModelsCollection;
import org.alfresco.rest.model.RestCommentModel;
import org.alfresco.rest.model.RestCommentModelsCollection;
import org.alfresco.rest.model.RestNodeAssocTargetModel;
import org.alfresco.rest.model.RestNodeAssociationModel;
import org.alfresco.rest.model.RestNodeAssociationModelCollection;
import org.alfresco.rest.model.RestNodeAssociationTypeModel;
import org.alfresco.rest.model.RestNodeBodyModel;
import org.alfresco.rest.model.RestNodeBodyMoveCopyModel;
import org.alfresco.rest.model.RestNodeChildAssocModelCollection;
import org.alfresco.rest.model.RestNodeChildAssociationModel;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.rest.model.RestNodeModelsCollection;
import org.alfresco.rest.model.RestRatingModel;
import org.alfresco.rest.model.RestRatingModelsCollection;
import org.alfresco.rest.model.RestRenditionInfoModel;
import org.alfresco.rest.model.RestRenditionInfoModelCollection;
import org.alfresco.rest.model.RestRuleExecutionModel;
import org.alfresco.rest.model.RestRuleSetLinkModel;
import org.alfresco.rest.model.RestRuleSetModel;
import org.alfresco.rest.model.RestRuleSetModelsCollection;
import org.alfresco.rest.model.RestTagModel;
import org.alfresco.rest.model.RestTagModelsCollection;
import org.alfresco.rest.model.RestVersionModel;
import org.alfresco.rest.model.RestVersionModelsCollection;
import org.alfresco.rest.model.body.RestNodeLockBodyModel; import org.alfresco.rest.model.body.RestNodeLockBodyModel;
import org.alfresco.rest.model.builder.NodesBuilder; import org.alfresco.rest.model.builder.NodesBuilder;
import org.alfresco.utility.Utility; import org.alfresco.utility.Utility;
import org.alfresco.utility.model.RepoTestModel; import org.alfresco.utility.model.RepoTestModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.reporters.Files;
/** /**
* Declares all Rest API under the /nodes path * Declares all Rest API under the /nodes path
@@ -294,6 +269,7 @@ public class Node extends ModelRequest<Node>
/** /**
* *
* Get fivestar rating of a document using GET call on "nodes/{nodeId}/ratings/{ratingId}" * Get fivestar rating of a document using GET call on "nodes/{nodeId}/ratings/{ratingId}"
*
* @return * @return
*/ */
public RestRatingModel getFiveStarRating() public RestRatingModel getFiveStarRating()
@@ -336,7 +312,6 @@ public class Node extends ModelRequest<Node>
return restWrapper.processModels(RestTagModelsCollection.class, request); return restWrapper.processModels(RestTagModelsCollection.class, request);
} }
/** /**
* Deletes a tag for a specific content node using DELETE call on nodes/{nodeId}/tags/{tagId} * Deletes a tag for a specific content node using DELETE call on nodes/{nodeId}/tags/{tagId}
* *
@@ -381,6 +356,7 @@ public class Node extends ModelRequest<Node>
* You need to specify first the multipart call {@link RestWrapper#usingMultipartFile(java.io.File)} * You need to specify first the multipart call {@link RestWrapper#usingMultipartFile(java.io.File)}
* *
* <code>usingMultipartFile(new File("your-local-file.txt")).withCoreAPI().usingNode(ContentModel.my()).createNode();</code> * <code>usingMultipartFile(new File("your-local-file.txt")).withCoreAPI().usingNode(ContentModel.my()).createNode();</code>
*
* @return * @return
*/ */
public RestNodeModel createNode() public RestNodeModel createNode()
@@ -415,7 +391,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Create node rendition using POST call on '/nodes/{nodeId}/renditions' * Create node rendition using POST call on '/nodes/{nodeId}/renditions'
* *
* @param renditionId id of rendition to be created * @param renditionId
* id of rendition to be created
* @return * @return
*/ */
public void createNodeRendition(String renditionId) public void createNodeRendition(String renditionId)
@@ -428,8 +405,10 @@ public class Node extends ModelRequest<Node>
/** /**
* Create node version rendition using POST call on '/nodes/{nodeId}/versions/{versionId}/renditions' * Create node version rendition using POST call on '/nodes/{nodeId}/versions/{versionId}/renditions'
* *
* @param renditionId id of rendition to be created * @param renditionId
* @param versionId version id of node * id of rendition to be created
* @param versionId
* version id of node
* @return * @return
*/ */
public void createNodeVersionRendition(String renditionId, String versionId) public void createNodeVersionRendition(String renditionId, String versionId)
@@ -442,10 +421,10 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Check if specified rendition exists and if not * Check if specified rendition exists and if not create node rendition using POST call on '/nodes/{nodeId}/renditions'
* create node rendition using POST call on '/nodes/{nodeId}/renditions'
* *
* @param renditionId id of rendition to be created * @param renditionId
* id of rendition to be created
* @return * @return
*/ */
public void createNodeRenditionIfNotExists(String renditionId) public void createNodeRenditionIfNotExists(String renditionId)
@@ -460,9 +439,10 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node rendition using GET call on '/nodes/{nodeId}/renditions/{renditionId} * Get node rendition using GET call on '/nodes/{nodeId}/renditions/{renditionId}
* *
* @param renditionId id of rendition to be retrieved * @param renditionId
* id of rendition to be retrieved
* @return * @return
*/ */
public RestRenditionInfoModel getNodeRendition(String renditionId) public RestRenditionInfoModel getNodeRendition(String renditionId)
@@ -474,8 +454,10 @@ public class Node extends ModelRequest<Node>
/** /**
* Get node version rendition using GET call on '/nodes/{nodeId}/versions/{versionId}renditions/{renditionId} * Get node version rendition using GET call on '/nodes/{nodeId}/versions/{versionId}renditions/{renditionId}
* *
* @param renditionId id of rendition to be retrieved * @param renditionId
* @param versionId versionId of the node * id of rendition to be retrieved
* @param versionId
* versionId of the node
* @return * @return
*/ */
public RestRenditionInfoModel getNodeVersionRendition(String renditionId, String versionId) public RestRenditionInfoModel getNodeVersionRendition(String renditionId, String versionId)
@@ -487,8 +469,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node rendition using GET call on 'nodes/{nodeId}/renditions/{renditionId} Please note that it retries to get * Get node rendition using GET call on 'nodes/{nodeId}/renditions/{renditionId} Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
* the renditions response several times because on the alfresco server the rendition can take a while to be created.
* *
* @return * @return
*/ */
@@ -510,8 +491,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node version rendition using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} Please note that it retries to get * Get node version rendition using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
* the renditions response several times because on the alfresco server the rendition can take a while to be created.
* *
* @return * @return
*/ */
@@ -533,10 +513,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node rendition content using GET call on * Get node rendition content using GET call on 'nodes/{nodeId}/renditions/{renditionId}/content Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
* 'nodes/{nodeId}/renditions/{renditionId}/content Please note that it
* retries to get the renditions response several times because on the
* alfresco server the rendition can take a while to be created.
* *
* @return * @return
*/ */
@@ -546,7 +523,7 @@ public class Node extends ModelRequest<Node>
renditionId); renditionId);
RestResponse response = restWrapper.process(request); RestResponse response = restWrapper.process(request);
int retry = 0; int retry = 0;
//Multiplied by '8' because AI rendition test cases need more time (~30 seconds) - see ACS-2158 // Multiplied by '8' because AI rendition test cases need more time (~30 seconds) - see ACS-2158
while (!Integer.valueOf(response.getStatusCode()).equals(HttpStatus.OK.value()) && retry < (8 * Utility.retryCountSeconds)) while (!Integer.valueOf(response.getStatusCode()).equals(HttpStatus.OK.value()) && retry < (8 * Utility.retryCountSeconds))
{ {
Utility.waitToLoopTime(1); Utility.waitToLoopTime(1);
@@ -558,10 +535,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node version rendition content using GET call on * Get node version rendition content using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
* 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content Please note that it
* retries to get the renditions response several times because on the
* alfresco server the rendition can take a while to be created.
* *
* @return * @return
*/ */
@@ -582,8 +556,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node rendition content using GET call on * Get node rendition content using GET call on 'nodes/{nodeId}/renditions/{renditionId}/content
* 'nodes/{nodeId}/renditions/{renditionId}/content
* *
* @return * @return
*/ */
@@ -595,8 +568,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get node version rendition content using GET call on * Get node version rendition content using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
* 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
* *
* @return * @return
*/ */
@@ -608,8 +580,8 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get rendition information for available renditions for the node using GET call on * Get rendition information for available renditions for the node using GET call on 'nodes/{nodeId}/renditions'
* 'nodes/{nodeId}/renditions' *
* @return * @return
*/ */
public RestRenditionInfoModelCollection getNodeRenditionsInfo() public RestRenditionInfoModelCollection getNodeRenditionsInfo()
@@ -620,8 +592,8 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Get rendition information for available renditions for the node version using GET call on * Get rendition information for available renditions for the node version using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions'
* 'nodes/{nodeId}/versions/{versionId}/renditions' *
* @return * @return
*/ */
public RestRenditionInfoModelCollection getNodeVersionRenditionsInfo(String versionId) public RestRenditionInfoModelCollection getNodeVersionRenditionsInfo(String versionId)
@@ -631,11 +603,11 @@ public class Node extends ModelRequest<Node>
return restWrapper.processModels(RestRenditionInfoModelCollection.class, request); return restWrapper.processModels(RestRenditionInfoModelCollection.class, request);
} }
/** /**
* Delete the rendition identified by renditionId using DELETE call on "/nodes/{nodeId}/renditions/{renditionId}" * Delete the rendition identified by renditionId using DELETE call on "/nodes/{nodeId}/renditions/{renditionId}"
* *
* @param renditionId id of rendition to delete * @param renditionId
* id of rendition to delete
*/ */
public void deleteNodeRendition(String renditionId) public void deleteNodeRendition(String renditionId)
{ {
@@ -657,7 +629,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Move a node to a target folder * Move a node to a target folder
* *
* @param moveBody a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id * @param moveBody
* a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
* @return the moved node's new information * @return the moved node's new information
*/ */
public RestNodeModel move(RestNodeBodyMoveCopyModel moveBody) public RestNodeModel move(RestNodeBodyMoveCopyModel moveBody)
@@ -669,7 +642,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Copy a node to a target folder * Copy a node to a target folder
* *
* @param copyBody a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id * @param copyBody
* a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
* @return the moved node's new information * @return the moved node's new information
*/ */
public RestNodeModel copy(RestNodeBodyMoveCopyModel copyBody) public RestNodeModel copy(RestNodeBodyMoveCopyModel copyBody)
@@ -679,7 +653,6 @@ public class Node extends ModelRequest<Node>
return restWrapper.processModel(RestNodeModel.class, request); return restWrapper.processModel(RestNodeModel.class, request);
} }
/** /**
* Lock a specific node using POST call on "nodes/{nodeId}/lock" * Lock a specific node using POST call on "nodes/{nodeId}/lock"
* *
@@ -747,8 +720,7 @@ public class Node extends ModelRequest<Node>
} }
/** /**
* Delete a target for a specific node using DELETE call on * Delete a target for a specific node using DELETE call on nodes/{nodeId}/targets/{targetId}
* nodes/{nodeId}/targets/{targetId}
* *
* @param target * @param target
*/ */
@@ -830,7 +802,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param secondaryChild - node, which should become a secondary child * @param secondaryChild
* - node, which should become a secondary child
* @return a node's parent-child association * @return a node's parent-child association
*/ */
public RestNodeChildAssociationModel addSecondaryChild(RepoTestModel secondaryChild) public RestNodeChildAssociationModel addSecondaryChild(RepoTestModel secondaryChild)
@@ -841,8 +814,10 @@ public class Node extends ModelRequest<Node>
/** /**
* Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param associationType - type of secondary parent-child relationship association * @param associationType
* @param secondaryChild - node, which should become a secondary child * - type of secondary parent-child relationship association
* @param secondaryChild
* - node, which should become a secondary child
* @return a node's parent-child association * @return a node's parent-child association
*/ */
public RestNodeChildAssociationModel addSecondaryChild(String associationType, RepoTestModel secondaryChild) public RestNodeChildAssociationModel addSecondaryChild(String associationType, RepoTestModel secondaryChild)
@@ -853,7 +828,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param secondaryChildAssociation - node's secondary parent-child association model * @param secondaryChildAssociation
* - node's secondary parent-child association model
* @return a node's parent-child association * @return a node's parent-child association
*/ */
public RestNodeChildAssociationModel addSecondaryChild(RestNodeChildAssociationModel secondaryChildAssociation) public RestNodeChildAssociationModel addSecondaryChild(RestNodeChildAssociationModel secondaryChildAssociation)
@@ -865,7 +841,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param secondaryChildren - nodes, which should become secondary children * @param secondaryChildren
* - nodes, which should become secondary children
* @return a collection of node's parent-child associations * @return a collection of node's parent-child associations
*/ */
public RestNodeChildAssocModelCollection addSecondaryChildren(RepoTestModel... secondaryChildren) public RestNodeChildAssocModelCollection addSecondaryChildren(RepoTestModel... secondaryChildren)
@@ -876,21 +853,24 @@ public class Node extends ModelRequest<Node>
/** /**
* Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param associationType - type of secondary parent-child relationship association * @param associationType
* @param secondaryChildren - nodes, which should become secondary children * - type of secondary parent-child relationship association
* @param secondaryChildren
* - nodes, which should become secondary children
* @return a collection of node's parent-child associations * @return a collection of node's parent-child associations
*/ */
public RestNodeChildAssocModelCollection addSecondaryChildren(String associationType, RepoTestModel... secondaryChildren) public RestNodeChildAssocModelCollection addSecondaryChildren(String associationType, RepoTestModel... secondaryChildren)
{ {
return addSecondaryChildren(Stream.of(secondaryChildren) return addSecondaryChildren(Stream.of(secondaryChildren)
.map(child -> new RestNodeChildAssociationModel(child.getNodeRef(), associationType)) .map(child -> new RestNodeChildAssociationModel(child.getNodeRef(), associationType))
.toArray(RestNodeChildAssociationModel[]::new)); .toArray(RestNodeChildAssociationModel[]::new));
} }
/** /**
* Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'. * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
* *
* @param secondaryChildrenAssociations - node's secondary parent-child association models * @param secondaryChildrenAssociations
* - node's secondary parent-child association models
* @return a collection of node's parent-child associations * @return a collection of node's parent-child associations
*/ */
public RestNodeChildAssocModelCollection addSecondaryChildren(RestNodeChildAssociationModel... secondaryChildrenAssociations) public RestNodeChildAssocModelCollection addSecondaryChildren(RestNodeChildAssociationModel... secondaryChildrenAssociations)
@@ -903,7 +883,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'. * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
* *
* @param secondaryChild - node, which should NOT be a secondary child anymore * @param secondaryChild
* - node, which should NOT be a secondary child anymore
*/ */
public void removeSecondaryChild(RepoTestModel secondaryChild) public void removeSecondaryChild(RepoTestModel secondaryChild)
{ {
@@ -913,8 +894,10 @@ public class Node extends ModelRequest<Node>
/** /**
* Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'. * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
* *
* @param associationType - type of secondary parent-child relationship association * @param associationType
* @param secondaryChild - node, which should NOT be a secondary child anymore * - type of secondary parent-child relationship association
* @param secondaryChild
* - node, which should NOT be a secondary child anymore
*/ */
public void removeSecondaryChild(String associationType, RepoTestModel secondaryChild) public void removeSecondaryChild(String associationType, RepoTestModel secondaryChild)
{ {
@@ -932,13 +915,12 @@ public class Node extends ModelRequest<Node>
/** /**
* Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'. * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
* *
* @param secondaryChildAssociation - node's secondary parent-child association to remove * @param secondaryChildAssociation
* - node's secondary parent-child association to remove
*/ */
public void removeSecondaryChild(RestNodeAssociationModel secondaryChildAssociation) public void removeSecondaryChild(RestNodeAssociationModel secondaryChildAssociation)
{ {
String parameters = StringUtils.isNotEmpty(secondaryChildAssociation.getAssociation().getAssocType()) ? String parameters = StringUtils.isNotEmpty(secondaryChildAssociation.getAssociation().getAssocType()) ? "assocType=" + secondaryChildAssociation.getAssociation().getAssocType() + "&" + restWrapper.getParameters() : restWrapper.getParameters();
"assocType=" + secondaryChildAssociation.getAssociation().getAssocType() + "&" + restWrapper.getParameters() :
restWrapper.getParameters();
RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/secondary-children/{childId}?{parameters}", repoModel.getNodeRef(), secondaryChildAssociation.getId(), parameters); RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/secondary-children/{childId}?{parameters}", repoModel.getNodeRef(), secondaryChildAssociation.getId(), parameters);
restWrapper.processEmptyModel(request); restWrapper.processEmptyModel(request);
} }
@@ -1013,7 +995,6 @@ public class Node extends ModelRequest<Node>
deleteNode(nodeModel.getId()); deleteNode(nodeModel.getId());
} }
/** /**
* Delete a specific node using DELETE call on nodes/{nodeId} * Delete a specific node using DELETE call on nodes/{nodeId}
* *
@@ -1035,6 +1016,7 @@ public class Node extends ModelRequest<Node>
/** /**
* Get Direct Access URL for a node * Get Direct Access URL for a node
*
* @param postBody * @param postBody
* @return * @return
*/ */
@@ -1055,6 +1037,7 @@ public class Node extends ModelRequest<Node>
/** /**
* Get Direct Access URL for a specific node rendition E.g "pdf" * Get Direct Access URL for a specific node rendition E.g "pdf"
*
* @param renditionId * @param renditionId
* @return * @return
*/ */
@@ -1067,6 +1050,7 @@ public class Node extends ModelRequest<Node>
/** /**
* Get Direct Access URL for a specific node version. E.g "1.1" * Get Direct Access URL for a specific node version. E.g "1.1"
*
* @param versionId * @param versionId
* @return * @return
*/ */
@@ -1079,6 +1063,7 @@ public class Node extends ModelRequest<Node>
/** /**
* Get Direct Access URL for a specific node version rendition. E.g ("1.1", "pdf") * Get Direct Access URL for a specific node version rendition. E.g ("1.1", "pdf")
*
* @param versionId * @param versionId
* @param renditionId * @param renditionId
* @return * @return
@@ -1132,7 +1117,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Get the specified rule set from a folder. * Get the specified rule set from a folder.
* *
* @param ruleSetId The id of the rule set. * @param ruleSetId
* The id of the rule set.
* @return The specified rule set. * @return The specified rule set.
*/ */
public RestRuleSetModel getRuleSet(String ruleSetId) public RestRuleSetModel getRuleSet(String ruleSetId)
@@ -1145,7 +1131,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Update a rule set on this folder - for example to reorder the rules. * Update a rule set on this folder - for example to reorder the rules.
* *
* @param ruleSet The updated rule set. * @param ruleSet
* The updated rule set.
* @return The updated rule set returned by the server. * @return The updated rule set returned by the server.
*/ */
public RestRuleSetModel updateRuleSet(RestRuleSetModel ruleSet) public RestRuleSetModel updateRuleSet(RestRuleSetModel ruleSet)
@@ -1188,7 +1175,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Try to delete a ruleset link performing a DELETE call on "/nodes/{folderNodeId}/rule-set-links/{rulesetId}" * Try to delete a ruleset link performing a DELETE call on "/nodes/{folderNodeId}/rule-set-links/{rulesetId}"
* *
* @param ruleSetId the id of the ruleset to be unlinked from the folder * @param ruleSetId
* the id of the ruleset to be unlinked from the folder
* @return * @return
*/ */
public void unlinkRuleSet(String ruleSetId) public void unlinkRuleSet(String ruleSetId)
@@ -1200,7 +1188,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Trigger rules on a folder performing POST call on "/nodes/{folderNodeId}/rule-executions" * Trigger rules on a folder performing POST call on "/nodes/{folderNodeId}/rule-executions"
* *
* @param body - rules execution request * @param body
* - rules execution request
* @return execution result * @return execution result
*/ */
public RestRuleExecutionModel executeRules(RestRuleExecutionModel body) public RestRuleExecutionModel executeRules(RestRuleExecutionModel body)
@@ -1223,7 +1212,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Link content to category performing POST call on "/nodes/{nodeId}/category-links" * Link content to category performing POST call on "/nodes/{nodeId}/category-links"
* *
* @param categoryLink - contains category ID * @param categoryLink
* - contains category ID
* @return linked to category * @return linked to category
*/ */
public RestCategoryModel linkToCategory(RestCategoryLinkBodyModel categoryLink) public RestCategoryModel linkToCategory(RestCategoryLinkBodyModel categoryLink)
@@ -1235,7 +1225,8 @@ public class Node extends ModelRequest<Node>
/** /**
* Link content to many categories performing POST call on "/nodes/{nodeId}/category-links" * Link content to many categories performing POST call on "/nodes/{nodeId}/category-links"
* *
* @param categoryLinks - contains categories IDs * @param categoryLinks
* - contains categories IDs
* @return linked to categories * @return linked to categories
*/ */
public RestCategoryModelsCollection linkToCategories(List<RestCategoryLinkBodyModel> categoryLinks) public RestCategoryModelsCollection linkToCategories(List<RestCategoryLinkBodyModel> categoryLinks)
@@ -1247,11 +1238,34 @@ public class Node extends ModelRequest<Node>
/** /**
* Unlink content from a category performing a DELETE call on "nodes/{nodeId}/category-links/{categoryId}" * Unlink content from a category performing a DELETE call on "nodes/{nodeId}/category-links/{categoryId}"
* *
* @param categoryId the id of the category to be unlinked from content * @param categoryId
* the id of the category to be unlinked from content
*/ */
public void unlinkFromCategory(String categoryId) public void unlinkFromCategory(String categoryId)
{ {
RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/category-links/{categoryId}", repoModel.getNodeRef(), categoryId); RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/category-links/{categoryId}", repoModel.getNodeRef(), categoryId);
restWrapper.processEmptyModel(request); restWrapper.processEmptyModel(request);
} }
/**
* In order to retrieve folder size details using POST call on "nodes/{nodeId}/size-details"
*
* @return
*/
public RestSizeDetailsModel executeSizeDetails()
{
RestRequest request = RestRequest.simpleRequest(HttpMethod.POST, "nodes/{nodeId}/size-details", repoModel.getNodeRef());
return restWrapper.processModel(RestSizeDetailsModel.class, request);
}
/**
* Getting Folder size details using GET call on "nodes/{nodeId}/size-details/{jobId}"
*
* @return
*/
public RestSizeDetailsModel getSizeDetails(String jobId)
{
RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, "nodes/{nodeId}/size-details/{jobId}", repoModel.getNodeRef(), jobId);
return restWrapper.processModel(RestSizeDetailsModel.class, request);
}
} }

View File

@@ -0,0 +1,380 @@
package org.alfresco.rest.nodes;
import static java.util.Objects.requireNonNull;
import static org.alfresco.utility.report.log.Step.STEP;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.IntStream;
import org.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility;
import org.awaitility.Durations;
import org.springframework.http.HttpStatus;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.alfresco.dataprep.CMISUtil.DocumentType;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestSizeDetailsModel;
import org.alfresco.utility.Utility;
import org.alfresco.utility.model.*;
import org.alfresco.utility.testrail.ExecutionType;
import org.alfresco.utility.testrail.annotation.TestRail;
public class NodeSizeDetailsTests extends RestTest
{
private UserModel user1;
private SiteModel siteModel;
private FolderModel folder;
private String jobId;
private FileModel sampleFileToCreate;
private long sampleFileSize;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws IOException
{
user1 = dataUser.createRandomTestUser("User-1");
siteModel = dataSite.usingUser(user1).createPublicRandomSite();
folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
String fileName = "sampleLargeContent.txt";
final byte[] sampleFileContent = getSampleFileContent(fileName);
sampleFileSize = sampleFileContent.length;
sampleFileToCreate = new FileModel(fileName, FileType.TEXT_PLAIN, new String(sampleFileContent));
}
/**
* calculateNodeSizeForSingleFile testcase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void calculateNodeSizeForSingleFile() throws Exception
{
STEP("1. Create a folder in the test site.");
folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
STEP("2. Upload a text document to the folder.");
dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(folder)
.createContent(sampleFileToCreate);
STEP("3. Wait for 30 seconds so that the content is indexed in Search Service.");
Utility.waitToLoopTime(30);
RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
jobId = restSizeDetailsModel.getJobId();
STEP("4. Wait for 5 seconds for the processing to complete.");
Awaitility
.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.OK);
sizeDetailsModel.assertThat()
.field("sizeInBytes")
.isNotEmpty();
Assert.assertEquals(sizeDetailsModel.getSizeInBytes(), sampleFileSize,
"Value of sizeInBytes " + sizeDetailsModel.getSizeInBytes()
+ " is not equal to " + sampleFileSize);
});
}
/**
* checkJobIdPresentInCache testcase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void checkJobIdPresentInCache() throws Exception
{
STEP("1. Verifying that same JobId is coming or not");
RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
Assert.assertEquals(restSizeDetailsModel.getJobId(), jobId, "jobId should be present in cache, actual :" + restSizeDetailsModel.getJobId() + " expected: " + jobId);
}
/**
* checkSizeDetailsWithInvalidJobId testcase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void checkSizeDetailsWithInvalidJobId() throws Exception
{
STEP("1. Create a folder in the test site.");
folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
STEP("2. Upload a text document to the folder.");
dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(folder)
.createContent(sampleFileToCreate);
STEP("3. Wait for 30 seconds so that the content is indexed in Search Service.");
Utility.waitToLoopTime(30);
RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
jobId = restSizeDetailsModel.getJobId();
STEP("4. Adding random content to jobId ");
jobId += RandomStringUtils.randomAlphanumeric(2);
STEP("5. Wait for 10 seconds for the processing to complete.");
Awaitility
.await()
.atMost(Duration.ofSeconds(10))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND);
});
}
/**
* checkSizeDetailsWithoutExecuteSizeDetails testcase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void checkSizeDetailsWithoutExecuteSizeDetails() throws Exception
{
STEP("1. Create a folder in the test site.");
folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
STEP("2. Upload a text document to the folder.");
String status = "NOT_INITIATED";
FileModel fileModel = dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(folder)
.createContent(sampleFileToCreate);
Assert.assertNotNull(fileModel, "fileModel should not be null");
STEP("3. Wait for 30 seconds so that the content is indexed in Search Service.");
Awaitility
.await()
.atMost(Duration.ofSeconds(30))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.OK);
sizeDetailsModel.assertThat().field("status").isNotEmpty();
Assert.assertEquals(sizeDetailsModel.getStatus().toString(), status, "Value of status should be same, actual :" + sizeDetailsModel.getStatus().toString() + " expected: " + status);
});
}
/**
* Unauthenticated user not able to execute POST /nodes/{nodeId}/size-details: 401 STATUS CODE
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void unauthenticatedUserIsNotAbleGetSizeDetails()
{
restClient.authenticateUser(new UserModel("random user", "random password"));
restClient.withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.UNAUTHORIZED);
}
/**
* Node Id Not Exist: 404 STATUS CODE
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void nodeIdNotExist()
{
folder.setNodeRef(RandomStringUtils.randomAlphanumeric(20));
restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND);
}
/**
* Value of nodeId is invalid: 422 STATUS CODE
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void nodeIdNotValid()
{
FileModel document = dataContent.usingSite(siteModel).usingUser(user1).createContent(DocumentType.TEXT_PLAIN);
restClient.authenticateUser(user1).withCoreAPI().usingNode(document).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.UNPROCESSABLE_ENTITY);
}
/**
*
* calculateNodeSizeForMultipleFiles testCase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void calculateNodeSizeForMultipleFiles() throws InterruptedException
{
STEP("1. Create a parent folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
STEP("2. Creating a 5 nested folders in the folder-1");
AtomicLong fileSize = new AtomicLong(0);
IntStream.rangeClosed(1, 5).forEach(i -> {
String folder0Name = "childFolder" + i + RandomStringUtils.randomAlphanumeric(2);
FolderModel folderModel = new FolderModel();
folderModel.setName(folder0Name);
FolderModel childFolder = dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(folder)
.createFolder(folderModel);
STEP("3. Upload a text document to the childFolders.");
dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(childFolder)
.createContent(sampleFileToCreate);
fileSize.addAndGet(sampleFileSize);
});
STEP("4. Wait for 30 seconds so that the content is indexed in Search Service.");
Utility.waitToLoopTime(30);
RestSizeDetailsModel restSizeDetailsModel = restClient
.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
String jobId = restSizeDetailsModel.getJobId();
STEP("5. Wait for 5 seconds for the processing to complete.");
Awaitility
.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.OK);
sizeDetailsModel.assertThat()
.field("sizeInBytes")
.isNotEmpty();
Assert.assertEquals(sizeDetailsModel.getSizeInBytes(), fileSize.get(),
"Value of sizeInBytes " + sizeDetailsModel.getSizeInBytes()
+ " is not equal to " + fileSize.get());
});
}
/**
*
* checkNumberOfFiles testCase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void checkNumberOfFiles() throws InterruptedException
{
STEP("1. Create a parent folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
STEP("2. Creating a 10 nested folders in the folder-1");
IntStream.rangeClosed(1, 10).forEach(i -> {
String folder0Name = "childFolder" + i + RandomStringUtils.randomAlphanumeric(2);
FolderModel folderModel = new FolderModel();
folderModel.setName(folder0Name);
FolderModel childFolder = dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(folder)
.createFolder(folderModel);
STEP("3. Upload a text document to the childFolders.");
dataContent.usingUser(user1)
.usingSite(siteModel)
.usingResource(childFolder)
.createContent(sampleFileToCreate);
});
STEP("4. Wait for 30 seconds so that the content is indexed in Search Service.");
Utility.waitToLoopTime(30);
RestSizeDetailsModel restSizeDetailsModel = restClient
.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
String jobId = restSizeDetailsModel.getJobId();
STEP("5. Wait for 10 seconds for the processing to complete.");
Awaitility
.await()
.atMost(Duration.ofSeconds(10))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.OK);
sizeDetailsModel.assertThat().field("numberOfFiles").isNotEmpty();
Assert.assertEquals(sizeDetailsModel.getNumberOfFiles(), 10, "Value of NumberOfFiles " + sizeDetailsModel.getNumberOfFiles() + " is not equal to " + 10);
});
}
private byte[] getSampleFileContent(String fileName) throws IOException
{
final String fileClasspathLocation = "/shared-resources/testdata/" + fileName;
try (InputStream fileStream = getClass().getResourceAsStream(fileClasspathLocation))
{
requireNonNull(fileStream, "Couldn't locate `" + fileClasspathLocation + "`");
return fileStream.readAllBytes();
}
}
@AfterClass(alwaysRun = true)
public void cleanup() throws Exception
{
dataSite.usingUser(user1).deleteSite(siteModel);
}
}

View File

@@ -0,0 +1,600 @@
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<properties> <properties>

20
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name> <name>Alfresco Community Repo Parent</name>
@@ -25,7 +25,7 @@
<properties> <properties>
<acs.version.major>23</acs.version.major> <acs.version.major>23</acs.version.major>
<acs.version.minor>4</acs.version.minor> <acs.version.minor>4</acs.version.minor>
<acs.version.revision>0</acs.version.revision> <acs.version.revision>2</acs.version.revision>
<acs.version.label /> <acs.version.label />
<amp.min.version>${acs.version.major}.0.0</amp.min.version> <amp.min.version>${acs.version.major}.0.0</amp.min.version>
@@ -51,14 +51,14 @@
<dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version> <dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version> <dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version> <dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.1.5-A1</dependency.alfresco-transform-core.version> <dependency.alfresco-transform-core.version>5.1.5</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.5-A1</dependency.alfresco-transform-service.version> <dependency.alfresco-transform-service.version>4.1.5</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.0</dependency.alfresco-greenmail.version> <dependency.alfresco-greenmail.version>7.0</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.33</dependency.acs-event-model.version> <dependency.acs-event-model.version>0.0.33</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version> <dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
<dependency.spring.version>6.1.13</dependency.spring.version> <dependency.spring.version>6.1.14</dependency.spring.version>
<dependency.spring-security.version>6.3.3</dependency.spring-security.version> <dependency.spring-security.version>6.3.4</dependency.spring-security.version>
<dependency.antlr.version>3.5.3</dependency.antlr.version> <dependency.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.17.2</dependency.jackson.version> <dependency.jackson.version>2.17.2</dependency.jackson.version>
<dependency.cxf.version>4.0.5</dependency.cxf.version> <dependency.cxf.version>4.0.5</dependency.cxf.version>
@@ -69,7 +69,7 @@
<dependency.assertj.version>3.26.3</dependency.assertj.version> <dependency.assertj.version>3.26.3</dependency.assertj.version>
<dependency.org-json.version>20240303</dependency.org-json.version> <dependency.org-json.version>20240303</dependency.org-json.version>
<dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version> <dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.16.1</dependency.commons-io.version> <dependency.commons-io.version>2.17.0</dependency.commons-io.version>
<dependency.gson.version>2.11.0</dependency.gson.version> <dependency.gson.version>2.11.0</dependency.gson.version>
<dependency.guava.version>33.3.1-jre</dependency.guava.version> <dependency.guava.version>33.3.1-jre</dependency.guava.version>
<dependency.httpclient.version>4.5.14</dependency.httpclient.version> <dependency.httpclient.version>4.5.14</dependency.httpclient.version>
@@ -113,8 +113,8 @@
<dependency.jakarta-json-path.version>2.9.0</dependency.jakarta-json-path.version> <dependency.jakarta-json-path.version>2.9.0</dependency.jakarta-json-path.version>
<dependency.json-smart.version>2.5.1</dependency.json-smart.version> <dependency.json-smart.version>2.5.1</dependency.json-smart.version>
<alfresco.googledrive.version>4.1.0</alfresco.googledrive.version> <alfresco.googledrive.version>4.1.0</alfresco.googledrive.version>
<alfresco.aos-module.version>4.0.0-A1</alfresco.aos-module.version> <alfresco.aos-module.version>3.2.0</alfresco.aos-module.version>
<alfresco.api-explorer.version>23.3.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share --> <alfresco.api-explorer.version>23.4.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version> <alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
<license-maven-plugin.version>2.4.0</license-maven-plugin.version> <license-maven-plugin.version>2.4.0</license-maven-plugin.version>
@@ -154,7 +154,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection> <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection> <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url> <url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>23.4.0.45</tag> <tag>23.4.2.1</tag>
</scm> </scm>
<distributionManagement> <distributionManagement>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<dependencies> <dependencies>

View File

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

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Remote API * 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. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -85,7 +85,7 @@ public class AuditImpl implements Audit
// list of equals filter's auditEntry (via where clause) // list of equals filter's auditEntry (via where clause)
private final static Set<String> LIST_AUDIT_ENTRY_EQUALS_QUERY_PROPERTIES = new HashSet<>( 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 // map of sort parameters for the moment one createdAt
private final static Map<String, String> SORT_PARAMS_TO_NAMES; private final static Map<String, String> SORT_PARAMS_TO_NAMES;
@@ -295,23 +295,29 @@ public class AuditImpl implements Audit
} }
else else
{ {
if (hasMoreItems) { if (hasMoreItems)
if (q != null) { {
if (q != null)
{
// filtering via "where" clause // filtering via "where" clause
AuditEntryQueryWalker propertyWalker = new AuditEntryQueryWalker(); AuditEntryQueryWalker propertyWalker = new AuditEntryQueryWalker();
QueryHelper.walk(q, propertyWalker); QueryHelper.walk(q, propertyWalker);
totalItems = getAuditEntriesCountByAppAndProperties(auditApplication, propertyWalker); totalItems = getAuditEntriesCountByAppAndProperties(auditApplication, propertyWalker);
} else { }
else
{
totalItems = getAuditEntriesCountByApp(auditApplication); totalItems = getAuditEntriesCountByApp(auditApplication);
} }
} else { }
else
{
totalItems = totalRetrievedItems; totalItems = totalRetrievedItems;
} }
} }
entriesAudit = (skipCount >= totalRetrievedItems) entriesAudit = (skipCount >= totalRetrievedItems)
? Collections.emptyList() ? Collections.emptyList()
: entriesAudit.subList(skipCount, end); : entriesAudit.subList(skipCount, end);
return CollectionWithPagingInfo.asPaged(paging, entriesAudit, hasMoreItems, totalItems); return CollectionWithPagingInfo.asPaged(paging, entriesAudit, hasMoreItems, totalItems);
} }
@@ -475,8 +481,7 @@ public class AuditImpl implements Audit
final Map<String, UserInfo> mapUserInfo = new HashMap<>(10); final Map<String, UserInfo> mapUserInfo = new HashMap<>(10);
// create the callback for auditQuery method // create the callback for auditQuery method
final AuditQueryCallback callback = new AuditQueryCallback() final AuditQueryCallback callback = new AuditQueryCallback() {
{
public boolean valuesRequired() public boolean valuesRequired()
{ {
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES))); return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
@@ -532,7 +537,7 @@ public class AuditImpl implements Audit
params.setApplicationName(auditApplication.getName()); params.setApplicationName(auditApplication.getName());
params.setFromId(auditEntryId); params.setFromId(auditEntryId);
params.setToId(auditEntryId + 1); params.setToId(auditEntryId + 1);
List<String> includeParam = new ArrayList<>(); List<String> includeParam = new ArrayList<>();
if (parameters != null) if (parameters != null)
{ {
@@ -545,8 +550,7 @@ public class AuditImpl implements Audit
final List<AuditEntry> results = new ArrayList<>(); final List<AuditEntry> results = new ArrayList<>();
// create the callback for auditQuery method // create the callback for auditQuery method
final AuditQueryCallback callback = new AuditQueryCallback() final AuditQueryCallback callback = new AuditQueryCallback() {
{
public boolean valuesRequired() public boolean valuesRequired()
{ {
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES))); return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
@@ -710,8 +714,7 @@ public class AuditImpl implements Audit
@Override @Override
public CollectionWithPagingInfo<AuditEntry> listAuditEntriesByNodeId(String nodeId, Parameters parameters) public CollectionWithPagingInfo<AuditEntry> listAuditEntriesByNodeId(String nodeId, Parameters parameters)
{ {
AuthenticationUtil.runAs(new RunAsWork<Void>() AuthenticationUtil.runAs(new RunAsWork<Void>() {
{
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
checkEnabled(); checkEnabled();
@@ -772,8 +775,7 @@ public class AuditImpl implements Audit
final List<AuditEntry> results = new ArrayList<>(); final List<AuditEntry> results = new ArrayList<>();
String auditAppId = "alfresco-access"; String auditAppId = "alfresco-access";
String auditApplicationName = AuthenticationUtil.runAs(new RunAsWork<String>() String auditApplicationName = AuthenticationUtil.runAs(new RunAsWork<String>() {
{
public String doWork() throws Exception public String doWork() throws Exception
{ {
return findAuditAppByIdOr404(auditAppId).getName(); return findAuditAppByIdOr404(auditAppId).getName();
@@ -781,8 +783,7 @@ public class AuditImpl implements Audit
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
// create the callback for auditQuery method // create the callback for auditQuery method
final AuditQueryCallback callback = new AuditQueryCallback() final AuditQueryCallback callback = new AuditQueryCallback() {
{
public boolean valuesRequired() public boolean valuesRequired()
{ {
return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES))); return ((includeParam != null) && (includeParam.contains(PARAM_INCLUDE_VALUES)));
@@ -808,8 +809,7 @@ public class AuditImpl implements Audit
Long toTime = propertyWalker.getToTime(); Long toTime = propertyWalker.getToTime();
validateWhereBetween(nodeRef.getId(), fromTime, toTime); validateWhereBetween(nodeRef.getId(), fromTime, toTime);
AuthenticationUtil.runAs(new RunAsWork<Object>() AuthenticationUtil.runAs(new RunAsWork<Object>() {
{
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
// QueryParameters // QueryParameters
@@ -820,7 +820,7 @@ public class AuditImpl implements Audit
pathParams.setFromTime(fromTime); pathParams.setFromTime(fromTime);
pathParams.setToTime(toTime); pathParams.setToTime(toTime);
pathParams.setApplicationName(auditApplicationName); pathParams.setApplicationName(auditApplicationName);
pathParams.addSearchKey("/"+auditAppId+"/transaction/path", nodePath); pathParams.addSearchKey("/" + auditAppId + "/transaction/path", nodePath);
auditService.auditQuery(callback, pathParams, limit); auditService.auditQuery(callback, pathParams, limit);
AuditQueryParameters copyFromPathParams = new AuditQueryParameters(); AuditQueryParameters copyFromPathParams = new AuditQueryParameters();
@@ -830,7 +830,7 @@ public class AuditImpl implements Audit
copyFromPathParams.setFromTime(fromTime); copyFromPathParams.setFromTime(fromTime);
copyFromPathParams.setToTime(toTime); copyFromPathParams.setToTime(toTime);
copyFromPathParams.setApplicationName(auditApplicationName); copyFromPathParams.setApplicationName(auditApplicationName);
copyFromPathParams.addSearchKey("/"+auditAppId+"/transaction/copy/from/path", nodePath); copyFromPathParams.addSearchKey("/" + auditAppId + "/transaction/copy/from/path", nodePath);
auditService.auditQuery(callback, copyFromPathParams, limit); auditService.auditQuery(callback, copyFromPathParams, limit);
AuditQueryParameters moveFromPathParams = new AuditQueryParameters(); AuditQueryParameters moveFromPathParams = new AuditQueryParameters();
@@ -840,7 +840,7 @@ public class AuditImpl implements Audit
moveFromPathParams.setFromTime(fromTime); moveFromPathParams.setFromTime(fromTime);
moveFromPathParams.setToTime(toTime); moveFromPathParams.setToTime(toTime);
moveFromPathParams.setApplicationName(auditApplicationName); moveFromPathParams.setApplicationName(auditApplicationName);
moveFromPathParams.addSearchKey("/"+auditAppId+"/transaction/move/from/path", nodePath); moveFromPathParams.addSearchKey("/" + auditAppId + "/transaction/move/from/path", nodePath);
auditService.auditQuery(callback, moveFromPathParams, limit); auditService.auditQuery(callback, moveFromPathParams, limit);
return null; return null;
@@ -857,7 +857,7 @@ public class AuditImpl implements Audit
public AuditEntriesByNodeIdQueryWalker() 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 @Override
@@ -909,14 +909,16 @@ public class AuditImpl implements Audit
public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker) public int getAuditEntriesCountByAppAndProperties(AuditService.AuditApplication auditApplication, AuditEntryQueryWalker propertyWalker)
{ {
final String applicationName = auditApplication.getKey().substring(1);
AuditQueryParameters parameters = new AuditQueryParameters(); AuditQueryParameters parameters = new AuditQueryParameters();
parameters.setApplicationName(auditApplication.getName()); parameters.setApplicationName(applicationName);
parameters.setFromTime(propertyWalker.getFromTime()); parameters.setFromTime(propertyWalker.getFromTime());
parameters.setToTime(propertyWalker.getToTime()); parameters.setToTime(propertyWalker.getToTime());
parameters.setFromId(propertyWalker.getFromId()); parameters.setFromId(propertyWalker.getFromId());
parameters.setToId(propertyWalker.getToId()); parameters.setToId(propertyWalker.getToId());
parameters.setUser(propertyWalker.getCreatedByUser()); parameters.setUser(propertyWalker.getCreatedByUser());
return auditService.getAuditEntriesCountByAppAndProperties(parameters); return auditService.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
} }
} }

View File

@@ -0,0 +1,119 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.impl;
import java.util.Optional;
import org.springframework.beans.factory.InitializingBean;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsService;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails.STATUS;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.SizeDetails;
import org.alfresco.rest.framework.core.exceptions.InvalidNodeTypeException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.GUID;
import org.alfresco.util.ParameterCheck;
public class SizeDetailsImpl implements SizeDetails, InitializingBean
{
private final Nodes nodes;
private final NodeSizeDetailsService nodeSizeDetailsService;
public SizeDetailsImpl(Nodes nodes, NodeSizeDetailsService nodeSizeDetailsService)
{
this.nodes = nodes;
this.nodeSizeDetailsService = nodeSizeDetailsService;
}
/**
* generateNodeSizeDetailsRequest : providing HTTP STATUS 202 with jobId.
*/
@Override
public NodeSizeDetails generateNodeSizeDetailsRequest(String nodeId)
{
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
validateType(nodeRef);
Optional<NodeSizeDetails> nodeSizeDetails = nodeSizeDetailsService.getSizeDetails(nodeId);
String actionId = nodeSizeDetails.map(NodeSizeDetails::getJobId)
.orElseGet(() -> executeSizeDetails(nodeRef));
return new NodeSizeDetails(actionId);
}
/**
* getNodeSizeDetails : providing HTTP STATUS 200 with NodeSizeDetails data from cache.
*/
@Override
public NodeSizeDetails getNodeSizeDetails(final String nodeId, final String jobId)
{
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
validateType(nodeRef);
Optional<NodeSizeDetails> optionalDetails = nodeSizeDetailsService.getSizeDetails(nodeId);
return optionalDetails.map(details -> {
String cachedJobId = details.getJobId();
if (cachedJobId != null && !jobId.equalsIgnoreCase(cachedJobId))
{
throw new NotFoundException("jobId does not exist");
}
return details;
})
.orElseGet(() -> new NodeSizeDetails(nodeId, STATUS.NOT_INITIATED));
}
/**
* Executing Asynchronously.
*/
private String executeSizeDetails(NodeRef nodeRef)
{
String jobId = GUID.generate();
NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), jobId, STATUS.PENDING);
nodeSizeDetailsService.putSizeDetails(nodeRef.getId(), nodeSizeDetails);
nodeSizeDetailsService.invokeSizeDetailsExecutor(nodeRef, jobId);
return jobId;
}
private void validateType(NodeRef nodeRef) throws InvalidNodeTypeException
{
if (!nodes.isSubClass(nodeRef, ContentModel.TYPE_FOLDER, false))
{
throw new InvalidNodeTypeException("Node id " + nodeRef.getId() + " does not represent a folder.");
}
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("nodes", this.nodes);
ParameterCheck.mandatory("nodeSizeDetailsServiceImpl", this.nodeSizeDetailsService);
}
}

View File

@@ -0,0 +1,84 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.nodes;
import java.util.List;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.webscripts.Status;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
import org.alfresco.rest.api.SizeDetails;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.WebApiParameters;
import org.alfresco.rest.framework.core.ResourceParameter;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.util.ParameterCheck;
@RelationshipResource(name = "size-details", entityResource = NodesEntityResource.class, title = "Node Size Details")
public class NodeSizeDetailsRelation implements RelationshipResourceAction.ReadById<NodeSizeDetails>,
RelationshipResourceAction.Create<NodeSizeDetails>, InitializingBean
{
private SizeDetails sizeDetails;
public void setSizeDetails(SizeDetails sizeDetails)
{
this.sizeDetails = sizeDetails;
}
@Override
public void afterPropertiesSet()
{
ParameterCheck.mandatory("sizeDetails", this.sizeDetails);
}
@WebApiDescription(title = "Create node-size details request", successStatus = Status.STATUS_ACCEPTED)
@WebApiParam(name = "nodeSizeEntity", title = "Node Size Details Request",
description = "Request for processing Node Size.", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT,
allowMultiple = false)
@Override
public List<NodeSizeDetails> create(String nodeId, List<NodeSizeDetails> nodeSizeEntity, Parameters parameters)
{
return List.of(sizeDetails.generateNodeSizeDetailsRequest(nodeId));
}
@WebApiDescription(title = "Get Node Size Details", description = "Get the Node Size Details")
@WebApiParameters({@WebApiParam(name = "nodeId", title = "The unique id of the Node being addressed",
description = "A single Node id"),
@WebApiParam(name = "jobId", title = "Job Id to get the NodeSizeDetails", description = "JobId")})
@Override
public NodeSizeDetails readById(String nodeId, String jobId, Parameters parameters)
throws RelationshipResourceNotFoundException
{
return sizeDetails.getNodeSizeDetails(nodeId, jobId);
}
}

View File

@@ -996,6 +996,25 @@
</property> </property>
</bean> </bean>
<bean id="sizeDetailsImpl" class="org.alfresco.rest.api.impl.SizeDetailsImpl">
<constructor-arg name="nodes" ref="nodes" />
<constructor-arg name="nodeSizeDetailsService" ref="NodeSizeDetailsService" />
</bean>
<bean id="sizeDetails" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rest.api.SizeDetails</value>
</property>
<property name="target">
<ref bean="sizeDetailsImpl" />
</property>
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
<bean class="org.alfresco.rest.api.rules.NodeRuleSettingsRelation"> <bean class="org.alfresco.rest.api.rules.NodeRuleSettingsRelation">
<property name="ruleSettings" ref="RuleSettings" /> <property name="ruleSettings" ref="RuleSettings" />
</bean> </bean>
@@ -1770,4 +1789,8 @@
</list> </list>
</property> </property>
</bean> </bean>
<bean class="org.alfresco.rest.api.nodes.NodeSizeDetailsRelation">
<property name="sizeDetails" ref="sizeDetails" />
</bean>
</beans> </beans>

View File

@@ -4,21 +4,21 @@
* %% * %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited * Copyright (C) 2005 - 2021 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
@@ -71,7 +71,7 @@ import org.junit.runners.Suite;
org.alfresco.rest.api.tests.TestPublicApiCaching.class, org.alfresco.rest.api.tests.TestPublicApiCaching.class,
org.alfresco.rest.api.tests.TestUserPreferences.class, org.alfresco.rest.api.tests.TestUserPreferences.class,
org.alfresco.rest.api.tests.WherePredicateApiTest.class, org.alfresco.rest.api.tests.WherePredicateApiTest.class,
org.alfresco.rest.api.tests.TestRemovePermissions.class, org.alfresco.rest.api.tests.TestRemovePermissions.class,
org.alfresco.rest.api.tests.TempOutputStreamTest.class, org.alfresco.rest.api.tests.TempOutputStreamTest.class,
org.alfresco.rest.api.tests.BufferedResponseTest.class, org.alfresco.rest.api.tests.BufferedResponseTest.class,
org.alfresco.rest.workflow.api.tests.DeploymentWorkflowApiTest.class, org.alfresco.rest.workflow.api.tests.DeploymentWorkflowApiTest.class,

View File

@@ -2,23 +2,23 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
@@ -36,6 +36,8 @@ import org.alfresco.util.testing.category.NonBuildTests;
@RunWith(Categories.class) @RunWith(Categories.class)
@Categories.ExcludeCategory({DBTests.class, NonBuildTests.class}) @Categories.ExcludeCategory({DBTests.class, NonBuildTests.class})
@Suite.SuiteClasses({ @Suite.SuiteClasses({
// [classpath:alfresco/application-context.xml, classpath:alfresco/web-scripts-application-context-test.xml,
// classpath:alfresco/web-scripts-application-context.xml]
org.alfresco.repo.web.scripts.quickshare.QuickShareRestApiTest.class, org.alfresco.repo.web.scripts.quickshare.QuickShareRestApiTest.class,
org.alfresco.repo.web.scripts.admin.AdminWebScriptTest.class, org.alfresco.repo.web.scripts.admin.AdminWebScriptTest.class,
org.alfresco.repo.web.scripts.audit.AuditWebScriptTest.class, org.alfresco.repo.web.scripts.audit.AuditWebScriptTest.class,
@@ -47,8 +49,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
org.alfresco.repo.web.scripts.forms.FormRestApiJsonPost_Test.class, org.alfresco.repo.web.scripts.forms.FormRestApiJsonPost_Test.class,
org.alfresco.repo.web.scripts.groups.GroupsTest.class, org.alfresco.repo.web.scripts.groups.GroupsTest.class,
org.alfresco.repo.web.scripts.invitation.InvitationWebScriptTest.class, org.alfresco.repo.web.scripts.invitation.InvitationWebScriptTest.class,
org.alfresco.repo.web.scripts.invite.InviteServiceTest.class, org.alfresco.repo.web.scripts.invite.InviteServiceTest.class, org.alfresco.repo.web.scripts.LoginTest.class,
org.alfresco.repo.web.scripts.LoginTest.class,
org.alfresco.repo.web.scripts.search.PersonSearchTest.class, org.alfresco.repo.web.scripts.search.PersonSearchTest.class,
org.alfresco.repo.web.scripts.person.PersonServiceTest.class, org.alfresco.repo.web.scripts.person.PersonServiceTest.class,
org.alfresco.repo.web.scripts.preference.PreferenceServiceTest.class, org.alfresco.repo.web.scripts.preference.PreferenceServiceTest.class,
@@ -76,9 +77,8 @@ import org.alfresco.util.testing.category.NonBuildTests;
org.alfresco.repo.web.scripts.node.NodeWebScripTest.class, org.alfresco.repo.web.scripts.node.NodeWebScripTest.class,
org.alfresco.rest.api.impl.CommentsImplUnitTest.class, org.alfresco.rest.api.impl.CommentsImplUnitTest.class,
org.alfresco.rest.api.impl.DownloadsImplCheckArchiveStatusUnitTest.class, org.alfresco.rest.api.impl.DownloadsImplCheckArchiveStatusUnitTest.class,
org.alfresco.rest.api.impl.FavouritesImplUnitTest.class, org.alfresco.rest.api.impl.RestApiDirectUrlConfigUnitTest.class,
org.alfresco.rest.api.impl.RestApiDirectUrlConfigUnitTest.class org.alfresco.rest.api.impl.SizeDetailsImplTest.class})
})
public class AppContext04TestSuite public class AppContext04TestSuite
{ {
public AppContext04TestSuite() public AppContext04TestSuite()

View File

@@ -0,0 +1,107 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.impl;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.Serializable;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;
import org.junit.Before;
import org.junit.Test;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Node;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
/**
* Unit tests for {@link SizeDetailsImpl} class.
*/
public class SizeDetailsImplTest
{
private static final String NAMESPACE = "http://www.alfresco.org/test/NodeSizeDetailsTest";
private static final QName TYPE_FOLDER = QName.createQName(NAMESPACE, "folder");
private SizeDetailsImpl sizeDetailsImpl;
private Nodes nodes;
private NodeSizeDetailsServiceImpl nodeSizeDetailsServiceImpl;
private NodeSizeDetails nodeSizeDetails;
@Before
public void setUp() throws Exception
{
nodes = mock(Nodes.class);
SearchService searchService = mock(SearchService.class);
nodeSizeDetailsServiceImpl = mock(NodeSizeDetailsServiceImpl.class);
ThreadPoolExecutor threadPoolExecutor = mock(ThreadPoolExecutor.class);
SimpleCache<Serializable, NodeSizeDetails> simpleCache = mock(SimpleCache.class);
nodeSizeDetails = mock(NodeSizeDetails.class);
nodeSizeDetailsServiceImpl.setSearchService(searchService);
nodeSizeDetailsServiceImpl.setDefaultItems(1000);
nodeSizeDetailsServiceImpl.setSimpleCache(simpleCache);
verify(nodeSizeDetailsServiceImpl).setSimpleCache(simpleCache);
nodeSizeDetailsServiceImpl.setThreadPoolExecutor(threadPoolExecutor);
sizeDetailsImpl = new SizeDetailsImpl(nodes, nodeSizeDetailsServiceImpl);
}
@Test
public void calculateNodeSizeDetails()
{
String nodeName = "folderNode";
String nodeId = "node-id";
String jobId = "job-id";
NodeRef nodeRef = new NodeRef("protocol", "identifier", nodeId);
Node node = new Node();
node.setIsFolder(true);
node.setNodeRef(nodeRef);
node.setName(nodeName);
node.setNodeType(TYPE_FOLDER.getLocalName());
node.setNodeId(nodeRef.getId());
when(nodes.validateOrLookupNode(nodeId)).thenReturn(nodeRef);
when(nodes.isSubClass(nodeRef, ContentModel.TYPE_FOLDER, false)).thenReturn(true);
when(nodeSizeDetailsServiceImpl.getSizeDetails(nodeId)).thenReturn(Optional.ofNullable(nodeSizeDetails));
NodeSizeDetails requestSizeDetails = sizeDetailsImpl.generateNodeSizeDetailsRequest(nodeId);
assertNotNull("After executing POST/size-details, it will provide with 202 status code", requestSizeDetails);
NodeSizeDetails nodeSizeDetails = sizeDetailsImpl.getNodeSizeDetails(nodeId, jobId);
assertNotNull("After executing GET/size-details, it will provide with 200 status code", nodeSizeDetails);
}
}

View File

@@ -2,50 +2,68 @@
* #%L * #%L
* Alfresco Remote API * Alfresco Remote API
* %% * %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited * Copyright (C) 2005 - 2024 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.rest.api.tests; package org.alfresco.rest.api.tests;
import org.alfresco.repo.content.directurl.SystemWideDirectUrlConfig;
import org.alfresco.rest.api.impl.directurl.RestApiDirectUrlConfig;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.experimental.categories.Category;
import org.springframework.util.ResourceUtils;
import org.alfresco.repo.content.directurl.SystemWideDirectUrlConfig;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil; import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.impl.directurl.RestApiDirectUrlConfig;
import org.alfresco.rest.api.model.Site; import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.nodes.NodesEntityResource; import org.alfresco.rest.api.nodes.NodesEntityResource;
import org.alfresco.rest.api.tests.RepoService.TestNetwork; import org.alfresco.rest.api.tests.RepoService.TestNetwork;
import org.alfresco.rest.api.tests.client.HttpResponse; import org.alfresco.rest.api.tests.client.HttpResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient; import org.alfresco.rest.api.tests.client.PublicApiClient;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload; import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder; import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder;
import org.alfresco.rest.api.tests.client.RequestContext; import org.alfresco.rest.api.tests.client.RequestContext;
@@ -65,26 +83,10 @@ import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
import org.alfresco.util.testing.category.LuceneTests; import org.alfresco.util.testing.category.LuceneTests;
import org.json.simple.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.experimental.categories.Category;
import org.springframework.util.ResourceUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
/** /**
* Generic methods for calling the Api (originally taken and adapted from BaseCustomModelApiTest) * Generic methods for calling the Api (originally taken and adapted from BaseCustomModelApiTest)
* *
* @author Jamal Kaabi-Mofrad * @author Jamal Kaabi-Mofrad
* @author janv * @author janv
* @author gethin * @author gethin
@@ -94,54 +96,40 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
public static final String LAST_MODIFIED_HEADER = "Last-Modified"; public static final String LAST_MODIFIED_HEADER = "Last-Modified";
public static final String IF_MODIFIED_SINCE_HEADER = "If-Modified-Since"; public static final String IF_MODIFIED_SINCE_HEADER = "If-Modified-Since";
private static final String RESOURCE_PREFIX = "publicapi/upload/";
protected static final String URL_NODES = "nodes"; protected static final String URL_NODES = "nodes";
protected static final String URL_DELETED_NODES = "deleted-nodes"; protected static final String URL_DELETED_NODES = "deleted-nodes";
protected static final String URL_RENDITIONS = "renditions"; protected static final String URL_RENDITIONS = "renditions";
protected static final String URL_VERSIONS = "versions"; protected static final String URL_VERSIONS = "versions";
private static final String URL_CHILDREN = "children";
private static final String URL_CONTENT = "content";
protected static final String TYPE_CM_FOLDER = "cm:folder"; protected static final String TYPE_CM_FOLDER = "cm:folder";
protected static final String TYPE_CM_CONTENT = "cm:content"; protected static final String TYPE_CM_CONTENT = "cm:content";
protected static final String TYPE_CM_OBJECT = "cm:cmobject"; protected static final String TYPE_CM_OBJECT = "cm:cmobject";
protected static final String ASPECT_CM_PREFERENCES = "cm:preferences"; protected static final String ASPECT_CM_PREFERENCES = "cm:preferences";
protected static final String ASSOC_TYPE_CM_PREFERENCE_IMAGE = "cm:preferenceImage"; protected static final String ASSOC_TYPE_CM_PREFERENCE_IMAGE = "cm:preferenceImage";
protected static final String ASSOC_TYPE_CM_CONTAINS = "cm:contains"; protected static final String ASSOC_TYPE_CM_CONTAINS = "cm:contains";
// TODO improve admin-related tests, including ability to override default admin un/pw // TODO improve admin-related tests, including ability to override default admin un/pw
protected static final String DEFAULT_ADMIN = "admin"; protected static final String DEFAULT_ADMIN = "admin";
protected static final String DEFAULT_ADMIN_PWD = "admin"; protected static final String DEFAULT_ADMIN_PWD = "admin";
protected static final long PAUSE_TIME = 5000; // millisecond
protected static final int MAX_RETRY = 20;
private static final String RESOURCE_PREFIX = "publicapi/upload/";
private static final String URL_CHILDREN = "children";
private static final String URL_CONTENT = "content";
private static final String URL_CALCULATEFOLDERSIZE = "size-details";
private static final String REQUEST_DIRECT_ACCESS_URL = "request-direct-access-url";
// network1 with user1, user2 and a testsite1 // network1 with user1, user2 and a testsite1
protected static TestNetwork networkOne; protected static TestNetwork networkOne;
protected static String user1; // user1 from network1 protected static String user1; // user1 from network1
protected static String user2; // user2 from network1 protected static String user2; // user2 from network1
// network admin (or default super admin, if not running within a tenant/network) // network admin (or default super admin, if not running within a tenant/network)
protected static String networkAdmin = DEFAULT_ADMIN; protected static String networkAdmin = DEFAULT_ADMIN;
protected static String tSiteId; protected static String tSiteId;
protected static String tDocLibNodeId; protected static String tDocLibNodeId;
protected static List<String> users = new ArrayList<>(); protected static List<String> users = new ArrayList<>();
protected static JacksonUtil jacksonUtil; protected static JacksonUtil jacksonUtil;
protected static MutableAuthenticationService authenticationService; protected static MutableAuthenticationService authenticationService;
protected static PersonService personService; protected static PersonService personService;
protected final String RUNID = System.currentTimeMillis() + "";
protected final String RUNID = System.currentTimeMillis()+"";
private static final String REQUEST_DIRECT_ACCESS_URL = "request-direct-access-url";
@Override @Override
@Before @Before
public void setup() throws Exception public void setup() throws Exception
@@ -153,22 +141,22 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
// note: populateTestData/createTestData will be called (which currently creates 2 tenants, 9 users per tenant, 10 sites per tenant, ...) // note: populateTestData/createTestData will be called (which currently creates 2 tenants, 9 users per tenant, 10 sites per tenant, ...)
networkOne = getTestFixture().getRandomNetwork(); networkOne = getTestFixture().getRandomNetwork();
} }
//userOneN1 = networkN1.createUser(); // userOneN1 = networkN1.createUser();
//userTwoN1 = networkN1.createUser(); // userTwoN1 = networkN1.createUser();
String tenantDomain = networkOne.getId(); String tenantDomain = networkOne.getId();
if (! TenantService.DEFAULT_DOMAIN.equals(tenantDomain)) if (!TenantService.DEFAULT_DOMAIN.equals(tenantDomain))
{ {
networkAdmin = DEFAULT_ADMIN+"@"+tenantDomain; networkAdmin = DEFAULT_ADMIN + "@" + tenantDomain;
} }
// to enable admin access via test calls - eg. via PublicApiClient -> AbstractTestApi -> findUserByUserName // to enable admin access via test calls - eg. via PublicApiClient -> AbstractTestApi -> findUserByUserName
getOrCreateUser(networkAdmin, "admin", networkOne); getOrCreateUser(networkAdmin, "admin", networkOne);
setRequestContext(networkOne.getId(), networkAdmin, DEFAULT_ADMIN_PWD); setRequestContext(networkOne.getId(), networkAdmin, DEFAULT_ADMIN_PWD);
// note: createUser currently relies on repoService // note: createUser currently relies on repoService
user1 = createUser("user1-" + RUNID, "user1Password", networkOne); user1 = createUser("user1-" + RUNID, "user1Password", networkOne);
user2 = createUser("user2-" + RUNID, "user2Password", networkOne); user2 = createUser("user2-" + RUNID, "user2Password", networkOne);
@@ -180,7 +168,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
users.add(user2); users.add(user2);
setRequestContext(networkOne.getId(), user1, null); setRequestContext(networkOne.getId(), user1, null);
tSiteId = createSite("TestSite A - " + RUNID, SiteVisibility.PRIVATE).getId(); tSiteId = createSite("TestSite A - " + RUNID, SiteVisibility.PRIVATE).getId();
tDocLibNodeId = getSiteContainerNodeId(tSiteId, "documentLibrary"); tDocLibNodeId = getSiteContainerNodeId(tSiteId, "documentLibrary");
@@ -197,11 +185,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
setRequestContext(networkAdmin); setRequestContext(networkAdmin);
for (final String username : users) for (final String username : users)
{ {
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
{
@Override @Override
public Void execute() throws Throwable public Void execute() throws Throwable
{ {
@@ -210,7 +197,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
}); });
} }
users.clear(); users.clear();
AuthenticationUtil.clearCurrentSecurityContext(); AuthenticationUtil.clearCurrentSecurityContext();
setRequestContext(null); setRequestContext(null);
@@ -233,7 +220,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String getRequestArchivedRenditonContentDirectUrl(String nodeId, String renditionID) protected String getRequestArchivedRenditonContentDirectUrl(String nodeId, String renditionID)
{ {
return URL_DELETED_NODES + "/" + nodeId + "/" + URL_RENDITIONS + "/" + renditionID + "/" + REQUEST_DIRECT_ACCESS_URL; return URL_DELETED_NODES + "/" + nodeId + "/" + URL_RENDITIONS + "/" + renditionID + "/"
+ REQUEST_DIRECT_ACCESS_URL;
} }
protected String getRequestRenditionDirectAccessUrl(String nodeId, String renditionID) protected String getRequestRenditionDirectAccessUrl(String nodeId, String renditionID)
@@ -246,7 +234,6 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + REQUEST_DIRECT_ACCESS_URL; return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + REQUEST_DIRECT_ACCESS_URL;
} }
/** /**
* The api scope. either public or private * The api scope. either public or private
* *
@@ -262,10 +249,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse post(String url, byte[] body, Map<String, String> params, Map<String, String> headers, String apiName, String contentType, int expectedStatus) throws Exception protected HttpResponse post(String url, byte[] body, Map<String, String> params, Map<String, String> headers,
String apiName, String contentType, int expectedStatus) throws Exception
{ {
RequestBuilder requestBuilder = httpClient.new PostRequestBuilder() RequestBuilder requestBuilder = httpClient.new PostRequestBuilder().setBodyAsByteArray(body)
.setBodyAsByteArray(body)
.setContentType(contentType) .setContentType(contentType)
.setRequestContext(publicApiClient.getRequestContext()) .setRequestContext(publicApiClient.getRequestContext())
.setScope(getScope()) .setScope(getScope())
@@ -279,10 +266,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse post(String url, String body, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception protected HttpResponse post(String url, String body, Map<String, String> params, Map<String, String> headers,
String apiName, int expectedStatus) throws Exception
{ {
RequestBuilder requestBuilder = httpClient.new PostRequestBuilder() RequestBuilder requestBuilder = httpClient.new PostRequestBuilder().setBodyAsString(body)
.setBodyAsString(body)
.setRequestContext(publicApiClient.getRequestContext()) .setRequestContext(publicApiClient.getRequestContext())
.setScope(getScope()) .setScope(getScope())
.setApiName(apiName) .setApiName(apiName)
@@ -307,7 +294,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse post(String url, String body, String queryString, String contentType, int expectedStatus) throws Exception protected HttpResponse post(String url, String body, String queryString, String contentType, int expectedStatus)
throws Exception
{ {
if (queryString != null) if (queryString != null)
{ {
@@ -319,7 +307,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse post(String url, byte[] body, String queryString, String contentType, int expectedStatus) throws Exception protected HttpResponse post(String url, byte[] body, String queryString, String contentType, int expectedStatus)
throws Exception
{ {
if (queryString != null) if (queryString != null)
{ {
@@ -332,9 +321,12 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
// TODO unused queryString - fix-up usages and then remove // TODO unused queryString - fix-up usages and then remove
protected HttpResponse post(String entityCollectionName, String entityId, String relationCollectionName, byte[] body, String queryString, String contentType, int expectedStatus) throws Exception protected HttpResponse post(String entityCollectionName, String entityId, String relationCollectionName,
byte[] body, String queryString, String contentType, int expectedStatus)
throws Exception
{ {
HttpResponse response = publicApiClient.post(getScope(), entityCollectionName, entityId, relationCollectionName, null, body, contentType); HttpResponse response = publicApiClient.post(getScope(), entityCollectionName, entityId, relationCollectionName, null, body,
contentType);
checkStatus(expectedStatus, response.getStatusCode()); checkStatus(expectedStatus, response.getStatusCode());
return response; return response;
@@ -345,7 +337,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return getAll(url, paging, null, expectedStatus); return getAll(url, paging, null, expectedStatus);
} }
protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, int expectedStatus) throws Exception protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
int expectedStatus) throws Exception
{ {
Map<String, String> params = createParams(paging, otherParams); Map<String, String> params = createParams(paging, otherParams);
@@ -355,7 +348,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getAll(Class<?> entityResource, PublicApiClient.Paging paging, Map<String, String> otherParams, int expectedStatus) throws Exception protected HttpResponse getAll(Class<?> entityResource, PublicApiClient.Paging paging,
Map<String, String> otherParams, int expectedStatus) throws Exception
{ {
HttpResponse response = publicApiClient.get(entityResource, null, null, otherParams); HttpResponse response = publicApiClient.get(entityResource, null, null, otherParams);
checkStatus(expectedStatus, response.getStatusCode()); checkStatus(expectedStatus, response.getStatusCode());
@@ -363,16 +357,17 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, Map<String, String> headers, int expectedStatus) throws Exception protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
Map<String, String> headers, int expectedStatus) throws Exception
{ {
return getAll(url, paging, otherParams, headers, null, expectedStatus); return getAll(url, paging, otherParams, headers, null, expectedStatus);
} }
protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, Map<String, String> headers, String apiName, int expectedStatus) throws Exception protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
Map<String, String> headers, String apiName, int expectedStatus) throws Exception
{ {
Map<String, String> params = createParams(paging, otherParams); Map<String, String> params = createParams(paging, otherParams);
RequestBuilder requestBuilder = httpClient.new GetRequestBuilder() RequestBuilder requestBuilder = httpClient.new GetRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
.setRequestContext(publicApiClient.getRequestContext())
.setScope(getScope()) .setScope(getScope())
.setApiName(apiName) .setApiName(apiName)
.setEntityCollectionName(url) .setEntityCollectionName(url)
@@ -384,7 +379,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getSingle(String url, String entityId, int expectedStatus) throws Exception protected HttpResponse getSingle(String url, String entityId, int expectedStatus) throws Exception
{ {
return getSingle(url, entityId, null, expectedStatus); return getSingle(url, entityId, null, expectedStatus);
@@ -398,7 +393,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, int expectedStatus) throws Exception protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, int expectedStatus)
throws Exception
{ {
HttpResponse response = publicApiClient.get(getScope(), url, entityId, null, null, params); HttpResponse response = publicApiClient.get(getScope(), url, entityId, null, null, params);
checkStatus(expectedStatus, response.getStatusCode()); checkStatus(expectedStatus, response.getStatusCode());
@@ -406,7 +402,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getSingle(Class<?> entityResource, String entityId, Map<String, String> params, int expectedStatus) throws Exception protected HttpResponse getSingle(Class<?> entityResource, String entityId, Map<String, String> params,
int expectedStatus) throws Exception
{ {
HttpResponse response = publicApiClient.get(entityResource, entityId, null, params); HttpResponse response = publicApiClient.get(entityResource, entityId, null, params);
checkStatus(expectedStatus, response.getStatusCode()); checkStatus(expectedStatus, response.getStatusCode());
@@ -414,15 +411,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, Map<String, String> headers, int expectedStatus) throws Exception protected HttpResponse getSingle(String url, String entityId, Map<String, String> params,
Map<String, String> headers, int expectedStatus) throws Exception
{ {
return getSingle(url, entityId, params, headers, null, expectedStatus); return getSingle(url, entityId, params, headers, null, expectedStatus);
} }
protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception protected HttpResponse getSingle(String url, String entityId, Map<String, String> params,
Map<String, String> headers, String apiName, int expectedStatus) throws Exception
{ {
RequestBuilder requestBuilder = httpClient.new GetRequestBuilder() RequestBuilder requestBuilder = httpClient.new GetRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
.setRequestContext(publicApiClient.getRequestContext())
.setScope(getScope()) .setScope(getScope())
.setApiName(apiName) .setApiName(apiName)
.setEntityCollectionName(url) .setEntityCollectionName(url)
@@ -437,7 +435,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
protected HttpResponse getSingleWithDelayRetry(String url, String entityId, Map<String, String> params, protected HttpResponse getSingleWithDelayRetry(String url, String entityId, Map<String, String> params,
Map<String, String> headers, int repeat, long pauseInMillisecond, int expectedStatus) throws Exception Map<String, String> headers, int repeat, long pauseInMillisecond,
int expectedStatus) throws Exception
{ {
int retryCount = 0; int retryCount = 0;
while (retryCount < repeat) while (retryCount < repeat)
@@ -445,7 +444,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
try try
{ {
return getSingle(url, entityId, params, headers, expectedStatus); return getSingle(url, entityId, params, headers, expectedStatus);
} }
catch (AssertionError ex) catch (AssertionError ex)
{ {
retryCount++; retryCount++;
@@ -455,7 +454,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return null; return null;
} }
protected HttpResponse put(String url, String entityId, String body, String queryString, int expectedStatus) throws Exception protected HttpResponse put(String url, String entityId, String body, String queryString, int expectedStatus)
throws Exception
{ {
if (queryString != null) if (queryString != null)
{ {
@@ -467,8 +467,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return response; return response;
} }
protected HttpResponse putBinary(String url, int version, BinaryPayload payload, String queryString, Map<String, String> params, protected HttpResponse putBinary(String url, int version, BinaryPayload payload, String queryString,
int expectedStatus) throws Exception Map<String, String> params, int expectedStatus) throws Exception
{ {
if (queryString != null) if (queryString != null)
{ {
@@ -482,7 +482,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
protected HttpResponse putBinary(String url, BinaryPayload payload, String queryString, Map<String, String> params, protected HttpResponse putBinary(String url, BinaryPayload payload, String queryString, Map<String, String> params,
int expectedStatus) throws Exception int expectedStatus) throws Exception
{ {
return putBinary(url, 1, payload, queryString, params, expectedStatus); return putBinary(url, 1, payload, queryString, params, expectedStatus);
} }
@@ -492,18 +492,19 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return delete(url, entityId, null, expectedStatus); return delete(url, entityId, null, expectedStatus);
} }
protected HttpResponse delete(String url, String entityId, Map<String, String> params, int expectedStatus) throws Exception protected HttpResponse delete(String url, String entityId, Map<String, String> params, int expectedStatus)
throws Exception
{ {
HttpResponse response = publicApiClient.delete(getScope(), 1, url, entityId, null, null, params); HttpResponse response = publicApiClient.delete(getScope(), 1, url, entityId, null, null, params);
checkStatus(expectedStatus, response.getStatusCode()); checkStatus(expectedStatus, response.getStatusCode());
return response; return response;
} }
protected HttpResponse delete(String url, String entityId, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception protected HttpResponse delete(String url, String entityId, Map<String, String> params, Map<String, String> headers,
String apiName, int expectedStatus) throws Exception
{ {
RequestBuilder requestBuilder = httpClient.new DeleteRequestBuilder() RequestBuilder requestBuilder = httpClient.new DeleteRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
.setRequestContext(publicApiClient.getRequestContext())
.setScope(getScope()) .setScope(getScope())
.setApiName(apiName) .setApiName(apiName)
.setEntityCollectionName(url) .setEntityCollectionName(url)
@@ -524,7 +525,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String createUser(String usernameIn, String password, TestNetwork network) protected String createUser(String usernameIn, String password, TestNetwork network)
{ {
return createUser(new PersonInfo(usernameIn, usernameIn, usernameIn, password, null, null, null, null, null, null, null), network); return createUser(
new PersonInfo(usernameIn, usernameIn, usernameIn, password, null, null, null, null, null, null,
null),
network);
} }
/** /**
@@ -533,17 +537,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String createUser(final PersonInfo personInfo, final TestNetwork network) protected String createUser(final PersonInfo personInfo, final TestNetwork network)
{ {
final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN); final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
{
@Override @Override
public String doWork() throws Exception public String doWork() throws Exception
{ {
return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
{
public String doWork() throws Exception public String doWork() throws Exception
{ {
String username = repoService.getPublicApiContext().createUserName(personInfo.getUsername(), tenantDomain); String username = repoService.getPublicApiContext()
.createUserName(personInfo.getUsername(), tenantDomain);
personInfo.setUsername(username); personInfo.setUsername(username);
RepoService.TestPerson person = repoService.createUser(personInfo, username, network); RepoService.TestPerson person = repoService.createUser(personInfo, username, network);
return person.getId(); return person.getId();
@@ -561,17 +564,17 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN); final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
{
@Override @Override
public String doWork() throws Exception public String doWork() throws Exception
{ {
return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
{
public String doWork() throws Exception public String doWork() throws Exception
{ {
String username = repoService.getPublicApiContext().createUserName(usernameIn, tenantDomain); String username = repoService.getPublicApiContext()
PersonInfo personInfo = new PersonInfo(username, username, username, password, null, null, null, null, null, null, null); .createUserName(usernameIn, tenantDomain);
PersonInfo personInfo = new PersonInfo(username, username, username, password, null, null, null, null, null,
null, null);
RepoService.TestPerson person = repoService.getOrCreateUser(personInfo, username, network); RepoService.TestPerson person = repoService.getOrCreateUser(personInfo, username, network);
return person.getId(); return person.getId();
} }
@@ -587,13 +590,11 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN); final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
{
@Override @Override
public String doWork() throws Exception public String doWork() throws Exception
{ {
return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
{
public String doWork() throws Exception public String doWork() throws Exception
{ {
repoService.deleteUser(username, network); repoService.deleteUser(username, network);
@@ -603,13 +604,15 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
}, networkAdmin); }, networkAdmin);
} }
protected SiteMember addSiteMember(String siteId, String userId, final SiteRole siteRole) throws Exception protected SiteMember addSiteMember(String siteId, String userId, final SiteRole siteRole) throws Exception
{ {
SiteMember siteMember = new SiteMember(userId, siteRole.name()); SiteMember siteMember = new SiteMember(userId, siteRole.name());
HttpResponse response = publicApiClient.post(getScope(), "sites", siteId, "members", null, siteMember.toJSON().toString()); HttpResponse response = publicApiClient.post(getScope(), "sites", siteId, "members", null, siteMember.toJSON()
.toString());
checkStatus(201, response.getStatusCode()); checkStatus(201, response.getStatusCode());
return SiteMember.parseSiteMember(siteMember.getSiteId(), (JSONObject)response.getJsonResponse().get("entry")); return SiteMember.parseSiteMember(siteMember.getSiteId(), (JSONObject) response.getJsonResponse()
.get("entry"));
} }
protected Site createSite(String siteTitle, SiteVisibility siteVisibility) throws Exception protected Site createSite(String siteTitle, SiteVisibility siteVisibility) throws Exception
@@ -617,7 +620,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return createSite(null, siteTitle, null, siteVisibility, 201); return createSite(null, siteTitle, null, siteVisibility, 201);
} }
protected Site createSite(String siteId, String siteTitle, String siteDescription, SiteVisibility siteVisibility, int expectedStatus) throws Exception protected Site createSite(String siteId, String siteTitle, String siteDescription, SiteVisibility siteVisibility,
int expectedStatus) throws Exception
{ {
Site site = new Site(); Site site = new Site();
site.setId(siteId); site.setId(siteId);
@@ -633,7 +637,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected HttpResponse deleteSite(String siteId, boolean permanent, int expectedStatus) throws Exception protected HttpResponse deleteSite(String siteId, boolean permanent, int expectedStatus) throws Exception
{ {
Map params = null; Map params = null;
if (permanent == true) if (permanent)
{ {
params = Collections.singletonMap("permanent", "true"); params = Collections.singletonMap("permanent", "true");
} }
@@ -655,14 +659,14 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String getSiteContainerNodeId(String siteId, String containerNameId) throws Exception protected String getSiteContainerNodeId(String siteId, String containerNameId) throws Exception
{ {
Map<String, String> params = Collections.singletonMap(Nodes.PARAM_RELATIVE_PATH, "/Sites/" + siteId + "/" + containerNameId); Map<String, String> params = Collections.singletonMap(Nodes.PARAM_RELATIVE_PATH, "/Sites/" + siteId + "/" + containerNameId);
HttpResponse response = publicApiClient.get(NodesEntityResource.class, Nodes.PATH_ROOT, null, params); HttpResponse response = publicApiClient.get(NodesEntityResource.class, Nodes.PATH_ROOT, null, params);
checkStatus(200, response.getStatusCode()); checkStatus(200, response.getStatusCode());
Node node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class); Node node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
return node.getId(); return node.getId();
} }
protected void checkStatus(int expectedStatus, int actualStatus) protected void checkStatus(int expectedStatus, int actualStatus)
{ {
if (expectedStatus > 0 && expectedStatus != actualStatus) if (expectedStatus > 0 && expectedStatus != actualStatus)
@@ -672,9 +676,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
/** /**
* @deprecated
*
* @param runAsUser * @param runAsUser
* @deprecated
*/ */
protected void setRequestContext(String runAsUser) protected void setRequestContext(String runAsUser)
{ {
@@ -702,9 +705,9 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
} }
else if ((runAsUser != null) && runAsUser.equals(DEFAULT_ADMIN)) else if ((runAsUser != null) && runAsUser.equals(DEFAULT_ADMIN))
{ {
runAsUser = runAsUser+"@"+runAsNetwork; runAsUser = runAsUser + "@" + runAsNetwork;
} }
publicApiClient.setRequestContext(new RequestContext(runAsNetwork, runAsUser, password)); publicApiClient.setRequestContext(new RequestContext(runAsNetwork, runAsUser, password));
} }
@@ -736,7 +739,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
return createFolder(parentId, folderName, null); return createFolder(parentId, folderName, null);
} }
protected Folder createFolder(String parentId, String folderName, Map<String, Object> props) throws Exception protected Folder createFolder(String parentId, String folderName, Map<String, Object> props) throws Exception
{ {
return createNode(parentId, folderName, TYPE_CM_FOLDER, props, Folder.class); return createNode(parentId, folderName, TYPE_CM_FOLDER, props, Folder.class);
@@ -750,17 +753,18 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String createUniqueContent(String folderId) throws Exception protected String createUniqueContent(String folderId) throws Exception
{ {
Document documentResp = createTextFile(folderId, "file-" + System.currentTimeMillis(), Document documentResp = createTextFile(folderId, "file-" + System.currentTimeMillis(),
"some text-" + System.currentTimeMillis(), "UTF-8", null); "some text-" + System.currentTimeMillis(), "UTF-8", null);
return documentResp.getId(); return documentResp.getId();
} }
protected Node createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props) throws Exception protected Node createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props)
throws Exception
{ {
return createNode(parentId, nodeName, nodeType, props, Node.class); return createNode(parentId, nodeName, nodeType, props, Node.class);
} }
protected <T> T createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props, Class<T> returnType) protected <T> T createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props,
throws Exception Class<T> returnType) throws Exception
{ {
Node n = new Node(); Node n = new Node();
n.setName(nodeName); n.setName(nodeName);
@@ -772,7 +776,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), returnType); return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), returnType);
} }
protected void deleteNode(String nodeId) throws Exception protected void deleteNode(String nodeId) throws Exception
{ {
deleteNode(nodeId, 204); deleteNode(nodeId, 204);
@@ -786,25 +790,27 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected void deleteNode(String nodeId, boolean permanent, int expectedStatus) throws Exception protected void deleteNode(String nodeId, boolean permanent, int expectedStatus) throws Exception
{ {
Map params = null; Map params = null;
if (permanent == true) if (permanent)
{ {
params = Collections.singletonMap("permanent", "true"); params = Collections.singletonMap("permanent", "true");
} }
delete(URL_NODES, nodeId, params, expectedStatus); delete(URL_NODES, nodeId, params, expectedStatus);
} }
protected Document createTextFile(String parentId, String fileName, String textContent) throws IOException, Exception protected Document createTextFile(String parentId, String fileName, String textContent) throws Exception
{ {
return createTextFile(parentId, fileName, textContent, "UTF-8", null); return createTextFile(parentId, fileName, textContent, "UTF-8", null);
} }
protected Document createTextFile(String parentId, String fileName, String textContent, String encoding, Map<String, String> props) throws IOException, Exception protected Document createTextFile(String parentId, String fileName, String textContent, String encoding,
Map<String, String> props) throws Exception
{ {
return createTextFile(parentId, fileName, textContent, encoding, props, 201); return createTextFile(parentId, fileName, textContent, encoding, props, 201);
} }
protected Document createTextFile(String parentId, String fileName, String textContent, String encoding, Map<String, String> props, int expectedStatus) throws IOException, Exception protected Document createTextFile(String parentId, String fileName, String textContent, String encoding,
Map<String, String> props, int expectedStatus) throws Exception
{ {
if (props == null) if (props == null)
{ {
@@ -820,9 +826,11 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
.setProperties(props) .setProperties(props)
.build(); .build();
HttpResponse response = post(getNodeChildrenUrl(parentId), reqBody.getBody(), null, reqBody.getContentType(), expectedStatus); HttpResponse response = post(getNodeChildrenUrl(parentId), reqBody.getBody(), null, reqBody.getContentType(),
expectedStatus);
if (response.getJsonResponse().get("error") != null) if (response.getJsonResponse()
.get("error") != null)
{ {
return null; return null;
} }
@@ -834,8 +842,9 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
return createEmptyTextFile(parentFolderId, docName, null, 201); return createEmptyTextFile(parentFolderId, docName, null, 201);
} }
protected Document createEmptyTextFile(String parentFolderId, String docName, Map<String, String> params, int expectedStatus) throws Exception protected Document createEmptyTextFile(String parentFolderId, String docName, Map<String, String> params,
int expectedStatus) throws Exception
{ {
Document d1 = new Document(); Document d1 = new Document();
d1.setName(docName); d1.setName(docName);
@@ -845,7 +854,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
d1.setContent(ci); d1.setContent(ci);
// create empty file // create empty file
HttpResponse response = post(getNodeChildrenUrl(parentFolderId), toJsonAsStringNonNull(d1), params, null, "alfresco", expectedStatus); HttpResponse response = post(getNodeChildrenUrl(parentFolderId), toJsonAsStringNonNull(d1), params, null, "alfresco",
expectedStatus);
if (expectedStatus != 201) if (expectedStatus != 201)
{ {
return null; return null;
@@ -858,7 +868,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return updateTextFile(contentId, textContent, params, 200); return updateTextFile(contentId, textContent, params, 200);
} }
protected Document updateTextFile(String contentId, String textContent, Map<String, String> params, int expectedStatus) throws Exception protected Document updateTextFile(String contentId, String textContent, Map<String, String> params,
int expectedStatus) throws Exception
{ {
ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes()); ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes());
File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt"); File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt");
@@ -874,7 +885,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected File getResourceFile(String fileName) throws FileNotFoundException protected File getResourceFile(String fileName) throws FileNotFoundException
{ {
URL url = NodeApiTest.class.getClassLoader().getResource(RESOURCE_PREFIX + fileName); URL url = NodeApiTest.class.getClassLoader()
.getResource(RESOURCE_PREFIX + fileName);
if (url == null) if (url == null)
{ {
fail("Cannot get the resource: " + fileName); fail("Cannot get the resource: " + fileName);
@@ -907,14 +919,15 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
* @return * @return
* @throws Exception * @throws Exception
*/ */
protected String updateFileVersions(String userId, String contentNodeId, int cnt, protected String updateFileVersions(String userId, String contentNodeId, int cnt, String textContentPrefix,
String textContentPrefix, int verCnt, int verCnt, Boolean majorVersion, String currentVersionLabel) throws Exception
Boolean majorVersion, String currentVersionLabel) throws Exception
{ {
String[] parts = currentVersionLabel.split("\\."); String[] parts = currentVersionLabel.split("\\.");
int majorVer = Integer.valueOf(parts[0]).intValue(); int majorVer = Integer.valueOf(parts[0])
int minorVer = Integer.valueOf(parts[1]).intValue(); .intValue();
int minorVer = Integer.valueOf(parts[1])
.intValue();
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put(Nodes.PARAM_OVERWRITE, "true"); params.put(Nodes.PARAM_OVERWRITE, "true");
@@ -928,7 +941,6 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
majorVersion = false; majorVersion = false;
} }
if (majorVersion) if (majorVersion)
{ {
minorVer = 0; minorVer = 0;
@@ -961,30 +973,33 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
HttpResponse response = putBinary(getNodeContentUrl(contentNodeId), payload, null, params, 200); HttpResponse response = putBinary(getNodeContentUrl(contentNodeId), payload, null, params, 200);
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class); Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
assertTrue(nodeResp.getAspectNames().contains("cm:versionable")); assertTrue(nodeResp.getAspectNames()
.contains("cm:versionable"));
assertNotNull(nodeResp.getProperties()); assertNotNull(nodeResp.getProperties());
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel")); assertEquals(currentVersionLabel, nodeResp.getProperties()
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType")); .get("cm:versionLabel"));
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties()
.get("cm:versionType"));
// double-check - get version node info // double-check - get version node info
response = getSingle(getNodeVersionsUrl(contentNodeId), currentVersionLabel, null, 200); response = getSingle(getNodeVersionsUrl(contentNodeId), currentVersionLabel, null, 200);
nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class); nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel")); assertEquals(currentVersionLabel, nodeResp.getProperties()
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType")); .get("cm:versionLabel"));
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties()
.get("cm:versionType"));
} }
return currentVersionLabel; return currentVersionLabel;
} }
protected static final long PAUSE_TIME = 5000; //millisecond
protected static final int MAX_RETRY = 20;
protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception
{ {
return waitAndGetRendition(sourceNodeId, versionId, renditionId, MAX_RETRY, PAUSE_TIME); return waitAndGetRendition(sourceNodeId, versionId, renditionId, MAX_RETRY, PAUSE_TIME);
} }
protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId, int maxRetry, long pauseTime) throws Exception protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId, int maxRetry,
long pauseTime) throws Exception
{ {
int retryCount = 0; int retryCount = 0;
while (retryCount < maxRetry) while (retryCount < maxRetry)
@@ -992,7 +1007,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
try try
{ {
HttpResponse response; HttpResponse response;
if ((versionId != null) && (! versionId.isEmpty())) if ((versionId != null) && (!versionId.isEmpty()))
{ {
response = getSingle(getNodeVersionRenditionsUrl(sourceNodeId, versionId), renditionId, 200); response = getSingle(getNodeVersionRenditionsUrl(sourceNodeId, versionId), renditionId, 200);
} }
@@ -1011,7 +1026,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
// wait for 'PAUSE_TIME' and try again. // wait for 'PAUSE_TIME' and try again.
retryCount++; retryCount++;
System.out.println("waitAndGetRendition: "+retryCount); System.out.println("waitAndGetRendition: " + retryCount);
Thread.sleep(pauseTime); Thread.sleep(pauseTime);
} }
} }
@@ -1024,7 +1039,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return createAndGetRendition(sourceNodeId, null, renditionId); return createAndGetRendition(sourceNodeId, null, renditionId);
} }
protected Rendition createAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception protected Rendition createAndGetRendition(String sourceNodeId, String versionId, String renditionId)
throws Exception
{ {
Rendition renditionRequest = new Rendition(); Rendition renditionRequest = new Rendition();
renditionRequest.setId(renditionId); renditionRequest.setId(renditionId);
@@ -1035,9 +1051,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
try try
{ {
HttpResponse response; HttpResponse response;
if ((versionId != null) && (! versionId.isEmpty())) if ((versionId != null) && (!versionId.isEmpty()))
{ {
response = post(getNodeVersionRenditionsUrl(sourceNodeId, versionId), toJsonAsString(renditionRequest), 202); response = post(getNodeVersionRenditionsUrl(sourceNodeId, versionId),
toJsonAsString(renditionRequest), 202);
} }
else else
{ {
@@ -1052,7 +1069,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
// wait for 'PAUSE_TIME' and try again. // wait for 'PAUSE_TIME' and try again.
retryCount++; retryCount++;
System.out.println("waitAndGetRendition: "+retryCount); System.out.println("waitAndGetRendition: " + retryCount);
Thread.sleep(PAUSE_TIME); Thread.sleep(PAUSE_TIME);
} }
} }
@@ -1072,7 +1089,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
protected String getNodeVersionRenditionIdUrl(String nodeId, String versionId, String renditionID) protected String getNodeVersionRenditionIdUrl(String nodeId, String versionId, String renditionID)
{ {
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS + "/" + renditionID; return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS + "/"
+ renditionID;
} }
protected String getNodeVersionsUrl(String nodeId) protected String getNodeVersionsUrl(String nodeId)
@@ -1120,5 +1138,14 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
RestApiDirectUrlConfig restDauConfig = (RestApiDirectUrlConfig) applicationContext.getBean("restApiDirectUrlConfig"); RestApiDirectUrlConfig restDauConfig = (RestApiDirectUrlConfig) applicationContext.getBean("restApiDirectUrlConfig");
restDauConfig.setEnabled(false); restDauConfig.setEnabled(false);
} }
}
protected String generateNodeSizeDetailsUrl(String nodeId)
{
return URL_NODES + "/" + nodeId + "/" + URL_CALCULATEFOLDERSIZE;
}
protected String getNodeSizeDetailsUrl(String nodeId, String jobId)
{
return URL_NODES + "/" + nodeId + "/" + URL_CALCULATEFOLDERSIZE + "/" + jobId;
}
}

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>23.4.0.45</version> <version>23.4.2.1</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -1,286 +1,282 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.audit; package org.alfresco.repo.audit;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.audit.model.AuditApplication; import org.alfresco.repo.audit.model.AuditApplication;
import org.alfresco.repo.audit.model.AuditModelRegistry; import org.alfresco.repo.audit.model.AuditModelRegistry;
import org.alfresco.repo.audit.model._3.AuditPath; import org.alfresco.repo.audit.model._3.AuditPath;
import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
/** /**
* The audit component. Used by the AuditService and AuditMethodInterceptor to insert audit entries. * The audit component. Used by the AuditService and AuditMethodInterceptor to insert audit entries.
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
public interface AuditComponent public interface AuditComponent
{ {
/** /**
* Determines whether audit is globally enabled or disabled. * Determines whether audit is globally enabled or disabled.
* *
* @return Returns <code>true</code> if audit is enabled * @return Returns <code>true</code> if audit is enabled
* *
* @since 3.3 * @since 3.3
*/ */
public boolean isAuditEnabled(); public boolean isAuditEnabled();
/** /**
* Switch auditing on or off * Switch auditing on or off
* *
* @param enable <tt>true</tt> to enable auditing or <tt>false</tt> to disable * @param enable
* * <tt>true</tt> to enable auditing or <tt>false</tt> to disable
* @since 3.4 *
*/ * @since 3.4
public void setAuditEnabled(boolean enable); */
public void setAuditEnabled(boolean enable);
/**
* @param userAuditFilter UserAuditFilter /**
* * @param userAuditFilter
* @since 4.2 * UserAuditFilter
*/ *
public void setUserAuditFilter(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 * Get all registered audit applications, whether active or not.
* *
* @since 3.4 * @return Returns a map of registered audit applications keyed by name
*/ *
public Map<String, AuditApplication> getAuditApplications(); * @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 * 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>.
* 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}.
* *
* @return Returns <code>true</code> if the calling code (data producers) * @since 3.3
* should go ahead and generate the data for */
* {@link #recordAuditValues(String, Map) recording}. public boolean areAuditValuesRequired();
*
* @since 3.3 /**
*/ * 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.
public boolean areAuditValuesRequired(); *
* @param path
/** * the audit path
* Determines if audit values are required based on whether there are any audit applications * @return Returns <tt>true</tt> if there is at least one audit application registered to handle the given path.
* 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. * @since 3.4
* */
* @param path the audit path public boolean areAuditValuesRequired(String path);
* @return Returns <tt>true</tt> if there is at least one audit application
* registered to handle the given path. /**
* * Delete audit entries for the given application and time range
* @since 3.4 *
*/ * @param applicationName
public boolean areAuditValuesRequired(String path); * the name of the application
* @param fromTime
/** * the start time of entries to remove (inclusive and optional)
* Delete audit entries for the given application and time range * @param toTime
* * the end time of entries to remove (exclusive and optional)
* @param applicationName the name of the application * @return Returns the number of entries deleted
* @param fromTime the start time of entries to remove (inclusive and optional) *
* @param toTime the end time of entries to remove (exclusive and optional) * @since 3.2
* @return Returns the number of entries deleted */
* int deleteAuditEntries(String applicationName, Long fromTime, Long toTime);
* @since 3.2
*/ /**
int deleteAuditEntries(String applicationName, Long fromTime, Long toTime); * Delete audit entries for the given application and id range
*
/** * @param applicationName
* Delete audit entries for the given application and id range * the name of the application
* * @param fromId
* @param applicationName the name of the application * the start time of entries to remove (inclusive and optional)
* @param fromId the start time of entries to remove (inclusive and optional) * @param toId
* @param toId the end time of entries to remove (exclusive and optional) * the end time of entries to remove (exclusive and optional)
* @return Returns the number of entries deleted * @return Returns the number of entries deleted
* *
* @since 5.2.2 * @since 5.2.2
*/ */
int deleteAuditEntriesByIdRange(String applicationName, Long fromId, Long toId); int deleteAuditEntriesByIdRange(String applicationName, Long fromId, Long toId);
/** /**
* Delete a discrete list of audit entries based on ID * Delete a discrete list of audit entries based on ID
* *
* @param auditEntryIds the audit entry IDs to delete * @param auditEntryIds
* @return Returns the number of entries deleted * the audit entry IDs to delete
*/ * @return Returns the number of entries deleted
int deleteAuditEntries(List<Long> auditEntryIds); */
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 * 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.
* data is audited. *
* * @param applicationName
* @param applicationName the name of the application being logged to * the name of the application being logged to
* @param path the audit path to check or <tt>null</tt> to assume the * @param path
* application's root 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 * @return Returns <tt>true</tt> if the audit path has been disabled
* *
* @since 3.2 * @since 3.2
*/ */
boolean isAuditPathEnabled(String applicationName, String path); boolean isAuditPathEnabled(String applicationName, String path);
/** /**
* Enable auditing (if it is not already enabled) for all paths that contain the given 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.
* The path is the path as originally logged and * <p>
* not the path that the generated data may contain - although this would be similarly * If the enabled
* enabled. *
* <p> * @param applicationName
* If the enabled * the name of the application being logged to
* * @param path
* @param applicationName the name of the application being logged to * the audit path to check or <tt>null</tt> to assume the application's root path
* @param path the audit path to check or <tt>null</tt> to assume the *
* application's root path * @since 3.2
* */
* @since 3.2 void enableAudit(String applicationName, String path);
*/
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>
* Disable auditing (if it is not already disabled) for all paths that contain the given path. * 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.
* The path is the path as originally logged and *
* not the path that the generated data may contain - although this would be similarly * @param applicationName
* disabled. * the name of the application being logged to
* <p> * @param path
* If the path is <b>/x/y</b> then any data paths that start with <b>/x/y</b> will be stripped * the audit path to check or <tt>null</tt> to assume the application's root path
* 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. * @since 3.2
* */
* @param applicationName the name of the application being logged to void disableAudit(String applicationName, String path);
* @param path the audit path to check or <tt>null</tt> to assume the
* application's root 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}.
* @since 3.2 *
*/ * @param applicationName
void disableAudit(String applicationName, String path); * the name of the application
*
/** * @since 3.2
* 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 void resetDisabledPaths(String applicationName);
* paths need {@link #enableAudit(String, String) enabling} or
* {@link #disableAudit(String, String) disabled}. /**
* * 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.
* @param applicationName the name of the application * <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).
* @since 3.2 * <p/>
*/ * The return values reflect what was actually persisted and is controlled by the data extractors defined in the audit configuration.
void resetDisabledPaths(String applicationName); * <p/>
* A new read-write transaction is started if there are values to write that there is not a viable transaction present.
/** *
* Create an audit entry for the given map of values. The map key is a path - starting with '/' * @param rootPath
* ({@link AuditApplication#AUDIT_PATH_SEPARATOR}) - relative to the root path provided. * a base path of {@link AuditPath} key entries concatenated with the path separator '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR})
* <p/> * @param values
* The root path and value keys are combined to produce a map of data keyed by full path. This * the values to audit mapped by {@link AuditPath} key relative to root path (may be <tt>null</tt>)
* fully-pathed map is then passed through the * @return Returns the values that were actually persisted, keyed by their full path.
* {@link AuditModelRegistry#getAuditPathMapper() audit path mapper}. The result may yield data * @throws IllegalStateException
* destined for several different * if the transaction state could not be determined
* {@link AuditModelRegistry#getAuditApplicationByKey(String) audit applications}. depending on *
* the data extraction and generation defined in the applications, values (or derived values) may * @since 3.2
* be recorded against several audit entries (one per application represented). */
* <p/> Map<String, Serializable> recordAuditValues(String rootPath, Map<String, Serializable> values);
* The return values reflect what was actually persisted and is controlled by the data extractors
* defined in the audit configuration. /**
* <p/> * The same as {@link AuditComponent#recordAuditValues(String, Map)}, but with controlled usage of userFilter
* 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 rootPath a base path of {@link AuditPath} key entries concatenated with the path separator * @param values
* '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR}) * the values to audit mapped by {@link AuditPath} key relative to root path (may be <tt>null</tt>)
* @param values the values to audit mapped by {@link AuditPath} key relative to root path * @param useUserFilter
* (may be <tt>null</tt>) * if <tt>false</tt> the user filter is disabled.
* @return Returns the values that were actually persisted, keyed by their full path. * @return Returns the values that were actually persisted, keyed by their full path.
* @throws IllegalStateException if the transaction state could not be determined * @throws IllegalStateException
* * if the transaction state could not be determined
* @since 3.2 */
*/ Map<String, Serializable> recordAuditValuesWithUserFilter(String rootPath, Map<String, Serializable> values, boolean useUserFilter);
Map<String, Serializable> recordAuditValues(String rootPath, Map<String, Serializable> values);
/**
/** * Find audit entries using the given parameters
* The same as {@link AuditComponent#recordAuditValues(String, Map)}, but with controlled usage of userFilter *
* * @param callback
* @param rootPath a base path of {@link AuditPath} key entries concatenated with the path separator * the data callback per entry
* '/' ({@link AuditApplication#AUDIT_PATH_SEPARATOR}) * @param parameters
* @param values the values to audit mapped by {@link AuditPath} key relative to root path * the parameters for the query (may not be <tt>null</tt>)
* (may be <tt>null</tt>) * @param maxResults
* @param useUserFilter if <tt>false</tt> the user filter is disabled. * the maximum number of results to retrieve (must be greater than 0)
* @return Returns the values that were actually persisted, keyed by their full path. *
* @throws IllegalStateException if the transaction state could not be determined * @throws IllegalArgumentException
*/ * if maxResults less or equal to zero
Map<String, Serializable> recordAuditValuesWithUserFilter(String rootPath, Map<String, Serializable> values, boolean useUserFilter); *
* @since 3.2
/** */
* Find audit entries using the given parameters void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
*
* @param callback the data callback per entry /**
* @param parameters the parameters for the query (may not be <tt>null</tt>) * Issue an audit query to retrieve min / max audit record id for a given application.
* @param maxResults the maximum number of results to retrieve (must be greater than 0) *
* * @param applicationName
* @throws IllegalArgumentException if maxResults less or equal to zero * the name of the application
* * @param extremes
* @since 3.2 * a list containing min/max or both
*/ * @return a map containing min/max and the associated value
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults); */
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes);
/**
* Issue an audit query to retrieve min / max audit record id for a given application. /**
* * Issue an audit query to retrieve count of records for a given application.
* @param applicationName the name of the application *
* @param extremes a list containing min/max or both * @param applicationName
* @return a map containing min/max and the associated value * the name of the application
*/ * @return a map containing min/max and the associated value
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes); */
default int getAuditEntriesCountByApp(String applicationName)
/** {
* Issue an audit query to retrieve count of records for a given application. return -1;
* }
* @param applicationName the name of the application
* @return a map containing min/max and the associated value /**
*/ * Issue an audit query to retrieve count of records for a given application and properties
default int getAuditEntriesCountByApp(String applicationName) *
{ * @param applicationName
return -1; * 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
* Issue an audit query to retrieve count of records for a given application and properties */
* default int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
* @param parameters audit parameters provided by the <code>where</code> clause on the ReST API {
* @return a map containing min/max and the associated value return -1;
*/ }
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters) }
{
return -1;
}
}

View File

@@ -1,197 +1,209 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.audit; package org.alfresco.repo.audit;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService; import org.alfresco.service.cmr.audit.AuditService;
/** /**
* The implementation of the AuditService for application auditing. * The implementation of the AuditService for application auditing.
* *
* @author Derek Hulley * @author Derek Hulley
* @since 3.2 * @since 3.2
*/ */
public class AuditServiceImpl implements AuditService public class AuditServiceImpl implements AuditService
{ {
private AuditComponent auditComponent; private AuditComponent auditComponent;
public AuditServiceImpl() public AuditServiceImpl()
{ {
super(); super();
} }
public void setAuditComponent(AuditComponent auditComponent) public void setAuditComponent(AuditComponent auditComponent)
{ {
this.auditComponent = auditComponent; this.auditComponent = auditComponent;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 3.4 *
*/ * @since 3.4
public boolean isAuditEnabled() */
{ public boolean isAuditEnabled()
return auditComponent.isAuditEnabled(); {
} return auditComponent.isAuditEnabled();
}
/**
* {@inheritDoc} /**
* @since 3.4 * {@inheritDoc}
*/ *
@Override * @since 3.4
public void setAuditEnabled(boolean enable) */
{ @Override
auditComponent.setAuditEnabled(enable); public void setAuditEnabled(boolean enable)
} {
auditComponent.setAuditEnabled(enable);
/** }
* {@inheritDoc}
* @since 3.4 /**
*/ * {@inheritDoc}
@Override *
public Map<String, AuditApplication> getAuditApplications() * @since 3.4
{ */
Map<String, org.alfresco.repo.audit.model.AuditApplication> apps = auditComponent.getAuditApplications(); @Override
public Map<String, AuditApplication> getAuditApplications()
Map<String, AuditApplication> ret = new TreeMap<String, AuditApplication>(); {
for (String app : apps.keySet()) Map<String, org.alfresco.repo.audit.model.AuditApplication> apps = auditComponent.getAuditApplications();
{
String name = app; Map<String, AuditApplication> ret = new TreeMap<String, AuditApplication>();
String key = org.alfresco.repo.audit.model.AuditApplication.AUDIT_PATH_SEPARATOR + apps.get(app).getApplicationKey(); for (String app : apps.keySet())
boolean enabled = auditComponent.isAuditPathEnabled(app, key); {
AuditApplication auditApplication = new AuditApplication(name, key, enabled); String name = app;
ret.put(name, auditApplication); String key = org.alfresco.repo.audit.model.AuditApplication.AUDIT_PATH_SEPARATOR + apps.get(app).getApplicationKey();
} boolean enabled = auditComponent.isAuditPathEnabled(app, key);
return ret; AuditApplication auditApplication = new AuditApplication(name, key, enabled);
} ret.put(name, auditApplication);
}
/** return ret;
* {@inheritDoc} }
* @since 3.2
*/ /**
public boolean isAuditEnabled(String applicationName, String path) * {@inheritDoc}
{ *
return auditComponent.isAuditPathEnabled(applicationName, path); * @since 3.2
} */
public boolean isAuditEnabled(String applicationName, String path)
/** {
* {@inheritDoc} return auditComponent.isAuditPathEnabled(applicationName, path);
* @since 3.2 }
*/
public void enableAudit(String applicationName, String path) /**
{ * {@inheritDoc}
auditComponent.enableAudit(applicationName, path); *
} * @since 3.2
*/
/** public void enableAudit(String applicationName, String path)
* {@inheritDoc} {
* @since 3.2 auditComponent.enableAudit(applicationName, path);
*/ }
public void disableAudit(String applicationName, String path)
{ /**
auditComponent.disableAudit(applicationName, path); * {@inheritDoc}
} *
* @since 3.2
/** */
* {@inheritDoc} public void disableAudit(String applicationName, String path)
* @since 3.2 {
*/ auditComponent.disableAudit(applicationName, path);
public int clearAudit(String applicationName) }
{
Long now = Long.valueOf(System.currentTimeMillis()); /**
return auditComponent.deleteAuditEntries(applicationName, null, now); * {@inheritDoc}
} *
* @since 3.2
/** */
* {@inheritDoc} public int clearAudit(String applicationName)
* @since 3.4 {
*/ Long now = Long.valueOf(System.currentTimeMillis());
@Override return auditComponent.deleteAuditEntries(applicationName, null, now);
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 3.4
/** */
* {@inheritDoc} @Override
* @since 5.2.2 public int clearAudit(String applicationName, Long fromTime, Long toTime)
*/ {
@Override toTime = (toTime == null) ? Long.valueOf(System.currentTimeMillis()) : toTime;
public int clearAuditByIdRange(String applicationName, Long fromId, Long toId) return auditComponent.deleteAuditEntries(applicationName, fromTime, toTime);
{ }
return auditComponent.deleteAuditEntriesByIdRange(applicationName, fromId, toId);
} /**
* {@inheritDoc}
/** *
* {@inheritDoc} * @since 5.2.2
* @since 3.4 */
*/ @Override
@Override public int clearAuditByIdRange(String applicationName, Long fromId, Long toId)
public int clearAudit(List<Long> auditEntryIds) {
{ return auditComponent.deleteAuditEntriesByIdRange(applicationName, fromId, toId);
return auditComponent.deleteAuditEntries(auditEntryIds); }
}
/**
/** * {@inheritDoc}
* {@inheritDoc} *
* @since 3.3 * @since 3.4
*/ */
public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults) @Override
{ public int clearAudit(List<Long> auditEntryIds)
auditComponent.auditQuery(callback, parameters, maxResults); {
} return auditComponent.deleteAuditEntries(auditEntryIds);
}
/**
* {@inheritDoc} /**
*/ * {@inheritDoc}
public HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes) *
{ * @since 3.3
return auditComponent.getAuditMinMaxByApp(applicationName, extremes); */
} public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults)
{
/** auditComponent.auditQuery(callback, parameters, maxResults);
* {@inheritDoc} }
*/
@Override /**
public int getAuditEntriesCountByApp(String applicationName) * {@inheritDoc}
{ */
return auditComponent.getAuditEntriesCountByApp(applicationName); public HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes)
} {
return auditComponent.getAuditMinMaxByApp(applicationName, extremes);
/** }
* {@inheritDoc}
*/ /**
@Override public int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters) * {@inheritDoc}
{ */
return auditComponent.getAuditEntriesCountByAppAndProperties(parameters); @Override
} public int getAuditEntriesCountByApp(String applicationName)
} {
return auditComponent.getAuditEntriesCountByApp(applicationName);
}
/**
* {@inheritDoc}
*/
@Override
public int getAuditEntriesCountByAppAndProperties(String applicationName, AuditQueryParameters parameters)
{
return auditComponent.getAuditEntriesCountByAppAndProperties(applicationName, parameters);
}
}

View File

@@ -1,123 +1,116 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain; package org.alfresco.repo.domain;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
/** /**
* Helper class to calculate CRC values for string persistence. * Helper class to calculate CRC values for string persistence.
* *
* @author Derek Hulley * @author Derek Hulley
* @since 3.2 * @since 3.2
*/ */
public class CrcHelper public class CrcHelper
{ {
public static final String EMPTY_STRING = ".empty"; public static final String EMPTY_STRING = ".empty";
/** /**
* Calculate a persistable, unique pair of values that can be persisted in a database unique * Calculate a persistable, unique pair of values that can be persisted in a database unique key and guarantee correct case-sensitivity.
* key and guarantee correct case-sensitivity. * <p>
* <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.
* While the short-string version of the value is always lowercase, the CRC is * <p>
* calculated from the virgin string if case-sensitivity is enforced; in the case-insensitive * 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>.
* case, the CRC is calculated from a lowercase version of the string. *
* <p> * @param value
* If the value is an empty string, then {@link #EMPTY_STRING} is used instead. This ensures * the raw value that will be persisted
* that persisted values don't fall foul of the Oracle empty string comparison "behaviour" i.e * @param dataLength
* you should never persist an empty string in Oracle as it equates to a SQL <b>NULL</b>. * the maximum number of characters that can be persisted
* * @param useCharsFromStart
* @param value the raw value that will be persisted * <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 dataLength the maximum number of characters that can be persisted * @param caseSensitive
* @param useCharsFromStart <tt>true</tt> if the shortened string value must be made from * <tt>true</tt> if the resulting pair must be case-sensitive or <tt>false</tt> if the pair must be case-insensitive.
* the first characters of the string or <tt>false</tt> to use * @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>
* characters from the end of the string. */
* @param caseSensitive <tt>true</tt> if the resulting pair must be case-sensitive or public static Pair<String, Long> getStringCrcPair(
* <tt>false</tt> if the pair must be case-insensitive. String value,
* @return Return the persistable pair. The result will never be <tt>null</tt>, int dataLength,
* but the individual pair values will be <tt>null</tt> if the boolean useCharsFromStart,
* value given is <tt>null</tt> boolean caseSensitive)
*/ {
public static Pair<String, Long> getStringCrcPair( String valueLowerCase;
String value, if (value == null)
int dataLength, {
boolean useCharsFromStart, return new Pair<String, Long>(null, null);
boolean caseSensitive) }
{ else if (value.length() == 0)
String valueLowerCase; {
if (value == null) value = CrcHelper.EMPTY_STRING;
{ valueLowerCase = value;
return new Pair<String, Long>(null, null); }
} else
else if (value.length() == 0) {
{ valueLowerCase = value.toLowerCase();
value = CrcHelper.EMPTY_STRING; }
valueLowerCase = value; Long valueCrc;
} try
else {
{ CRC32 crc = new CRC32();
valueLowerCase = value.toLowerCase(); if (caseSensitive)
} {
Long valueCrc; crc.update(value.getBytes("UTF-8"));
try }
{ else
CRC32 crc = new CRC32(); {
if (caseSensitive) crc.update(valueLowerCase.getBytes("UTF-8"));
{ }
crc.update(value.getBytes("UTF-8")); valueCrc = crc.getValue();
} }
else catch (UnsupportedEncodingException e)
{ {
crc.update(valueLowerCase.getBytes("UTF-8")); throw new RuntimeException("UTF-8 encoding is not supported");
} }
valueCrc = crc.getValue(); // Get the short value (case-sensitive or not)
} String valueShort = null;
catch (UnsupportedEncodingException e) int valueLen = valueLowerCase.length();
{ if (valueLen < dataLength)
throw new RuntimeException("UTF-8 encoding is not supported"); {
} valueShort = valueLowerCase;
// Crc Value will change based on the case-sensitive, So we need to get the short value based on case-sensitive }
String valueShort = null; else if (useCharsFromStart)
String currentValue = caseSensitive ? value : valueLowerCase; {
int valueLen = currentValue.length(); valueShort = valueLowerCase.substring(0, dataLength - 1);
if (valueLen < dataLength) }
{ else
valueShort = currentValue; {
} valueShort = valueLowerCase.substring(valueLen - dataLength);
else if (useCharsFromStart) }
{ return new Pair<String, Long>(valueShort, valueCrc);
valueShort = currentValue.substring(0, dataLength - 1); }
} }
else
{
valueShort = currentValue.substring(valueLen - dataLength);
}
return new Pair<String, Long>(valueShort, valueCrc);
}
}

View File

@@ -1,258 +1,285 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain.audit; package org.alfresco.repo.domain.audit;
import java.io.Serializable; import java.io.Serializable;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
/** /**
* DAO services for <b>alf_audit_XXX</b> tables. * DAO services for <b>alf_audit_XXX</b> tables.
* <p> * <p>
* The older methods are supported by a different implementation and will eventually * The older methods are supported by a different implementation and will eventually be deprecated and phased out.
* be deprecated and phased out. *
* * @author Derek Hulley
* @author Derek Hulley * @since 3.2
* @since 3.2 */
*/ public interface AuditDAO
public interface AuditDAO {
{ /* V3.2 methods after here only, please */
/*
* V3.2 methods after here only, please /**
*/ * Information about the audit application to be passed in an out of the interface.
*
/** * @author Derek Hulley
* Information about the audit application to be passed in an out of the interface. * @since 3.2
* */
* @author Derek Hulley public static class AuditApplicationInfo
* @since 3.2 {
*/ private Long id;
public static class AuditApplicationInfo private String name;
{ private Long modelId;
private Long id; private Long disabledPathsId;
private String name;
private Long modelId; @Override
private Long disabledPathsId; public String toString()
{
@Override StringBuilder sb = new StringBuilder();
public String toString() sb.append("AuditApplicationInfo ")
{ .append("[ id=").append(id)
StringBuilder sb = new StringBuilder(); .append(", name=").append(name)
sb.append("AuditApplicationInfo ") .append(", modelId=").append(modelId)
.append("[ id=").append(id) .append(", disabledPathsId=").append(disabledPathsId)
.append(", name=").append(name) .append("]");
.append(", modelId=").append(modelId) return sb.toString();
.append(", disabledPathsId=").append(disabledPathsId) }
.append("]");
return sb.toString(); public Long getId()
} {
return id;
public Long getId() }
{
return id; public void setId(Long id)
} {
public void setId(Long id) this.id = id;
{ }
this.id = id;
} public String getName()
public String getName() {
{ return name;
return name; }
}
public void setname(String name) public void setname(String name)
{ {
this.name = name; this.name = name;
} }
public Long getModelId()
{ public Long getModelId()
return modelId; {
} return modelId;
public void setModelId(Long modelId) }
{
this.modelId = modelId; public void setModelId(Long modelId)
} {
public Long getDisabledPathsId() this.modelId = modelId;
{ }
return disabledPathsId;
} public Long getDisabledPathsId()
public void setDisabledPathsId(Long disabledPathsId) {
{ return disabledPathsId;
this.disabledPathsId = 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 * Creates a new audit model entry or finds an existing one
* @since 3.2 *
*/ * @param url
Pair<Long, ContentData> getOrCreateAuditModel(URL 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
* Get the audit application details. */
* Pair<Long, ContentData> getOrCreateAuditModel(URL url);
* @param applicationName the name of the application
* @return Returns details of an existing application or <tt>null</tt> if it doesn't exist /**
* * Get the audit application details.
* @since 3.2 *
*/ * @param applicationName
AuditApplicationInfo getAuditApplication(String applicationName); * the name of the application
* @return Returns details of an existing application or <tt>null</tt> if it doesn't exist
/** *
* Creates a new audit application. The application name must be unique. * @since 3.2
* */
* @param application the name of the application AuditApplicationInfo getAuditApplication(String applicationName);
* @param modelId the ID of the model configuration
* /**
* @since 3.2 * Creates a new audit application. The application name must be unique.
*/ *
AuditApplicationInfo createAuditApplication(String application, Long modelId); * @param application
* the name of the application
/** * @param modelId
* Update the audit application to refer to a new model. * the ID of the model configuration
* If the model did not change, then nothing will be done. *
* * @since 3.2
* @param id the ID of the audit application */
* @param modelId the ID of the new model AuditApplicationInfo createAuditApplication(String application, Long modelId);
*
* @since 3.2 /**
*/ * Update the audit application to refer to a new model. If the model did not change, then nothing will be done.
void updateAuditApplicationModel(Long id, Long modelId); *
* @param id
/** * the ID of the audit application
* Update the audit application to hold a new set of disabled paths. * @param modelId
* If the value did not change, then nothing will be done. * the ID of the new model
* *
* @param id the ID of the audit application * @since 3.2
* @param disabledPaths the new disabled paths */
* void updateAuditApplicationModel(Long id, Long modelId);
* @since 3.2
*/ /**
void updateAuditApplicationDisabledPaths(Long id, Set<String> disabledPaths); * 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
* Delete audit entries for the application, possibly limiting the time range. * the ID of the audit application
* * @param disabledPaths
* @param applicationId an existing audit application ID * the new disabled paths
* @param fromTime the minimum entry time (inclusive, optional) *
* @param toTime the maximum entry time (exclusive, optional) * @since 3.2
* @return Returns the number of entries deleted */
* void updateAuditApplicationDisabledPaths(Long id, Set<String> disabledPaths);
* @since 3.2
*/ /**
int deleteAuditEntries(Long applicationId, Long fromTime, Long toTime); * Delete audit entries for the application, possibly limiting the time range.
*
/** * @param applicationId
* Delete audit entries for the application for given id range. * an existing audit application ID
* * @param fromTime
* @param applicationId an existing audit application ID * the minimum entry time (inclusive, optional)
* @param fromId the minimum fromId (inclusive, optional) * @param toTime
* @param toId the maximum toId (exclusive, optional) * the maximum entry time (exclusive, optional)
* @return Returns the number of entries deleted * @return Returns the number of entries deleted
* *
* @since 5.2.2 * @since 3.2
*/ */
int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId); int deleteAuditEntries(Long applicationId, Long fromTime, Long toTime);
/** /**
* Delete a discrete list of audit entries. Duplicate entries are collapsed * Delete audit entries for the application for given id range.
* 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 * @param applicationId
* will be generated. * an existing audit application ID
* * @param fromId
* @param auditEntryIds the IDs of all audit entries to delete * the minimum fromId (inclusive, optional)
* @return Returns the number of entries deleted * @param toId
*/ * the maximum toId (exclusive, optional)
int deleteAuditEntries(List<Long> auditEntryIds); * @return Returns the number of entries deleted
*
/** * @since 5.2.2
* Create a new audit entry with the given map of values. */
* int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId);
* @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) * 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 values the values to record *
* @return Returns the unique entry ID * @param auditEntryIds
* * the IDs of all audit entries to delete
* @since 3.2 * @return Returns the number of entries deleted
*/ */
Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values); int deleteAuditEntries(List<Long> auditEntryIds);
/** /**
* Find audit entries using the given parameters, any of which may be null * Create a new audit entry with the given map of values.
* *
* @param callback the data callback per entry * @param applicationId
* @param parameters the parameters for the query (may not be <tt>null</tt>) * an existing audit application ID
* @param maxResults the maximum number of results to retrieve (must be greater than 0) * @param time
* * the time (ms since epoch) to log the entry against
* @throws IllegalArgumentException if maxResults less or equal to zero * @param username
*/ * the authenticated user (<tt>null</tt> if not present)
void findAuditEntries( * @param values
AuditQueryCallback callback, * the values to record
org.alfresco.service.cmr.audit.AuditQueryParameters parameters, * @return Returns the unique entry ID
int maxResults); *
* @since 3.2
/** */
* Issue an audit query to retrieve min / max audit record id for a given application. Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values);
*
* @param appId the database id of the application /**
* @param extremes a list containing min/max or both * Find audit entries using the given parameters, any of which may be null
* @return a map containing min/max and the associated value *
*/ * @param callback
HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes); * the data callback per entry
* @param parameters
/** * the parameters for the query (may not be <tt>null</tt>)
* Issue an audit query to retrieve count of records for a given application. * @param maxResults
* * the maximum number of results to retrieve (must be greater than 0)
* @param applicationId the database id of the application *
* @return a map containing min/max and the associated value * @throws IllegalArgumentException
*/ * if maxResults less or equal to zero
default int getAuditEntriesCountByApp(long applicationId) */
{ void findAuditEntries(
return -1; AuditQueryCallback callback,
} org.alfresco.service.cmr.audit.AuditQueryParameters parameters,
int maxResults);
/**
* Issue an audit query to retrieve count of records for a given application and properties /**
* * Issue an audit query to retrieve min / max audit record id for a given 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 * @param appId
*/ * the database id of the application
default int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters) * @param extremes
{ * a list containing min/max or both
return -1; * @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;
}
}

View File

@@ -1,316 +1,315 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain.audit.ibatis; package org.alfresco.repo.domain.audit.ibatis;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl; import org.apache.ibatis.session.RowBounds;
import org.alfresco.repo.domain.audit.AuditApplicationEntity; import org.mybatis.spring.SqlSessionTemplate;
import org.alfresco.repo.domain.audit.AuditDeleteParameters; import org.springframework.dao.ConcurrencyFailureException;
import org.alfresco.repo.domain.audit.AuditEntryEntity;
import org.alfresco.repo.domain.audit.AuditModelEntity; import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
import org.alfresco.repo.domain.audit.AuditQueryParameters; import org.alfresco.repo.domain.audit.AuditApplicationEntity;
import org.alfresco.repo.domain.audit.AuditQueryResult; import org.alfresco.repo.domain.audit.AuditDeleteParameters;
import org.alfresco.repo.domain.propval.PropertyValueDAO.PropertyFinderCallback; import org.alfresco.repo.domain.audit.AuditEntryEntity;
import org.alfresco.util.Pair; import org.alfresco.repo.domain.audit.AuditModelEntity;
import org.apache.ibatis.session.RowBounds; import org.alfresco.repo.domain.audit.AuditQueryParameters;
import org.mybatis.spring.SqlSessionTemplate; import org.alfresco.repo.domain.audit.AuditQueryResult;
import org.springframework.dao.ConcurrencyFailureException; 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. /**
* * iBatis-specific implementation of the DAO for <b>alf_audit_XXX</b> tables.
* @author Derek Hulley *
* @since 3.2 * @author Derek Hulley
*/ * @since 3.2
public class AuditDAOImpl extends AbstractAuditDAOImpl */
{ 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_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 SELECT_APPLICATION_BY_ID = "alfresco.audit.select_AuditApplicationById";
private static final String INSERT_APPLICATION = "alfresco.audit.insert.insert_AuditApplication"; private static final String SELECT_APPLICATION_BY_NAME_ID = "alfresco.audit.select_AuditApplicationByNameId";
private static final String UPDATE_APPLICATION = "alfresco.audit.update_AuditApplication"; 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 DELETE_ENTRIES = "alfresco.audit.delete_AuditEntries";
private static final String INSERT_ENTRY = "alfresco.audit.insert.insert_AuditEntry"; private static final String DELETE_ENTRIES_BY_ID = "alfresco.audit.delete_AuditEntriesById";
private static final String SELECT_MINMAX_ENTRY_FOR_APP = "alfresco.audit.select_MinMaxAuditEntryId"; private static final String INSERT_ENTRY = "alfresco.audit.insert.insert_AuditEntry";
private static final String SELECT_COUNT_ENTRIES_FOR_APP = "alfresco.audit.select_CountAuditEntryId"; private static final String SELECT_MINMAX_ENTRY_FOR_APP = "alfresco.audit.select_MinMaxAuditEntryId";
private static final String SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES = "select_CountAuditEntryIdWithWhereClause"; 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"; @SuppressWarnings("unused")
private static final String SELECT_ENTRIES_WITH_VALUES = "alfresco.audit.select_AuditEntriesWithValues"; private static final String SELECT_ENTRIES_SIMPLE = "alfresco.audit.select_AuditEntriesSimple";
private static final String SELECT_ENTRIES_WITHOUT_VALUES = "alfresco.audit.select_AuditEntriesWithoutValues"; 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;
private SqlSessionTemplate template;
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
{ public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
this.template = sqlSessionTemplate; {
} this.template = sqlSessionTemplate;
}
@Override
protected AuditModelEntity getAuditModelByCrc(long crc) @Override
{ protected AuditModelEntity getAuditModelByCrc(long crc)
AuditModelEntity entity = new AuditModelEntity(); {
entity.setContentCrc(crc); AuditModelEntity entity = new AuditModelEntity();
entity = template.selectOne( entity.setContentCrc(crc);
SELECT_MODEL_BY_CRC, entity = template.selectOne(
entity); SELECT_MODEL_BY_CRC,
// Done entity);
return entity; // Done
} return entity;
}
@Override
protected AuditModelEntity createAuditModel(Long contentDataId, long crc) @Override
{ protected AuditModelEntity createAuditModel(Long contentDataId, long crc)
AuditModelEntity entity = new AuditModelEntity(); {
entity.setContentDataId(contentDataId); AuditModelEntity entity = new AuditModelEntity();
entity.setContentCrc(crc); entity.setContentDataId(contentDataId);
template.insert(INSERT_MODEL, entity); entity.setContentCrc(crc);
return entity; template.insert(INSERT_MODEL, entity);
} return entity;
}
@Override
protected AuditApplicationEntity getAuditApplicationById(Long id) @Override
{ protected AuditApplicationEntity getAuditApplicationById(Long id)
Map<String, Object> params = new HashMap<String, Object>(11); {
params.put("id", id); Map<String, Object> params = new HashMap<String, Object>(11);
AuditApplicationEntity entity = template.selectOne( params.put("id", id);
SELECT_APPLICATION_BY_ID, AuditApplicationEntity entity = template.selectOne(
params); SELECT_APPLICATION_BY_ID,
// Done params);
if (logger.isDebugEnabled()) // Done
{ if (logger.isDebugEnabled())
logger.debug("Searched for audit application ID " + id + " and found: " + entity); {
} logger.debug("Searched for audit application ID " + id + " and found: " + entity);
return entity; }
} return entity;
}
@Override
protected AuditApplicationEntity getAuditApplicationByName(String appName) @Override
{ protected AuditApplicationEntity getAuditApplicationByName(String appName)
// Resolve the name as a property ID {
Pair<Long, Serializable> appNamePair = propertyValueDAO.getPropertyValue(appName); // Resolve the name as a property ID
if (appNamePair == null) Pair<Long, Serializable> appNamePair = propertyValueDAO.getPropertyValue(appName);
{ if (appNamePair == null)
// There will be no results {
return null; // There will be no results
} return null;
}
Map<String, Object> params = new HashMap<String, Object>(11);
params.put("id", appNamePair.getFirst()); Map<String, Object> params = new HashMap<String, Object>(11);
AuditApplicationEntity entity = template.selectOne( params.put("id", appNamePair.getFirst());
SELECT_APPLICATION_BY_NAME_ID, AuditApplicationEntity entity = template.selectOne(
params); SELECT_APPLICATION_BY_NAME_ID,
// Done params);
if (logger.isDebugEnabled()) // Done
{ if (logger.isDebugEnabled())
logger.debug("Searched for audit application '" + appName + "' and found: " + entity); {
} logger.debug("Searched for audit application '" + appName + "' and found: " + entity);
return entity; }
} return entity;
}
@Override
protected AuditApplicationEntity createAuditApplication(Long appNameId, Long modelId, Long disabledPathsId) @Override
{ protected AuditApplicationEntity createAuditApplication(Long appNameId, Long modelId, Long disabledPathsId)
AuditApplicationEntity entity = new AuditApplicationEntity(); {
entity.setVersion((short)0); AuditApplicationEntity entity = new AuditApplicationEntity();
entity.setApplicationNameId(appNameId); entity.setVersion((short) 0);
entity.setAuditModelId(modelId); entity.setApplicationNameId(appNameId);
entity.setDisabledPathsId(disabledPathsId); entity.setAuditModelId(modelId);
template.insert(INSERT_APPLICATION, entity); entity.setDisabledPathsId(disabledPathsId);
return entity; template.insert(INSERT_APPLICATION, entity);
} return entity;
}
@Override
protected AuditApplicationEntity updateAuditApplication(AuditApplicationEntity entity) @Override
{ protected AuditApplicationEntity updateAuditApplication(AuditApplicationEntity entity)
AuditApplicationEntity updateEntity = new AuditApplicationEntity(); {
updateEntity.setId(entity.getId()); AuditApplicationEntity updateEntity = new AuditApplicationEntity();
updateEntity.setVersion(entity.getVersion()); updateEntity.setId(entity.getId());
updateEntity.incrementVersion(); updateEntity.setVersion(entity.getVersion());
updateEntity.setApplicationNameId(entity.getApplicationNameId()); updateEntity.incrementVersion();
updateEntity.setAuditModelId(entity.getAuditModelId()); updateEntity.setApplicationNameId(entity.getApplicationNameId());
updateEntity.setDisabledPathsId(entity.getDisabledPathsId()); updateEntity.setAuditModelId(entity.getAuditModelId());
updateEntity.setDisabledPathsId(entity.getDisabledPathsId());
int updated = template.update(UPDATE_APPLICATION, updateEntity);
if (updated != 1) 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); // unexpected number of rows affected
} throw new ConcurrencyFailureException("Incorrect number of rows affected for updateAuditApplication: " + updateEntity + ": expected 1, actual " + updated);
}
// Done
return updateEntity; // Done
} return updateEntity;
}
public int deleteAuditEntries(Long applicationId, Long from, Long to)
{ public int deleteAuditEntries(Long applicationId, Long from, Long to)
AuditDeleteParameters params = new AuditDeleteParameters(); {
params.setAuditApplicationId(applicationId); AuditDeleteParameters params = new AuditDeleteParameters();
params.setAuditFromTime(from); params.setAuditApplicationId(applicationId);
params.setAuditToTime(to); params.setAuditFromTime(from);
return template.delete(DELETE_ENTRIES, params); params.setAuditToTime(to);
} return template.delete(DELETE_ENTRIES, params);
}
public int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId)
{ public int deleteAuditEntriesByIdRange(Long applicationId, Long fromId, Long toId)
AuditDeleteParameters params = new AuditDeleteParameters(); {
params.setAuditApplicationId(applicationId); AuditDeleteParameters params = new AuditDeleteParameters();
params.setAuditFromId(fromId); params.setAuditApplicationId(applicationId);
params.setAuditToId(toId); params.setAuditFromId(fromId);
return template.delete(DELETE_ENTRIES, params); params.setAuditToId(toId);
} return template.delete(DELETE_ENTRIES, params);
}
@Override
protected int deleteAuditEntriesImpl(List<Long> auditEntryIds) @Override
{ protected int deleteAuditEntriesImpl(List<Long> auditEntryIds)
AuditDeleteParameters params = new AuditDeleteParameters(); {
params.setAuditEntryIds(auditEntryIds); AuditDeleteParameters params = new AuditDeleteParameters();
return template.delete(DELETE_ENTRIES_BY_ID, params); params.setAuditEntryIds(auditEntryIds);
} return template.delete(DELETE_ENTRIES_BY_ID, params);
}
@Override
protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId) @Override
{ protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId)
AuditEntryEntity entity = new AuditEntryEntity(); {
entity.setAuditApplicationId(applicationId); AuditEntryEntity entity = new AuditEntryEntity();
entity.setAuditTime(time); entity.setAuditApplicationId(applicationId);
entity.setAuditUserId(usernameId); entity.setAuditTime(time);
entity.setAuditValuesId(valuesId); entity.setAuditUserId(usernameId);
template.insert(INSERT_ENTRY, entity); entity.setAuditValuesId(valuesId);
return entity; template.insert(INSERT_ENTRY, entity);
} return entity;
}
public HashMap<String, Long> getAuditMinMaxByApp(long appId, List<String> extremes)
{ 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)); // Build parameters to be used in the query. Filter the duplicates when inserting into map
params.put("auditAppId", appId); 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);
HashMap<String, Long> result = template.selectOne(SELECT_MINMAX_ENTRY_FOR_APP, params);
return result;
} return result;
}
@Override
public int getAuditEntriesCountByApp(long applicationId) @Override
{ public int getAuditEntriesCountByApp(long applicationId)
Map<String, Object> params = new HashMap<>(); {
params.put("auditAppId", applicationId); Map<String, Object> params = new HashMap<>();
params.put("auditAppId", applicationId);
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP, params);
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP, params);
return result;
} return result;
}
@Override
public int getAuditEntriesCountByAppAndProperties(org.alfresco.service.cmr.audit.AuditQueryParameters parameters) @Override
{ public int getAuditEntriesCountByAppAndProperties(String applicationName, org.alfresco.service.cmr.audit.AuditQueryParameters parameters)
AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters); {
AuditQueryParameters dbParameters = convertFromRestAuditQueryParameters(parameters);
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES, dbParameters);
int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP_WITH_PROPERTIES, dbParameters);
return result;
} return result;
}
@SuppressWarnings("unchecked")
@Override @SuppressWarnings("unchecked")
protected void findAuditEntries( @Override
final AuditQueryRowHandler rowHandler, protected void findAuditEntries(
int maxResults, final AuditQueryRowHandler rowHandler,
org.alfresco.service.cmr.audit.AuditQueryParameters restParameters) int maxResults,
{ org.alfresco.service.cmr.audit.AuditQueryParameters restParameters)
AuditQueryParameters params = convertFromRestAuditQueryParameters(restParameters); {
if (params==null) AuditQueryParameters params = convertFromRestAuditQueryParameters(restParameters);
{ if (params == null)
return; {
} return;
}
if (maxResults > 0)
{ if (maxResults > 0)
// Query without getting the values. We gather all the results and batch-fetch the audited {
// values afterwards. // Query without getting the values. We gather all the results and batch-fetch the audited
final Map<Long, AuditQueryResult> resultsByValueId = new HashMap<Long, AuditQueryResult>(173); // values afterwards.
PropertyFinderCallback propertyFinderCallback = new PropertyFinderCallback() final Map<Long, AuditQueryResult> resultsByValueId = new HashMap<Long, AuditQueryResult>(173);
{ PropertyFinderCallback propertyFinderCallback = new PropertyFinderCallback() {
public void handleProperty(Long id, Serializable value) public void handleProperty(Long id, Serializable value)
{ {
// get the row // get the row
AuditQueryResult row = resultsByValueId.get(id); AuditQueryResult row = resultsByValueId.get(id);
try try
{ {
row.setAuditValue((Map<String, Serializable>) value); row.setAuditValue((Map<String, Serializable>) value);
} }
catch (ClassCastException e) catch (ClassCastException e)
{ {
// The handler will deal with the entry // The handler will deal with the entry
} }
} }
}; };
List<AuditQueryResult> rows = template.selectList(SELECT_ENTRIES_WITHOUT_VALUES, params, new RowBounds(0, maxResults)); List<AuditQueryResult> rows = template.selectList(SELECT_ENTRIES_WITHOUT_VALUES, params, new RowBounds(0, maxResults));
for (AuditQueryResult row : rows) for (AuditQueryResult row : rows)
{ {
resultsByValueId.put(row.getAuditValuesId(), row); resultsByValueId.put(row.getAuditValuesId(), row);
if (resultsByValueId.size() >= 100) if (resultsByValueId.size() >= 100)
{ {
// Fetch values for the results. The treemap is ordered. // Fetch values for the results. The treemap is ordered.
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet()); List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback); propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
// Clear and continue // Clear and continue
resultsByValueId.clear(); resultsByValueId.clear();
} }
} }
// Process any remaining results // Process any remaining results
if (resultsByValueId.size() > 0) if (resultsByValueId.size() > 0)
{ {
// Fetch values for the results. The treemap is ordered. // Fetch values for the results. The treemap is ordered.
List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet()); List<Long> valueIds = new ArrayList<Long>(resultsByValueId.keySet());
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback); propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
} }
// Now pass the filled-out results to the row handler (order-preserved) // Now pass the filled-out results to the row handler (order-preserved)
for (AuditQueryResult row : rows) for (AuditQueryResult row : rows)
{ {
rowHandler.processResult(row); rowHandler.processResult(row);
} }
} }
else else
{ {
throw new IllegalArgumentException("maxResults must be greater than 0"); throw new IllegalArgumentException("maxResults must be greater than 0");
} }
} }
} }

View File

@@ -1,173 +1,158 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.domain.propval; package org.alfresco.repo.domain.propval;
import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.CrcHelper;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
/** /**
* Entity bean for <b>alf_prop_string_value</b> table. * Entity bean for <b>alf_prop_string_value</b> table.
* *
* @author Derek Hulley * @author Derek Hulley
* @since 3.2 * @since 3.2
*/ */
public class PropertyStringValueEntity public class PropertyStringValueEntity
{ {
public static final String EMPTY_STRING = ""; public static final String EMPTY_STRING = "";
public static final String EMPTY_STRING_REPLACEMENT = ".empty"; public static final String EMPTY_STRING_REPLACEMENT = ".empty";
private Long id; private Long id;
private String stringValue; private String stringValue;
private String stringEndLower; private String stringEndLower;
private Long stringCrc; private Long stringCrc;
private String stringLower;
public PropertyStringValueEntity()
public PropertyStringValueEntity() {}
{
} @Override
public int hashCode()
@Override {
public int hashCode() return (stringValue == null ? 0 : stringValue.hashCode());
{ }
return (stringValue == null ? 0 : stringValue.hashCode());
} @Override
public boolean equals(Object obj)
@Override {
public boolean equals(Object obj) if (this == obj)
{ {
if (this == obj) return true;
{ }
return true; else if (obj != null && obj instanceof PropertyStringValueEntity)
} {
else if (obj != null && obj instanceof PropertyStringValueEntity) PropertyStringValueEntity that = (PropertyStringValueEntity) obj;
{ return EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue);
PropertyStringValueEntity that = (PropertyStringValueEntity) obj; }
return EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue); else
} {
else return false;
{ }
return false; }
}
} @Override
public String toString()
@Override {
public String toString() StringBuilder sb = new StringBuilder(512);
{ sb.append("PropertyStringValueEntity")
StringBuilder sb = new StringBuilder(512); .append("[ ID=").append(id)
sb.append("PropertyStringValueEntity") .append(", stringValue=").append(stringValue)
.append("[ ID=").append(id) .append("]");
.append(", stringValue=").append(stringValue) return sb.toString();
.append("]"); }
return sb.toString();
} public Pair<Long, String> getEntityPair()
{
public Pair<Long, String> getEntityPair() if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT))
{ {
if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT)) return new Pair<Long, String>(id, PropertyStringValueEntity.EMPTY_STRING);
{ }
return new Pair<Long, String>(id, PropertyStringValueEntity.EMPTY_STRING); else
} {
else return new Pair<Long, String>(id, stringValue);
{ }
return new Pair<Long, String>(id, stringValue); }
}
} /**
* Set the string and string-end values
/** */
* Set the string and string-end values public void setValue(String value)
*/ {
public void setValue(String value) if (value == null)
{ {
if (value == null) throw new IllegalArgumentException("Null strings cannot be persisted");
{ }
throw new IllegalArgumentException("Null strings cannot be persisted"); if (value != null && value.equals(PropertyStringValueEntity.EMPTY_STRING))
} {
if (value != null && value.equals(PropertyStringValueEntity.EMPTY_STRING)) // Oracle: We can't insert empty strings into the column.
{ value = PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT;
// 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
stringValue = value; Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true);
// Calculate the crc value from the original value stringEndLower = crcPair.getFirst();
Pair<String, Long> crcPair = CrcHelper.getStringCrcPair(value, 16, false, true); stringCrc = crcPair.getSecond();
stringEndLower = crcPair.getFirst(); }
stringCrc = crcPair.getSecond();
// Calculate the crc value with case-insensitive public Long getId()
Pair<String, Long> crcPairWithCaseInSensitive = CrcHelper.getStringCrcPair(value, 16, false, false); {
stringLower = crcPairWithCaseInSensitive.getFirst(); return id;
} }
public Long getId() public void setId(Long id)
{ {
return id; this.id = id;
} }
public void setId(Long id) public String getStringValue()
{ {
this.id = id; return stringValue;
} }
public String getStringValue() public void setStringValue(String stringValue)
{ {
return stringValue; this.stringValue = stringValue;
} }
public void setStringValue(String stringValue) public String getStringEndLower()
{ {
this.stringValue = stringValue; return stringEndLower;
} }
public String getStringEndLower() public void setStringEndLower(String stringEndLower)
{ {
return stringEndLower; this.stringEndLower = stringEndLower;
} }
public void setStringEndLower(String stringEndLower) public Long getStringCrc()
{ {
this.stringEndLower = stringEndLower; return stringCrc;
} }
public Long getStringCrc() public void setStringCrc(Long stringCrc)
{ {
return stringCrc; this.stringCrc = stringCrc;
} }
}
public void setStringCrc(Long stringCrc)
{
this.stringCrc = stringCrc;
}
public String getStringLower()
{
return stringLower;
}
public void setStringLower(String stringLower)
{
this.stringLower = stringLower;
}
}

View File

@@ -1,28 +1,28 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.i18n; package org.alfresco.repo.i18n;
import java.io.BufferedReader; import java.io.BufferedReader;
@@ -204,13 +204,11 @@ public class MessageServiceImpl implements MessageService
{ {
if (! tenantResourceBundleBaseNames.contains(resBundlePath)) if (! tenantResourceBundleBaseNames.contains(resBundlePath))
{ {
tenantResourceBundleBaseNames.add(resBundlePath); tenantResourceBundleBaseNames.add(resBundlePath);
putResourceBundleBaseNames(tenantDomain, tenantResourceBundleBaseNames); reloadResourceBundles(tenantResourceBundleBaseNames);
} }
logger.info("Registered message bundle '" + resBundlePath + "'"); logger.info("Registered message bundle '" + resBundlePath + "'");
clearLoadedResourceBundles(tenantDomain); // force re-load of message cache
} }
finally finally
{ {
@@ -288,61 +286,64 @@ public class MessageServiceImpl implements MessageService
Map<Locale, Set<String>> loadedResourceBundlesForAllLocales; Map<Locale, Set<String>> loadedResourceBundlesForAllLocales;
Map<Locale, Map<String, String>> cachedMessagesForAllLocales; Map<Locale, Map<String, String>> cachedMessagesForAllLocales;
Set<String> resourceBundleBaseNamesForAllLocales; Set<String> resourceBundleBaseNamesForAllLocales;
String tenantDomain = getTenantDomain(); String tenantDomain = getTenantDomain();
LockHelper.tryLock(readLock, tryLockTimeout, "getting loaded resource bundles, messages and base names in 'MessageServiceImpl.unregisterResourceBundle()'"); LockHelper.tryLock(readLock, tryLockTimeout,
"getting loaded resource bundles, messages and base names in 'MessageServiceImpl.unregisterResourceBundle()'");
try try
{ {
// all locales // all locales
loadedResourceBundlesForAllLocales = getLoadedResourceBundles(tenantDomain, false); loadedResourceBundlesForAllLocales = getLoadedResourceBundles(tenantDomain, false);
cachedMessagesForAllLocales = getMessages(tenantDomain, false); cachedMessagesForAllLocales = getMessages(tenantDomain, false);
resourceBundleBaseNamesForAllLocales = getResourceBundleBaseNames(tenantDomain, false, true); resourceBundleBaseNamesForAllLocales = getResourceBundleBaseNames(tenantDomain, false, true);
} }
finally finally
{ {
readLock.unlock(); readLock.unlock();
} }
LockHelper.tryLock(writeLock, tryLockTimeout, "removing resource bundle by path in 'MessageServiceImpl.unregisterResourceBundle()'"); LockHelper.tryLock(writeLock, tryLockTimeout,
"removing resource bundle by path in 'MessageServiceImpl.unregisterResourceBundle()'");
try try
{ {
// unload resource bundles for each locale (by tenant, if applicable) // unload resource bundles for each locale (by tenant, if applicable)
if ((loadedResourceBundlesForAllLocales != null) && (cachedMessagesForAllLocales != null)) if ((loadedResourceBundlesForAllLocales != null) && (cachedMessagesForAllLocales != null))
{ {
Iterator<Locale> itr = loadedResourceBundlesForAllLocales.keySet().iterator(); Iterator<Locale> itr = loadedResourceBundlesForAllLocales.keySet().iterator();
while (itr.hasNext()) while (itr.hasNext())
{ {
Locale locale = itr.next(); Locale locale = itr.next();
Set<String> loadedBundles = loadedResourceBundlesForAllLocales.get(locale); Set<String> loadedBundles = loadedResourceBundlesForAllLocales.get(locale);
Map<String, String> props = cachedMessagesForAllLocales.get(locale); Map<String, String> props = cachedMessagesForAllLocales.get(locale);
if ((loadedBundles != null) && (props != null)) if ((loadedBundles != null) && (props != null))
{ {
if (loadedBundles.contains(resBundlePath)) if (loadedBundles.contains(resBundlePath))
{ {
ResourceBundle resourcebundle = null; ResourceBundle resourcebundle = null;
int idx1 = resBundlePath.indexOf(StoreRef.URI_FILLER); int idx1 = resBundlePath.indexOf(StoreRef.URI_FILLER);
if (idx1 != -1) if (idx1 != -1)
{ {
// load from repository // load from repository
int idx2 = resBundlePath.indexOf("/", idx1+3); int idx2 = resBundlePath.indexOf("/", idx1 + 3);
String store = resBundlePath.substring(0, idx2); String store = resBundlePath.substring(0, idx2);
String path = resBundlePath.substring(idx2); String path = resBundlePath.substring(idx2);
StoreRef storeRef = tenantService.getName(new StoreRef(store)); StoreRef storeRef = tenantService.getName(new StoreRef(store));
try try
{ {
resourcebundle = getRepoResourceBundle(storeRef, path, locale); resourcebundle = getRepoResourceBundle(storeRef, path, locale);
} }
catch (IOException ioe) catch (IOException ioe)
{ {
throw new AlfrescoRuntimeException("Failed to read message resource bundle from repository " + resBundlePath + " : " + ioe); throw new AlfrescoRuntimeException("Failed to read message resource bundle from repository "
+ resBundlePath + " : " + ioe);
} }
} }
else else
@@ -350,7 +351,7 @@ public class MessageServiceImpl implements MessageService
// load from classpath // load from classpath
resourcebundle = ResourceBundle.getBundle(resBundlePath, locale); resourcebundle = ResourceBundle.getBundle(resBundlePath, locale);
} }
if (resourcebundle != null) if (resourcebundle != null)
{ {
// unload from the cached messages // unload from the cached messages
@@ -361,21 +362,20 @@ public class MessageServiceImpl implements MessageService
props.remove(key); props.remove(key);
} }
} }
loadedBundles.remove(resBundlePath); loadedBundles.remove(resBundlePath);
} }
} }
} }
} }
// unregister resource bundle // unregister resource bundle
if (resourceBundleBaseNamesForAllLocales != null) if (resourceBundleBaseNamesForAllLocales != null)
{ {
resourceBundleBaseNamesForAllLocales.remove(resBundlePath); resourceBundleBaseNamesForAllLocales.remove(resBundlePath);
reloadResourceBundles(resourceBundleBaseNamesForAllLocales);
logger.info("Unregistered message bundle '" + resBundlePath + "'"); logger.info("Unregistered message bundle '" + resBundlePath + "'");
} }
clearLoadedResourceBundles(tenantDomain); // force re-load of message cache
} }
finally finally
{ {
@@ -383,6 +383,14 @@ public class MessageServiceImpl implements MessageService
} }
} }
private void reloadResourceBundles(Set<String> newResourceBundles)
{
logger.debug("Reloading message bundles ...");
String tenantDomain = getTenantDomain();
putResourceBundleBaseNames(tenantDomain, newResourceBundles);
clearLoadedResourceBundles(tenantDomain); // force re-load of message cache
}
/** /**
* Get the messages for a locale. * Get the messages for a locale.
* <p> * <p>
@@ -465,7 +473,7 @@ public class MessageServiceImpl implements MessageService
Set<String> resBundleBaseNames = getResourceBundleBaseNames(tenantDomain, true, false); Set<String> resBundleBaseNames = getResourceBundleBaseNames(tenantDomain, true, false);
int count = 0; int count = 0;
// load resource bundles for given locale (by tenant, if applicable) // load resource bundles for given locale (by tenant, if applicable)
for (String resBundlePath : resBundleBaseNames) for (String resBundlePath : resBundleBaseNames)
{ {
@@ -474,24 +482,25 @@ public class MessageServiceImpl implements MessageService
ResourceBundle resourcebundle = null; ResourceBundle resourcebundle = null;
int idx1 = resBundlePath.indexOf(StoreRef.URI_FILLER); int idx1 = resBundlePath.indexOf(StoreRef.URI_FILLER);
if (idx1 != -1) if (idx1 != -1)
{ {
// load from repository // load from repository
int idx2 = resBundlePath.indexOf("/", idx1+3); int idx2 = resBundlePath.indexOf("/", idx1 + 3);
String store = resBundlePath.substring(0, idx2); String store = resBundlePath.substring(0, idx2);
String path = resBundlePath.substring(idx2); String path = resBundlePath.substring(idx2);
StoreRef storeRef = tenantService.getName(new StoreRef(store)); StoreRef storeRef = tenantService.getName(new StoreRef(store));
try try
{ {
resourcebundle = getRepoResourceBundle(storeRef, path, locale); resourcebundle = getRepoResourceBundle(storeRef, path, locale);
} }
catch (IOException ioe) catch (IOException ioe)
{ {
throw new AlfrescoRuntimeException("Failed to read message resource bundle from repository " + resBundlePath + " : " + ioe); throw new AlfrescoRuntimeException(
"Failed to read message resource bundle from repository " + resBundlePath + " : " + ioe);
} }
} }
else else
@@ -508,13 +517,13 @@ public class MessageServiceImpl implements MessageService
String key = enumKeys.nextElement(); String key = enumKeys.nextElement();
props.put(key, resourcebundle.getString(key)); props.put(key, resourcebundle.getString(key));
} }
loadedBundles.add(resBundlePath); loadedBundles.add(resBundlePath);
count++; count++;
} }
} }
} }
logger.info("Message bundles (x " + count + ") loaded for locale " + locale); logger.info("Message bundles (x " + count + ") loaded for locale " + locale);
} }
finally finally

View File

@@ -0,0 +1,41 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.node.sizedetails;
import java.util.Optional;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
import org.alfresco.service.cmr.repository.NodeRef;
public interface NodeSizeDetailsService
{
void invokeSizeDetailsExecutor(NodeRef nodeRef, String jobId);
void putSizeDetails(String id, NodeSizeDetails nodeSizeDetails);
Optional<NodeSizeDetails> getSizeDetails(String id);
}

View File

@@ -0,0 +1,400 @@
/*
* #%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.node.sizedetails;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails.STATUS;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
/**
* NodeSizeDetailsServiceImpl Executing Alfresco FTS Query to find size details of Folder Node
*/
public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, InitializingBean
{
private static final Logger LOG = LoggerFactory.getLogger(NodeSizeDetailsServiceImpl.class);
private static final String FIELD_FACET = "content.size";
private static final String FACET_QUERY = "{!afts}content.size:[0 TO " + Integer.MAX_VALUE + "]";
private SearchService searchService;
private SimpleCache<Serializable, NodeSizeDetails> simpleCache;
private TransactionService transactionService;
private ThreadPoolExecutor threadPoolExecutor;
private int defaultItems;
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
@Override
public Optional<NodeSizeDetails> getSizeDetails(String id)
{
NodeSizeDetails details = simpleCache.get(id);
return Optional.ofNullable(details)
.or(() -> {
LOG.error("No Size details found for ID: " + id);
return Optional.empty();
});
}
public void setSimpleCache(SimpleCache<Serializable, NodeSizeDetails> simpleCache)
{
this.simpleCache = simpleCache;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor)
{
this.threadPoolExecutor = threadPoolExecutor;
}
public void setDefaultItems(int defaultItems)
{
this.defaultItems = defaultItems;
}
@Override
public void invokeSizeDetailsExecutor(NodeRef nodeRef, String jobId)
{
try
{
executeSizeCalculation(nodeRef, jobId);
}
catch (Exception e)
{
LOG.error("Exception occurred while executing invokeSizeDetailsExecutor method ", e);
}
}
@Override
public void putSizeDetails(String id, NodeSizeDetails nodeSizeDetails)
{
simpleCache.put(id, nodeSizeDetails);
}
private void executeSizeCalculation(NodeRef nodeRef, String jobId)
{
String authenticatedUserName = AuthenticationUtil.getFullyAuthenticatedUser();
RetryingTransactionCallback<NodeSizeDetails> executionCallback = () -> {
try
{
return calculateTotalSizeFromFacet(nodeRef, jobId);
}
catch (Exception ex)
{
LOG.error("Exception occurred in executeSizeCalculation:RetryingTransactionCallback ", ex);
throw ex;
}
};
threadPoolExecutor.execute(() -> {
NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), jobId, STATUS.IN_PROGRESS);
putSizeDetails(nodeRef.getId(), nodeSizeDetails);
try
{
nodeSizeDetails = AuthenticationUtil.runAs(() -> transactionService.getRetryingTransactionHelper()
.doInTransaction(executionCallback, true), authenticatedUserName);
}
catch (Exception e)
{
LOG.error("Exception occurred in executeSizeCalculation", e);
nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), 0L, jobId, STATUS.FAILED);
}
finally
{
putSizeDetails(nodeRef.getId(), nodeSizeDetails);
}
});
}
private NodeSizeDetails calculateTotalSizeFromFacet(NodeRef nodeRef, String jobId)
{
long totalSizeFromFacet = 0;
int skipCount = 0;
int totalItems = defaultItems;
boolean isCalculationCompleted = false;
try
{
ResultSet results = facetQuery(nodeRef);
int resultsSize = results.getFieldFacet(FIELD_FACET)
.size();
while (!isCalculationCompleted)
{
List<Pair<String, Integer>> facetPairs = results.getFieldFacet(FIELD_FACET)
.subList(skipCount, Math.min(totalItems, resultsSize));
totalSizeFromFacet += facetPairs.parallelStream()
.mapToLong(pair -> Long.parseLong(pair.getFirst()) * pair.getSecond())
.sum();
if (resultsSize <= totalItems || resultsSize <= defaultItems)
{
isCalculationCompleted = true;
}
else
{
skipCount += defaultItems;
resultsSize -= totalItems;
totalItems += Math.min(resultsSize, defaultItems);
}
}
Date calculationDate = new Date(System.currentTimeMillis());
NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), totalSizeFromFacet, calculationDate,
results.getNodeRefs()
.size(),
STATUS.COMPLETED, jobId);
return nodeSizeDetails;
}
catch (Exception e)
{
LOG.error("Exception occurred while calculating total size from facet", e);
throw e;
}
}
private ResultSet facetQuery(NodeRef nodeRef)
{
try
{
SearchParameters searchParameters = createSearchParameters(nodeRef);
ResultSet resultsWithoutFacet = searchService.query(searchParameters);
if (LOG.isDebugEnabled())
{
LOG.debug(" After Executing facet query, no. of records found " + resultsWithoutFacet.getNumberFound());
}
searchParameters.addFacetQuery(FACET_QUERY);
FieldFacet fieldFacet = new FieldFacet(FIELD_FACET);
fieldFacet.setLimitOrNull((int) resultsWithoutFacet.getNumberFound());
searchParameters.addFieldFacet(fieldFacet);
resultsWithoutFacet.close();
return searchService.query(searchParameters);
}
catch (Exception e)
{
LOG.error("Exception occurred while executing facetQuery ", e);
throw e;
}
}
private SearchParameters createSearchParameters(NodeRef nodeRef)
{
SearchParameters searchParameters = new SearchParameters();
searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
searchParameters.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
searchParameters.setQuery("ANCESTOR:\"" + nodeRef + "\" AND TYPE:\"cm:content\"");
searchParameters.setTrackTotalHits(-1);
return searchParameters;
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("searchService", this.searchService);
ParameterCheck.mandatory("simpleCache", this.simpleCache);
ParameterCheck.mandatory("transactionService", this.transactionService);
ParameterCheck.mandatory("threadPoolExecutor", this.threadPoolExecutor);
}
/**
* POJO class to hold node size details.
*/
public static class NodeSizeDetails implements Serializable
{
private static final long serialVersionUID = 1L;
private String id;
private Long sizeInBytes;
private Date calculatedAt;
private Integer numberOfFiles;
private String jobId;
private STATUS status;
public NodeSizeDetails()
{}
public NodeSizeDetails(String jobId)
{
this.jobId = jobId;
}
public NodeSizeDetails(String id, STATUS status)
{
this.id = id;
this.status = status;
}
public NodeSizeDetails(String id, String jobId, STATUS status)
{
this.id = id;
this.jobId = jobId;
this.status = status;
}
public NodeSizeDetails(String id, Long sizeInBytes, String jobId, STATUS status)
{
this.id = id;
this.sizeInBytes = sizeInBytes;
this.jobId = jobId;
this.status = status;
}
public NodeSizeDetails(String id, Long sizeInBytes, Date calculatedAt, Integer numberOfFiles,
STATUS currentStatus, String jobId)
{
this.id = id;
this.sizeInBytes = sizeInBytes;
this.calculatedAt = calculatedAt;
this.numberOfFiles = numberOfFiles;
this.status = currentStatus;
this.jobId = jobId;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Long getSizeInBytes()
{
return sizeInBytes;
}
public void setSizeInBytes(Long sizeInBytes)
{
this.sizeInBytes = sizeInBytes;
}
public Date getCalculatedAt()
{
return calculatedAt;
}
public void setCalculatedAt(Date calculatedAt)
{
this.calculatedAt = calculatedAt;
}
public Integer getNumberOfFiles()
{
return numberOfFiles;
}
public void setNumberOfFiles(Integer numberOfFiles)
{
this.numberOfFiles = numberOfFiles;
}
public String getJobId()
{
return jobId;
}
public void setJobId(String jobId)
{
this.jobId = jobId;
}
public STATUS getStatus()
{
return status;
}
public void setStatus(STATUS status)
{
this.status = status;
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
NodeSizeDetails that = (NodeSizeDetails) o;
return Objects.equals(id, that.id) && Objects.equals(sizeInBytes, that.sizeInBytes) && Objects.equals(
calculatedAt, that.calculatedAt) && Objects.equals(numberOfFiles, that.numberOfFiles)
&& Objects.equals(jobId, that.jobId) && status == that.status;
}
@Override
public int hashCode()
{
return Objects.hash(id, sizeInBytes, calculatedAt, numberOfFiles, jobId, status);
}
@Override
public String toString()
{
return "NodeSizeDetails{" + "id='" + id + '\'' + ", sizeInBytes=" + sizeInBytes + ", calculatedAt="
+ calculatedAt + ", numberOfFiles=" + numberOfFiles + ", jobId='" + jobId + '\'' + ", status="
+ status + '}';
}
public enum STATUS
{
NOT_INITIATED, PENDING, IN_PROGRESS, COMPLETED, FAILED
}
}
}

View File

@@ -1,266 +1,298 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2024 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.service.cmr.audit; package org.alfresco.service.cmr.audit;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* The public API by which applications can query the audit logs and enable or disable auditing. * The public API by which applications can query the audit logs and enable or disable auditing.
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
public interface AuditService public interface AuditService
{ {
/** /**
* @return Returns <tt>true</tt> if auditing is globally enabled * @return Returns <tt>true</tt> if auditing is globally enabled
* *
* @since 3.4 * @since 3.4
*/ */
boolean isAuditEnabled(); boolean isAuditEnabled();
/** /**
* Enable or disable the global auditing state * Enable or disable the global auditing state
* *
* @param enable <tt>true</tt> to enable auditing globally or <tt>false</tt> to disable * @param enable
* * <tt>true</tt> to enable auditing globally or <tt>false</tt> to disable
* @since 3.4 *
*/ * @since 3.4
void setAuditEnabled(boolean enable); */
void setAuditEnabled(boolean enable);
/**
* Helper bean to carry information about an audit application. /**
* * Helper bean to carry information about an audit application.
* @author Derek Hulley *
* @since 3.4 * @author Derek Hulley
*/ * @since 3.4
public static class AuditApplication */
{ public static class AuditApplication
private final String name; {
private final String key; private final String name;
private final boolean enabled; private final String key;
/** private final boolean enabled;
* Constructor for final variables
*/ /**
public AuditApplication(String name, String key, boolean enabled) * Constructor for final variables
{ */
this.name = name; public AuditApplication(String name, String key, boolean enabled)
this.key = key; {
this.enabled = enabled; this.name = name;
} this.key = key;
public String getName() this.enabled = enabled;
{ }
return name;
} public String getName()
public String getKey() {
{ return name;
return key; }
}
public boolean isEnabled() public String getKey()
{ {
return enabled; return key;
} }
}
public boolean isEnabled()
/** {
* Get all registered audit applications return enabled;
* }
* @return Returns a map of audit applications keyed by their name }
*
* @since 3.4 /**
*/ * Get all registered audit applications
Map<String, AuditApplication> getAuditApplications(); *
* @return Returns a map of audit applications keyed by their name
/** *
* @param applicationName the name of the application to check * @since 3.4
* @param path the path to check */
* @return Returns <tt>true</tt> if auditing is enabled for the given path Map<String, AuditApplication> getAuditApplications();
*
* @since 3.2 /**
*/ * @param applicationName
boolean isAuditEnabled(String applicationName, String path); * the name of the application to check
* @param path
/** * the path to check
* Enable auditing for an application path * @return Returns <tt>true</tt> if auditing is enabled for the given path
* *
* @param applicationName the name of the application to check * @since 3.2
* @param path the path to enable */
* boolean isAuditEnabled(String applicationName, String path);
* @since 3.2
*/ /**
void enableAudit(String applicationName, String path); * Enable auditing for an application path
*
/** * @param applicationName
* Disable auditing for an application path * the name of the application to check
* * @param path
* @param applicationName the name of the application to check * the path to enable
* @param path the path to disable *
* * @since 3.2
* @since 3.2 */
*/ void enableAudit(String applicationName, String path);
void disableAudit(String applicationName, String path);
/**
/** * Disable auditing for an application path
* Remove all audit entries for the given application *
* * @param applicationName
* @param applicationName the name of the application for which to remove entries * the name of the application to check
* @return Returns the number of audit entries deleted * @param path
* * the path to disable
* @since 3.2 *
* * @since 3.2
* @deprecated Use {@link #clearAudit(String, Long, Long)} */
*/ void disableAudit(String applicationName, String path);
int clearAudit(String applicationName);
/**
/** * Remove all audit entries for the given application
* 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 * @param applicationName
* given then entries are deleted up until the current time. * the name of the application for which to remove entries
* * @return Returns the number of audit entries deleted
* @param applicationName the name of the application for which to remove entries *
* @param fromTime the start time of entries to remove (inclusive and optional) * @since 3.2
* @param toTime the end time of entries to remove (exclusive and optional) *
* @return Returns the number of audit entries deleted * @deprecated Use {@link #clearAudit(String, Long, Long)}
* */
* @since 3.4 int clearAudit(String applicationName);
*/
int clearAudit(String applicationName, Long fromTime, Long toTime); /**
* 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.
/** *
* 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 applicationName the name of the application for which to remove entries * @param fromTime
* @param fromId the start time of entries to remove (inclusive and optional) * the start time of entries to remove (inclusive and optional)
* @param toId the end time of entries to remove (exclusive and optional) * @param toTime
* @return Returns the number of audit entries deleted * the end time of entries to remove (exclusive and optional)
* * @return Returns the number of audit entries deleted
* @since 5.2.2 *
*/ * @since 3.4
int clearAuditByIdRange(String applicationName, Long fromId, Long toId); */
int clearAudit(String applicationName, Long fromTime, Long toTime);
/**
* Delete a discrete list of audit entries. /**
* <p/> * Remove audit entries for the given application between the audit entry ids.
* This method should not be called <i>while</i> processing *
* {@link #auditQuery(AuditQueryCallback, AuditQueryParameters, int) query results}. * @param applicationName
* * the name of the application for which to remove entries
* @param auditEntryIds the IDs of all audit entries to delete * @param fromId
* @return Returns the number of audit entries deleted * the start time of entries to remove (inclusive and optional)
* * @param toId
* @since 3.4 * the end time of entries to remove (exclusive and optional)
*/ * @return Returns the number of audit entries deleted
int clearAudit(List<Long> auditEntryIds); *
* @since 5.2.2
/** */
* The interface that will be used to give query results to the calling code. int clearAuditByIdRange(String applicationName, Long fromId, Long toId);
*
* @since 3.2 /**
*/ * Delete a discrete list of audit entries.
public static interface AuditQueryCallback * <p/>
{ * This method should not be called <i>while</i> processing {@link #auditQuery(AuditQueryCallback, AuditQueryParameters, int) query results}.
/** *
* Determines whether this callback requires the values argument to be populated when {@link #handleAuditEntry} * @param auditEntryIds
* is called. * the IDs of all audit entries to delete
* * @return Returns the number of audit entries deleted
* @return <code>true</code> if this callback requires the values argument to be populated *
*/ * @since 3.4
boolean valuesRequired(); */
int clearAudit(List<Long> auditEntryIds);
/**
* Handle a row of audit entry data. /**
* * The interface that will be used to give query results to the calling code.
* @param entryId the unique audit entry ID *
* @param applicationName the name of the application * @since 3.2
* @param user the user that logged the entry */
* @param time the time of the entry public static interface AuditQueryCallback
* @param values the values map as created {
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop /**
*/ * Determines whether this callback requires the values argument to be populated when {@link #handleAuditEntry} is called.
boolean handleAuditEntry( *
Long entryId, * @return <code>true</code> if this callback requires the values argument to be populated
String applicationName, */
String user, boolean valuesRequired();
long time,
Map<String, Serializable> values); /**
* Handle a row of audit entry data.
/** *
* Handle audit entry failures * @param entryId
* * the unique audit entry ID
* @param entryId the entry ID * @param applicationName
* @param errorMsg the error message * the name of the application
* @param error the exception causing the error (may be <tt>null</tt>) * @param user
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop * the user that logged the entry
*/ * @param time
boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error); * 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
* Issue an audit query using the given parameters and consuming results in the callback. */
* Results are returned in entry order, corresponding to time order. boolean handleAuditEntry(
* Long entryId,
* @param callback the callback that will handle results String applicationName,
* @param parameters the parameters for the query (may not be <tt>null</tt>) String user,
* @param maxResults the maximum number of results to retrieve (must be greater than 0) long time,
* Map<String, Serializable> values);
* @throws IllegalArgumentException if maxResults less or equal to zero
* /**
* @since 3.3 * Handle audit entry failures
*/ *
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults); * @param entryId
* the entry ID
/** * @param errorMsg
* Issue an audit query to retrieve min / max audit record id for a given application. * the error message
* * @param error
* @param applicationName the name of the application * the exception causing the error (may be <tt>null</tt>)
* @param extremes a list containing min/max or both * @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
* @return a map containing min/max and the associated value */
*/ boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error);
HashMap<String, Long> getAuditMinMaxByApp(String applicationName, List<String> extremes); }
/** /**
* Issue an audit query to retrieve min / max audit record id for a given application. * 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 applicationName the name of the application * @param callback
* @return a map containing min/max and the associated value * the callback that will handle results
*/ * @param parameters
default int getAuditEntriesCountByApp(String applicationName) * the parameters for the query (may not be <tt>null</tt>)
{ * @param maxResults
return -1; * the maximum number of results to retrieve (must be greater than 0)
} *
* @throws IllegalArgumentException
/** * if maxResults less or equal to zero
* Issue an audit query to retrieve min / max audit record id for a given application and properties *
* * @since 3.3
* @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 void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
*/
default int getAuditEntriesCountByAppAndProperties(AuditQueryParameters parameters) /**
{ * Issue an audit query to retrieve min / max audit record id for a given application.
return -1; *
} * @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;
}
}

View File

@@ -514,4 +514,10 @@
<bean name="ldapInitialDirContextCache" factory-bean="cacheFactory" factory-method="createCache"> <bean name="ldapInitialDirContextCache" factory-bean="cacheFactory" factory-method="createCache">
<constructor-arg value="cache.ldapInitialDirContextCache"/> <constructor-arg value="cache.ldapInitialDirContextCache"/>
</bean> </bean>
<!-- The shared cache for Folder Node -->
<bean name="folderSizeSharedCache" factory-bean="cacheFactory" factory-method="createCache">
<constructor-arg value="cache.folderSizeSharedCache"/>
</bean>
</beans> </beans>

View File

@@ -163,7 +163,7 @@ cache.node.nodesSharedCache.tx.statsEnabled=${caches.tx.statsEnabled}
cache.node.nodesSharedCache.maxItems=250000 cache.node.nodesSharedCache.maxItems=250000
cache.node.nodesSharedCache.timeToLiveSeconds=300 cache.node.nodesSharedCache.timeToLiveSeconds=300
cache.node.nodesSharedCache.maxIdleSeconds=0 cache.node.nodesSharedCache.maxIdleSeconds=0
cache.node.nodesSharedCache.cluster.type=invalidating cache.node.nodesSharedCache.cluster.type=fully-distributed
cache.node.nodesSharedCache.backup-count=1 cache.node.nodesSharedCache.backup-count=1
cache.node.nodesSharedCache.eviction-policy=LRU cache.node.nodesSharedCache.eviction-policy=LRU
cache.node.nodesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy cache.node.nodesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
@@ -394,7 +394,7 @@ cache.loadedResourceBundlesSharedCache.tx.statsEnabled=${caches.tx.statsEnabled}
cache.loadedResourceBundlesSharedCache.maxItems=1000 cache.loadedResourceBundlesSharedCache.maxItems=1000
cache.loadedResourceBundlesSharedCache.timeToLiveSeconds=0 cache.loadedResourceBundlesSharedCache.timeToLiveSeconds=0
cache.loadedResourceBundlesSharedCache.maxIdleSeconds=0 cache.loadedResourceBundlesSharedCache.maxIdleSeconds=0
cache.loadedResourceBundlesSharedCache.cluster.type=invalidating cache.loadedResourceBundlesSharedCache.cluster.type=local
cache.loadedResourceBundlesSharedCache.backup-count=1 cache.loadedResourceBundlesSharedCache.backup-count=1
cache.loadedResourceBundlesSharedCache.eviction-policy=LRU cache.loadedResourceBundlesSharedCache.eviction-policy=LRU
cache.loadedResourceBundlesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy cache.loadedResourceBundlesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
@@ -405,7 +405,7 @@ cache.messagesSharedCache.tx.statsEnabled=${caches.tx.statsEnabled}
cache.messagesSharedCache.maxItems=1000 cache.messagesSharedCache.maxItems=1000
cache.messagesSharedCache.timeToLiveSeconds=0 cache.messagesSharedCache.timeToLiveSeconds=0
cache.messagesSharedCache.maxIdleSeconds=0 cache.messagesSharedCache.maxIdleSeconds=0
cache.messagesSharedCache.cluster.type=invalidating cache.messagesSharedCache.cluster.type=local
cache.messagesSharedCache.backup-count=1 cache.messagesSharedCache.backup-count=1
cache.messagesSharedCache.eviction-policy=LRU cache.messagesSharedCache.eviction-policy=LRU
cache.messagesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy cache.messagesSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
@@ -709,4 +709,13 @@ cache.ldapInitialDirContextCache.cluster.type=fully-distributed
cache.ldapInitialDirContextCache.backup-count=1 cache.ldapInitialDirContextCache.backup-count=1
cache.ldapInitialDirContextCache.eviction-policy=NONE cache.ldapInitialDirContextCache.eviction-policy=NONE
cache.ldapInitialDirContextCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy cache.ldapInitialDirContextCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy
cache.ldapInitialDirContextCache.readBackupData=false cache.ldapInitialDirContextCache.readBackupData=false
cache.folderSizeSharedCache.maxItems=1000
cache.folderSizeSharedCache.timeToLiveSeconds=300
cache.folderSizeSharedCache.maxIdleSeconds=0
cache.folderSizeSharedCache.cluster.type=fully-distributed
cache.folderSizeSharedCache.backup-count=1
cache.folderSizeSharedCache.eviction-policy=LRU
cache.folderSizeSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
cache.folderSizeSharedCache.readBackupData=false

View File

@@ -330,6 +330,42 @@
<property name="nodeService" ref="nodeService"/> <property name="nodeService" ref="nodeService"/>
<property name="policyComponent" ref="policyComponent"/> <property name="policyComponent" ref="policyComponent"/>
<property name="searchTrackingComponent" ref="searchTrackingComponent" /> <property name="searchTrackingComponent" ref="searchTrackingComponent" />
</bean> </bean>
<bean id="nodeSizeThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName">
<value>defaultThreadPool</value>
</property>
<property name="corePoolSize">
<value>${default.nodeSize.corePoolSize}</value>
</property>
<property name="maximumPoolSize">
<value>${default.nodeSize.maximumPoolSize}</value>
</property>
<property name="workQueueSize">
<value>${default.nodeSize.workQueueSize}</value>
</property>
</bean>
<bean id="NodeSizeDetailsServiceImpl" class="org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl">
<property name="searchService" ref="SearchService"/>
<property name="simpleCache" ref="folderSizeSharedCache" />
<property name="transactionService" ref="transactionService"/>
<property name="threadPoolExecutor">
<ref bean="nodeSizeThreadPool"/>
</property>
<property name="defaultItems" value="${default.async.folder.items}"/>
</bean>
<bean id="NodeSizeDetailsService" class="org.springframework.aop.framework.ProxyFactoryBean" >
<property name="targetName">
<value>NodeSizeDetailsServiceImpl</value>
</property>
<property name="proxyInterfaces">
<list>
<value>org.alfresco.repo.node.sizedetails.NodeSizeDetailsService</value>
</list>
</property>
</bean>
</beans> </beans>

View File

@@ -1385,3 +1385,12 @@ scripts.execution.maxMemoryUsedInBytes=-1
# Number of instructions that will trigger the observer # Number of instructions that will trigger the observer
scripts.execution.observerInstructionCount=5000 scripts.execution.observerInstructionCount=5000
# Default value being used in POST/size-details endpoint to partition a huge folder into smaller chunks
# so that we can compute more efficiently and consolidate all sizes into a single unit.
default.async.folder.items=1000
# Default NodeSize Thread pool
default.nodeSize.corePoolSize=5
default.nodeSize.maximumPoolSize=10
default.nodeSize.workQueueSize=100