Compare commits

...

135 Commits
12.13 ... 14.35

Author SHA1 Message Date
Travis CI User
67af102fc0 [maven-release-plugin][skip ci] prepare release 14.35 2021-11-22 18:59:15 +00:00
tiagosalvado10
20a617adef [MNT-22680] Bump surf-webscripts to 8.26 (#814) 2021-11-22 16:18:27 +00:00
Travis CI User
5947ae891a [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-22 13:51:01 +00:00
Travis CI User
26957c7b81 [maven-release-plugin][skip ci] prepare release 14.34 2021-11-22 13:50:58 +00:00
David Edwards
f212e8ff81 ACS-222 Add missing ArchivedIOException throw (#812)
The getContentString() method catches all Exceptions and re-throws as a
custom ContentIOException. We want ArchivedIOExceptions re-thrown.
2021-11-22 12:58:02 +00:00
Alan Davis
512540e32e ACS-2270 Read T-Engine config in alphabetical order (#806)
* T-Engines config need to be combined in the same predefined order in the all-in-one transformer,
T-Router and the Content Repository with individual T-Engines.
2021-11-22 12:53:22 +00:00
Travis CI User
bafc3fb3e4 [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-19 12:34:42 +00:00
Travis CI User
51dd968069 [maven-release-plugin][skip ci] prepare release 14.33 2021-11-19 12:34:39 +00:00
David Edwards
d698619bff ACS-2222 Add ArchivedIOException (#802)
`ArchivedIOException` and `ArchivedContentException` added to provide an appropriate response when attempting to access content that is archived, for example in GLACIER s3.

Discovered and fixed a bug, when producing an error during content streaming that caused clients to hang. Content Length now set to `-1` when any `ContentIOException` is thrown so that any clients are not expecting and waiting to received the content.
2021-11-19 11:36:35 +00:00
evasques
be4fa79c76 MNT-18700 - Dynamic Message bundles do not deploy/reload automatically (#805)
* Restored the ability to register dynamic messages on bootstrap
* Added unit tests on bootstrap to verify if the dynamic messages are registered on bootstrap
* Added unit tests for the Repo Admin Console regarding registering dynamic messages and classpath files
2021-11-18 15:48:40 +00:00
Travis CI User
2c51af33d3 [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-17 20:20:53 +00:00
Travis CI User
8f73a82358 [maven-release-plugin][skip ci] prepare release 14.32 2021-11-17 20:20:50 +00:00
tiagosalvado10
ee07bb635f [PRODSEC-5795] Bump surf-webscripts to 8.25 (#803) 2021-11-17 19:28:24 +00:00
Travis CI User
9ee35d793b [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-16 16:13:52 +00:00
Travis CI User
9ebc8c3cbe [maven-release-plugin][skip ci] prepare release 14.31 2021-11-16 16:13:50 +00:00
Alan Davis
53c70cee66 ACS-1998 Enhance the transform config (#796)
* ACS-1998 Pick up changes in transform-model 1.4.1 for "xxxSupported" elements [skip ci]
* Pick up 2.5.4 t-engines for testing
2021-11-16 15:16:51 +00:00
Travis CI User
46da760cb2 [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-12 11:03:30 +00:00
Travis CI User
f6d005c15c [maven-release-plugin][skip ci] prepare release 14.30 2021-11-12 11:03:27 +00:00
alandavis
3a86e5c2f0 Fix minor typo in README.md [skip ci] 2021-11-12 10:00:41 +00:00
Jamal Kaabi-Mofrad
244ad60c5f ACS-2228: Fixed duplicate index error for MySql DB. Also, re-ordered removal of table statement in the alf_sever patch. 2021-11-12 04:33:54 +00:00
Travis CI User
fc6cdf8d6b [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-11 17:52:34 +00:00
Travis CI User
18ab090f4e [maven-release-plugin][skip ci] prepare release 14.29 2021-11-11 17:52:30 +00:00
Jamal Kaabi-Mofrad
a9e3221883 ACS-1795: Bump tas-utility to 3.0.47 and tas-restapi to 1.65. (#797) 2021-11-11 16:05:18 +00:00
Travis CI User
edfad6b4ab [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-11 13:02:54 +00:00
Travis CI User
fecdca496a [maven-release-plugin][skip ci] prepare release 14.28 2021-11-11 13:02:52 +00:00
alandavis
e4fd6d7606 Tidy up of unused FrequentlyFailingTests references and run build with disabled tests 2021-11-11 12:11:10 +00:00
alandavis
7b8c865f2b ACS-2243 Disable Intermittent failure: JobLockServiceTest.testGetLockWithCallbackNormal [skip ci] 2021-11-11 11:55:06 +00:00
alandavis
38a5664cf3 ACS-2242 Disable Intermittent failure: EncryptionTests.testFailedEncryptionWithCachedCiphers [skip ci] 2021-11-11 11:54:32 +00:00
alandavis
c8b0a6dbd0 ACS-2245 Disable Intermittent failure: FixedAclUpdaterTest.testAsyncWithNodeLock [skip ci] 2021-11-11 11:52:41 +00:00
Travis CI User
868672e7ea [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-09 19:48:38 +00:00
Travis CI User
e712d188fe [maven-release-plugin][skip ci] prepare release 14.27 2021-11-09 19:48:35 +00:00
Nithin Nambiar
bdedc23c95 ACS-2238 Added missing BatchProcessWorkProvider implemenations (#793) 2021-11-09 16:41:21 +00:00
Travis CI User
aff84374c4 [maven-release-plugin][skip ci] prepare for next development iteration 2021-11-01 22:02:33 +00:00
Travis CI User
779731018d [maven-release-plugin][skip ci] prepare release 14.26 2021-11-01 22:02:30 +00:00
Alan Davis
e242f5db98 PRODSEC-4343 Build the MMT tool in alfreaco-community-repo so it picks up the latest libraries (#785)
The code form MMT comes from this project anyway
2021-11-01 18:45:45 +00:00
alandavis
68cde24419 Tidy up of README files on how to build projects [skip ci] 2021-10-29 13:53:28 +01:00
Travis CI User
7daef9ee21 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-28 16:15:22 +00:00
Travis CI User
db52b87849 [maven-release-plugin][skip ci] prepare release 14.25 2021-10-28 16:15:19 +00:00
Damian Ujma
cf379f3baa Feature/acs 2129 setup agent (#781)
* ACS-2129 Setup agent scanning

* ACS-2129 Run agent scanning only for master and release branches

* ACS-2129 Fix source_clear.sh
2021-10-28 15:59:23 +02:00
Travis CI User
de04ce6944 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-28 10:08:09 +00:00
Travis CI User
caf5fdede4 [maven-release-plugin][skip ci] prepare release 14.24 2021-10-28 10:08:06 +00:00
mpichura
2d4140ea64 ACS-2147 renaming method which gets storage props (#778)
* ACS-2147: Adding missing ContentStore implementation, switching some logging
to trace.

* ACS-2147: Renaming getObjectStorageProperties to getStorageProperties

* [maven-release-plugin][skip ci] prepare release 14.20

* [maven-release-plugin][skip ci] prepare for next development iteration

* Fix/mnt 21506 sanitation create people (#756)

* MNT-21506: sanitize username on nodeBrowser Repo

* [maven-release-plugin][skip ci] prepare release 14.21

* [maven-release-plugin][skip ci] prepare for next development iteration

* ACS-2148: Adding get StorageObjectProps to ContentService (#773)

* ACS-2148: Adding get StorageObjectProps to ContentService and implementation.

* ACS-2148: Adding propertyQName param to get storage property method.

* ACS-2148: Security config for added method.

* ACS-2148: Renaming getObjectStorageProperties to getStorageProperties

* ACS-2148: Javadoc fix

* ACS-2148: Fixing security context after method renaming.

* ACS-2148: ContentService with new method names.

* ACS-2147: Adding missing ContentStore implementation, switching some logging
to trace.

* ACS-2147: Renaming getObjectStorageProperties to getStorageProperties

* ACS-2148: ContentService with new method names.

* ACS-2148: Small fixes after code review.
2021-10-27 13:35:11 +02:00
Travis CI User
3c928a4928 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-27 00:30:21 +00:00
Travis CI User
599f5727a0 [maven-release-plugin][skip ci] prepare release 14.23 2021-10-27 00:30:18 +00:00
Lev Belava
7ac5cb1807 ACS-2121 Alfresco repo migration from Mockito 1 to Mockito 3 (#770) 2021-10-26 23:55:03 +01:00
Travis CI User
d311ef2c5f [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-26 12:39:10 +00:00
Travis CI User
6f820e2c25 [maven-release-plugin][skip ci] prepare release 14.22 2021-10-26 12:39:07 +00:00
mpichura
e515dacab1 ACS-2148: Adding get StorageObjectProps to ContentService (#773)
* ACS-2148: Adding get StorageObjectProps to ContentService and implementation.

* ACS-2148: Adding propertyQName param to get storage property method.

* ACS-2148: Security config for added method.

* ACS-2148: Renaming getObjectStorageProperties to getStorageProperties

* ACS-2148: Javadoc fix

* ACS-2148: Fixing security context after method renaming.
2021-10-26 13:48:53 +02:00
Travis CI User
5041249f03 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-26 09:48:01 +00:00
Travis CI User
1b26e3a937 [maven-release-plugin][skip ci] prepare release 14.21 2021-10-26 09:47:57 +00:00
Vítor Moreira
a2d9afcecc Fix/mnt 21506 sanitation create people (#756)
* MNT-21506: sanitize username on nodeBrowser Repo
2021-10-26 09:58:11 +01:00
Travis CI User
577de6bf4c [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-26 08:45:13 +00:00
Travis CI User
f71f53c988 [maven-release-plugin][skip ci] prepare release 14.20 2021-10-26 08:45:10 +00:00
mpichura
7e4d72a66a ACS-2147: Fixing docker logins in init.sh (#771) 2021-10-25 13:10:39 +02:00
Aleksandra Onych
142f99b2a2 MNT-21883 - Fix unshare content from smart folder (#765) 2021-10-25 10:28:36 +02:00
mpichura
1b0ddb1e74 Feature/acs 2147 add get storage object props in content store (#769)
* ACS-2147: initial idea for adding storage properties to ContentStore.

* ACS-2147: adding implementations to ContentStore children + some static analysis cleanup.

* ACS-2147: adding javadoc and small fixes to ObjectStorageProps.

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* ACS-2147: initial idea for adding storage properties to ContentStore.

* ACS-2147: adding implementations to ContentStore children + some static analysis cleanup.

* ACS-2147: adding javadoc and small fixes to ObjectStorageProps.

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* ACS-2147: Adding unit tests and changes after first round of code review.

* ACS-2147: initial idea for adding storage properties to ContentStore.

* ACS-2147: adding implementations to ContentStore children + some static analysis cleanup.

* ACS-2147: adding javadoc and small fixes to ObjectStorageProps.

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* ACS-2147: Adding unit tests and changes after first round of code review.

* ACS-2147: adding implementations to ContentStore children + some static analysis cleanup.

* License header update

Co-authored-by: David Edwards <david.edwards@alfresco.com>

* ACS-2147: Fixes after reverting some 'boy scout' refactor.

* ACS-2147: Rephrasing Alfresco-derived storage properties.

* ACS-2147: Reverting some 'boy scout' refactor.

* ACS-2147: Renaming enum values.

* ACS-2147: Removing wildcard import.

Co-authored-by: David Edwards <david.edwards@alfresco.com>
2021-10-25 09:47:36 +02:00
Travis CI User
4fa0157594 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-22 08:53:09 +00:00
Travis CI User
c1196ed8e9 [maven-release-plugin][skip ci] prepare release 14.19 2021-10-22 08:53:06 +00:00
mpichura
90a69173bd ACS-2147: Adding Experimental annotation. (#764) 2021-10-22 10:07:48 +02:00
Travis CI User
cb0a07d5da [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-22 06:47:39 +00:00
Travis CI User
77e721d66a [maven-release-plugin][skip ci] prepare release 14.18 2021-10-22 06:47:36 +00:00
Suneet Gupta
25d2a51254 Merge branch 'master' of github.com:Alfresco/alfresco-community-repo 2021-10-22 11:29:08 +05:30
Suneet Gupta
54fe4bb969 Added default.properties for test cases config 2021-10-22 11:25:43 +05:30
Travis CI User
7e719cae80 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-21 15:59:24 +00:00
Travis CI User
157a6ba1c5 [maven-release-plugin][skip ci] prepare release 14.17 2021-10-21 15:59:21 +00:00
alandavis
4fc165150a Revert "Alfresco community repo migration from Mockito 1 to Mockito 3 (#745)"
This reverts commit b846ccd85e.
2021-10-21 15:21:34 +01:00
Travis CI User
d574d05066 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-21 10:33:28 +00:00
Travis CI User
f66426bb60 [maven-release-plugin][skip ci] prepare release 14.16 2021-10-21 10:33:25 +00:00
Lev Belava
b846ccd85e Alfresco community repo migration from Mockito 1 to Mockito 3 (#745) 2021-10-21 11:45:35 +02:00
Travis CI User
09fc6f1e25 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-19 16:27:33 +00:00
Travis CI User
630f553fce [maven-release-plugin][skip ci] prepare release 14.15 2021-10-19 16:27:30 +00:00
Tom Page
7242a78705 MNT-21985 Handle case where permissions in Solr and DB are out of sync. (#760)
* MNT-21985 Handle case where permissions in Solr and DB are out of sync.

* MNT-21985 Simplify return logic in error case.
2021-10-19 16:40:50 +01:00
Travis CI User
539a89537b [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-19 12:53:46 +00:00
Travis CI User
608c16d4a4 [maven-release-plugin][skip ci] prepare release 14.14 2021-10-19 12:53:43 +00:00
David Edwards
c00736c639 ACS-2064 DAU: Fix response content type always PDF (#754)
* ACS-2064 ContentStore.java to require mimetype

- Updates the ContentStore interface to also require a mimetype, deprecates old method signatures
- Original interface methods maintained so code should be backwards compatible
- Implementing classes updated to reflect changes
2021-10-19 13:10:17 +01:00
Travis CI User
15cb7ff44e [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-14 14:11:10 +00:00
Travis CI User
4776e37223 [maven-release-plugin][skip ci] prepare release 14.13 2021-10-14 14:11:07 +00:00
Lev Belava
cbd45fcb3e MNT-21706 NodeService setAssociations list of elements is now handled. (#746)
MNT-21706 NodeService setAssociations list of elements is now handled.
2021-10-14 15:27:41 +02:00
Travis CI User
655cadbda0 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-12 17:01:08 +00:00
Travis CI User
6d7e3bb787 [maven-release-plugin][skip ci] prepare release 14.12 2021-10-12 17:01:05 +00:00
Nithin Nambiar
bb8d10074e ACS-1112 Upgrade the BatchProcessor counting mechanism to work with "long" Java type (#706)
* ACS-1112 update to long data type
2021-10-12 17:04:31 +01:00
alandavis
806880a86b Include the latest MariaDB and MySQL tests in PRs.
[skip ci]
2021-10-11 12:21:42 +01:00
Nithin Nambiar
e68f56270a ACS-849_incorrect_probes added db check (#692)
* ACS-849_incorrect_probes added db check
2021-10-11 12:08:43 +01:00
Travis CI User
8705d97407 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-08 15:44:38 +00:00
Travis CI User
44e3242132 [maven-release-plugin][skip ci] prepare release 14.11 2021-10-08 15:44:36 +00:00
alandavis
8a3cdd55a7 Revert "Bump mysql-connector-java from 8.0.25 to 8.0.26 (#741)"
As tests on MySQL 5.7.23 failed - not in the PR build

This reverts commit 3b41308ecc.
2021-10-08 15:37:35 +01:00
alandavis
cff2a70b17 Use a common property for json-path as it is used in community and enterprise repo and packaging 2021-10-08 15:24:36 +01:00
dependabot[bot]
3b41308ecc Bump mysql-connector-java from 8.0.25 to 8.0.26 (#741) 2021-10-08 13:40:53 +00:00
dependabot[bot]
8a60e26ff0 Bump lombok from 1.18.20 to 1.18.22 (#742) 2021-10-08 13:38:37 +00:00
Ryan Wilson
accfc4662d Community contribution: fix spelling within permissionDefinition.xml (#469)
There were a number of locations within comments that contained incorrect spelling. [skip ci]
2021-10-08 14:30:43 +01:00
Travis CI User
1e0fcfcc14 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-08 11:06:13 +00:00
Travis CI User
837a706514 [maven-release-plugin][skip ci] prepare release 14.10 2021-10-08 11:06:10 +00:00
dependabot[bot]
db290c98f2 Bump cmis from 1.30 to 1.31 (#711) 2021-10-08 09:58:24 +00:00
dependabot[bot]
12682ddcff Bump dependency.spring.version from 5.3.9 to 5.3.10 (#715) 2021-10-08 09:39:26 +00:00
dependabot[bot]
0ed2e9b3a7 Bump joda-time from 2.10.10 to 2.10.12 (#716) 2021-10-08 09:37:42 +00:00
dependabot[bot]
3442e91575 Bump maven-war-plugin from 3.2.2 to 3.3.2 (#719) 2021-10-08 09:34:46 +00:00
Travis CI User
59b636e0ba [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-07 18:15:14 +00:00
Travis CI User
0333fe05b5 [maven-release-plugin][skip ci] prepare release 14.9 2021-10-07 18:15:11 +00:00
alandavis
9b592bfc13 Revert "Bump mysql-connector-java from 8.0.25 to 8.0.26 (#609)"
As DbNodeServiceImplTest>BaseNodeServiceTest.testLargeStrings:1061 » AlfrescoRuntime now fails

This reverts commit 386696d58b.
2021-10-07 18:26:05 +01:00
dependabot-preview[bot]
386696d58b Bump mysql-connector-java from 8.0.25 to 8.0.26 (#609)
Bumps [mysql-connector-java](https://github.com/mysql/mysql-connector-j) from 8.0.25 to 8.0.26.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Alan Davis <alan.davis@alfresco.com>
2021-10-07 15:23:38 +01:00
dependabot[bot]
1f243d629e Bump xmlsec from 1.5.8 to 2.2.3 (#732) 2021-10-07 14:16:40 +00:00
dependabot[bot]
dee7625998 Bump postgresql from 42.2.20 to 42.2.24 (#734) 2021-10-07 14:15:04 +00:00
dependabot[bot]
1c541281db Bump maven-javadoc-plugin from 3.3.0 to 3.3.1 (#733) 2021-10-07 14:11:08 +00:00
dependabot-preview[bot]
c991290c01 Bump dependency.slf4j.version from 1.7.30 to 1.7.32 (#611) 2021-10-07 14:01:24 +00:00
Travis CI User
9b62808ed7 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-07 13:00:53 +00:00
Travis CI User
d4e8bba9f5 [maven-release-plugin][skip ci] prepare release 14.8 2021-10-07 13:00:50 +00:00
dependabot[bot]
5ae240c392 Bump docker-java from 3.2.11 to 3.2.12 (#735) 2021-10-07 11:31:07 +00:00
dependabot[bot]
a5b35b7d96 Bump spring-security-core from 5.5.1 to 5.5.2 (#737) 2021-10-07 11:30:32 +00:00
dependabot[bot]
d2544b7a4d Bump docker-maven-plugin from 0.34.1 to 0.37.0 (#724) 2021-10-07 11:14:27 +00:00
dependabot[bot]
b9abc05eda Bump maven-artifact from 3.8.1 to 3.8.3 (#727) 2021-10-07 11:11:15 +00:00
dependabot[bot]
04e3743f01 Bump jsoup from 1.14.2 to 1.14.3 (#730) 2021-10-07 11:08:54 +00:00
Travis CI User
745295c4ba [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-07 10:30:48 +00:00
Travis CI User
c9b08594de [maven-release-plugin][skip ci] prepare release 14.7 2021-10-07 10:30:45 +00:00
dependabot[bot]
1d8044076c Bump dependency.webscripts.version from 8.23 to 8.24 (#710) 2021-10-07 09:10:15 +00:00
dependabot[bot]
377b082ef8 Bump mariadb-java-client from 2.7.2 to 2.7.4 (#709) 2021-10-07 09:07:17 +00:00
dependabot[bot]
ad2525bf17 Bump dependency.cxf.version from 3.4.4 to 3.4.5 (#708) 2021-10-07 09:04:57 +00:00
dependabot[bot]
888b26ef72 Bump groovy from 2.5.9 to 3.0.9 (#713)
Bumps [groovy](https://github.com/apache/groovy) from 2.5.9 to 3.0.9.
- [Release notes](https://github.com/apache/groovy/releases)
- [Commits](https://github.com/apache/groovy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-07 09:51:16 +01:00
alandavis
aa4a5a6063 Try to give dependabot access to Nexus 2021-10-05 11:12:24 +01:00
dependabot-preview[bot]
7ea91ea702 Upgrade to GitHub-native Dependabot (#424)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-10-05 09:31:58 +02:00
Travis CI User
b3e8051f08 [maven-release-plugin][skip ci] prepare for next development iteration 2021-10-01 14:32:21 +00:00
Travis CI User
4ba0d3a899 [maven-release-plugin][skip ci] prepare release 14.6 2021-10-01 14:32:18 +00:00
kcichonczyk
8d78b257aa [PRODSEC-4829] Bumped versions of libraries to prevent security vulnerabilities: (#703)
* 'keycloak' version to 15.0.2
2021-10-01 14:38:58 +02:00
Travis CI User
df67011596 [maven-release-plugin][skip ci] prepare for next development iteration 2021-09-29 20:23:22 +00:00
Travis CI User
871bd40d6d [maven-release-plugin][skip ci] prepare release 14.5 2021-09-29 20:23:19 +00:00
montgolfiere
2ef97e0b23 ACS-2067: Fix probes for when DAU enabled (#700) 2021-09-29 19:32:10 +01:00
Vítor Moreira
f1d48f7aab MNT-22428: configurable unsecure jsonp callback CMIS operation (#698) (#704)
* MNT-22428: configurable unsecure jsonp callback CMIS operation

(cherry picked from commit 5807e756bd)
2021-09-29 17:44:06 +01:00
Travis CI User
b5f24f5d58 [maven-release-plugin][skip ci] prepare for next development iteration 2021-09-29 12:17:15 +00:00
Travis CI User
14668044f4 [maven-release-plugin][skip ci] prepare release 14.4 2021-09-29 12:17:12 +00:00
evasques
c5281d7f10 MNT-22600 Nodes with security marks appear unfiltered on CMIS DB queries (#702)
* Change isUnfiltered to protected so we can extend it in enterprise
* Added test method to be able to do a cmis query test

Original commit in governance-services: e4e3235328
2021-09-29 12:07:06 +01:00
Travis CI User
00565f3bc9 [maven-release-plugin][skip ci] prepare for next development iteration 2021-09-29 10:03:49 +00:00
Travis CI User
f15c4d7a8f [maven-release-plugin][skip ci] prepare release 14.3 2021-09-29 10:03:47 +00:00
Piotr Żurek
85a3c71849 MNT-22611 - Fix bulk import parameters parsing (#699) 2021-09-29 10:50:54 +02:00
Travis CI User
4db8ca16e1 [maven-release-plugin][skip ci] prepare for next development iteration 2021-09-29 04:44:40 +00:00
Travis CI User
52e71719d1 [maven-release-plugin][skip ci] prepare release 14.2 2021-09-29 04:44:37 +00:00
alandavis
507161a1d0 Get master ready for 7.2.0 development 2021-09-28 22:56:03 +01:00
145 changed files with 4641 additions and 2042 deletions

181
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,181 @@
version: 2
registries:
maven-repository-artifacts-alfresco-com-nexus-content-groups-int:
type: maven-repository
url: https://artifacts.alfresco.com/nexus/content/groups/internal
username: ${{secrets.NEXUS_USERNAME}}
password: ${{secrets.NEXUS_PASSWORD}}
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: daily
time: "22:00"
timezone: Africa/Abidjan
open-pull-requests-limit: 99
ignore:
- dependency-name: com.google.code.gson:gson
versions:
- "> 2.8.6"
- dependency-name: io.fabric8:fabric8-maven-plugin
versions:
- "> 4.4.0"
- dependency-name: javax.servlet:javax.servlet-api
versions:
- "> 3.0.1"
- dependency-name: org.acegisecurity:acegi-security
versions:
- "> 0.8.2_patched"
- dependency-name: org.activiti:activiti-engine
versions:
- "> 5.23.0"
- dependency-name: org.activiti:activiti-engine
versions:
- ">= 7.1.a, < 7.2"
- dependency-name: org.activiti:activiti-spring
versions:
- "> 5.23.0"
- dependency-name: org.activiti:activiti-spring
versions:
- ">= 7.1.a, < 7.2"
- dependency-name: org.apache.camel:camel-activemq
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-amqp
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-direct
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-directvm
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-jackson
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-mock
versions:
- "> 3.7.1"
- dependency-name: org.apache.camel:camel-spring
versions:
- "> 3.7.1"
- dependency-name: org.apache.chemistry.opencmis:chemistry-opencmis-client-impl
versions:
- "> 1.0.0"
- dependency-name: org.apache.chemistry.opencmis:chemistry-opencmis-commons-impl
versions:
- "> 1.0.0"
- dependency-name: org.apache.chemistry.opencmis:chemistry-opencmis-server-bindings
versions:
- "> 1.0.0"
- dependency-name: org.apache.chemistry.opencmis:chemistry-opencmis-test-tck
versions:
- "> 1.0.0"
- dependency-name: org.freemarker:freemarker
versions:
- "> 2.3.20-alfresco-patched-20200421"
- dependency-name: org.keycloak:keycloak-adapter-core
versions:
- "> 12.0.2"
- dependency-name: org.keycloak:keycloak-adapter-spi
versions:
- "> 12.0.2"
- dependency-name: org.keycloak:keycloak-authz-client
versions:
- "> 12.0.2"
- dependency-name: org.keycloak:keycloak-common
versions:
- "> 12.0.2"
- dependency-name: org.keycloak:keycloak-core
versions:
- "> 12.0.2"
- dependency-name: org.keycloak:keycloak-servlet-adapter-spi
versions:
- "> 12.0.2"
- dependency-name: org.eclipse.jetty:jetty-server
versions:
- 9.4.38.v20210224
- dependency-name: org.alfresco.tas:cmis
versions:
- "1.28"
- dependency-name: org.springframework:spring-webmvc
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-web
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-tx
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-orm
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-test
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-jms
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-jdbc
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-expression
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-core
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-context-support
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-context
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-beans
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.springframework:spring-aop
versions:
- 5.3.4
- 5.3.5
- dependency-name: org.alfresco.tas:restapi
versions:
- "1.55"
- dependency-name: org.eclipse.jetty:jetty-security
versions:
- 11.0.1
- dependency-name: org.alfresco.aos-module:alfresco-vti-bin
versions:
- 1.4.0-M1
- dependency-name: org.alfresco.aos-module:alfresco-aos-module-distributionzip
versions:
- 1.4.0-M1
- dependency-name: org.alfresco.aos-module:alfresco-aos-module
versions:
- 1.4.0-M1
- dependency-name: org.alfresco.surf:spring-webscripts-api
versions:
- "8.16"
- dependency-name: org.alfresco.surf:spring-webscripts:tests
versions:
- "8.16"
- dependency-name: org.alfresco.surf:spring-webscripts
versions:
- "8.16"
- dependency-name: org.alfresco.surf:spring-surf-core-configservice
versions:
- "8.16"
registries:
- maven-repository-artifacts-alfresco-com-nexus-content-groups-int

5
.gitignore vendored
View File

@@ -24,16 +24,17 @@ target
*.log.*
# Mobile Tools for Java (J2ME)
.mtj
.tmp/
# Package Files #
*.jar
*.war
*.ear
# maven-shade-plugin for mmt tool
dependency-reduced-pom.xml
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

View File

@@ -43,6 +43,11 @@ install: travis_retry travis_wait 40 bash scripts/travis/build.sh
jobs:
include:
- name: "Source Clear Scan (SCA)"
if: branch = master OR branch =~ /release\/.*/
# Run Veracode
install: skip
script: travis_wait 30 bash scripts/travis/source_clear.sh
- name: "Core, Data-Model, Repository - AllUnitTestsSuite - Build and test"
if: commit_message !~ /\[skip repo\]/
@@ -55,7 +60,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext02TestSuite"
@@ -70,7 +75,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext04TestSuite"
@@ -78,7 +83,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext05TestSuite"
@@ -97,7 +102,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContextExtraTestSuite"
@@ -105,7 +110,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - MiscContextTestSuite"
@@ -113,7 +118,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl repository -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - SearchTestSuite"
@@ -145,7 +150,8 @@ jobs:
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Repository - MariaDB 10.6 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
# We run tests on the latest version of MariaDB on pull requests plus the normal master and release branches - ignored on feature branches
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.6 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
@@ -159,7 +165,8 @@ jobs:
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - MySQL 8 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
# We run tests on the latest version of MySQL on pull requests plus the normal master and release branches - ignored on feature branches
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
before_script:
- docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mysql:8 --transaction-isolation='READ-COMMITTED'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
@@ -234,7 +241,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext03TestSuite"
@@ -242,7 +249,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext04TestSuite"
@@ -250,7 +257,7 @@ jobs:
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContextExtraTestSuite"

View File

@@ -2,13 +2,6 @@
[![Build Status](https://travis-ci.com/Alfresco/alfresco-community-repo.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-community-repo)
This project contains the bulk of the [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository) code.
To make the development process simpler, it brings together code historically in `alfresco-core`,
`alfresco-data-madel`, `alfresco-repository`, `alfresco-remote-api` and repository specific
tests and war file creation from `acs-community-packaging`. They exist as sub projects within the Maven Reactor and still
create the same artifacts.
#### Alfresco Core
Alfresco Core is a library packaged as a jar file which contains the following:
@@ -16,8 +9,6 @@ Alfresco Core is a library packaged as a jar file which contains the following:
* Canned queries interface and supporting classes
* Generic encryption supporting classes
Version 7 of the library uses Spring 5, Quartz 2.3 and does not have Hibernate dependency.
#### Alfresco Data Model
Data model is a library packaged as a jar file which contains the following:
* Dictionary, Repository and Search Services interfaces
@@ -31,14 +22,6 @@ Repository is a library packaged as a jar file which contains the following:
* Various Service implementations
* Utility classes
Tests are combined into test classes split by test type or Spring application context used in the test, see classes
in _src/test/java/org/alfresco_. All of these classes as well as individual tests can be run by specifying the test
class name and a set of DB connection properties. Check the travis.yml file for docker images that should be started
to provide a suitable test environment. For example:
~~~
mvn clean test -Dtest=SomeRepoTest -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql:alfresco -Ddb.username=alfresco -Ddb.password=alfresco
~~~
#### Alfresco Remote API
Remote API is a library packaged as a jar file which contains the following:
@@ -46,13 +29,10 @@ Remote API is a library packaged as a jar file which contains the following:
* WebScript implementations including [V1 REST APIs](https://community.alfresco.com/community/ecm/blog/2017/05/02/v1-rest-api-10-things-you-should-know)
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
Like the `alfresco-repository` tests are combined in test classes split by test type or Spring application context used
in the test.
#### Artifacts
The artifacts can be obtained by:
* downloading from [Alfresco maven repository](https://artifacts.alfresco.com/nexus/content/groups/public)
* getting as Maven dependency by adding the dependency to your pom file:
* as Maven dependency by adding the dependency to your pom file:
~~~
<dependency>
<groupId>org.alfresco</groupId>
@@ -94,40 +74,24 @@ and Alfresco maven repository:
~~~
The SNAPSHOT versions of the artifact are not published.
All current source versions are held in github. Historic versions can be found in [Alfresco SVN](https://svn.alfresco.com/repos/alfresco-open-mirror/services/alfresco-core/)
### Contributing guide
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
## Setting up your development environment
Although it is possible to work on individual github projects, we recommend working on the `alfresco-community-repo`
and `acs-community-packaging` in a single Intellij IDEA project. They depend on each other and typically you will
want to make changes to both of them if you are changing the repository code.
~~~
mkdir work
cd work
git clone git@github.com:Alfresco/alfresco-community-repo.git
git clone git@github.com:Alfresco/acs-community-packaging.git
~~~
If you wish to build these projects from the command line, use the following commands.
~~~
cd alfresco-community-repo
mvn clean install -Pbuild-docker-images -DskipTests=true -Dversion.edition=Community
cd ..
cd acs-community-packaging
mvn clean install -Pbuild-docker-images -Dmaven.javadoc.skip=true
cd ..
~~~
In Intellij IDEA, create a new project using the `work` directory as the source.
* File > New Project from Existing Sources > .../work > Maven
## Setting up and building your development environment
See the [Development Tomcat Environment](https://github.com/Alfresco/acs-community-packaging/tree/master/dev/README.md)
page which will show you how to try out your repository changes in a local tomcat instance.
If you wish to use Docker images, take a look at the aliases ending in `D` and the docker-compose files in this
project's test modules.
## Branches
As multiple projects have been combined, branch names use the ACS version they are targeting.
For example the code used to create the repository in ACS 6.2.1 is a branch called `releases/6.2.1`.
This project has a branch for each ACS release. For example the code in ACS 6.2.1 is a
branch called `releases/6.2.2`. In addition to the original 6.2.2 release it will also contain Hot Fixes
added later. The latest unreleased code is on the `master` branch. There are also `.N` branches, such as
`releases/7.1.N` on which we gather unreleased fixes for future service pack releases. They do not indicate
that one is planned.
The actual version number of the **repository artifacts** created by `alfresco-community-repo` are however different.
For example `release/6.2.1` artifacts are `7.183.x`. This adds some complexity, but ensures that
version numbers do not go backwards in existing releases. It also provides some level of
independence between the repository and other ACS components.
For historic reasons the version of artifacts created on each branch do not match the ACS version.
For example artifact in ACS 7.2.0 will be `14.<something>`.
The enterprise projects which extend the `alfresco-community-repo` use the same branch names and leading
artifact version number.
### Contributing guide
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
@@ -40,7 +40,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
<version>1.7.32</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -82,7 +82,7 @@
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.2.11</version>
<version>3.2.12</version>
</dependency>
</dependencies>
</project>

View File

@@ -619,11 +619,27 @@ public class BaseRMRestTest extends RestTest
* @return
*/
public List<String> searchForContentAsUser(UserModel user, String term)
{
String query = "cm:name:*" + term + "*";
return searchForContentAsUser(user,query,"afts");
}
/**
* Returns search results for the given search term
*
* @param user
* @param term
* @param query language
* @return
* @throws Exception
*/
public List<String> searchForContentAsUser(UserModel user, String q, String queryLanguage)
{
getRestAPIFactory().getRmRestWrapper().authenticateUser(user);
RestRequestQueryModel queryReq = new RestRequestQueryModel();
SearchRequest query = new SearchRequest(queryReq);
queryReq.setQuery("cm:name:*" + term + "*");
queryReq.setQuery(q);
queryReq.setLanguage(queryLanguage);
List<String> names = new ArrayList<>();
// wait for solr indexing

View File

@@ -0,0 +1,89 @@
# dataprep related
alfresco.scheme=http
alfresco.server=localhost
alfresco.port=8082
# sync service related
sync.scheme=http
sync.server=localhost
sync.port=9090
# Solr Server Settings
solr.scheme=http
solr.server=localhost
solr.port=8083
#Solr Indexing Time
solrWaitTimeInSeconds=20
# credentials
admin.user=admin
admin.password=admin
# Identity Service configuration
# set this property to run tests using AIS
# identity-service.auth-server-url=http://localhost:8999/auth
# in containers we cannot access directly JMX, so we will use http://jolokia.org agent
# disabling this we will use direct JMX calls to server
jmx.useJolokiaAgent=false
# Server Health section
# in ServerHealth#isServerReachable() - could also be shown.
# enable this option to view if on server there are tenants or not
serverHealth.showTenants=false
# TEST MANAGEMENT SECTION - Test Rail
#
# (currently supporting Test Rail v5.2.1.3472 integration)
#
# Example of configuration:
# ------------------------------------------------------
# if testManagement.enabled=true we enabled TestRailExecutorListener (if used in your suite xml file)
# testManagement.updateTestExecutionResultsOnly=true (this will just update the results of a test: no step will be updated - good for performance)
# testManagement.endPoint=https://alfresco.testrail.com/
# testManagement.username=<username>
# testManagement.apiKey=<api-key>
# testManagement.project=<id-of-your-project
# testManagement.testRun=<test-run-name>
# testManagement.includeOnlyTestCasesExecuted=true #if you want to include in your run ONLY the test cases that you run, then set this value to false
# testManagement.rateLimitInSeconds=1 #is the default rate limit after what minimum time, should we upload the next request. http://docs.gurock.com/testrail-api2/introduction #Rate Limit
# testManagement.suiteId=23 (the id of the Master suite)
# ------------------------------------------------------
testManagement.enabled=false
testManagement.endPoint=https://alfresco.testrail.com/
testManagement.username=
testManagement.apiKey=
testManagement.project=7
testManagement.includeOnlyTestCasesExecuted=true
testManagement.rateLimitInSeconds=1
testManagement.testRun=MyTestRunInTestRail
testManagement.suiteId=12
# The location of the reports path
reports.path=./target/reports
#
# Database Section
# You should provide here the database URL, that can be a differed server as alfresco.
# https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html
#
# Current supported db.url:
#
# MySQL:
# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
#
# PostgreSQL:
# db.url = jdbc:postgresql://<your-DB-IP>:3306/alfresco
#
# Oracle:
# db.url = jdbc:oracle://<your-DB-IP>:3306/alfresco
#
# MariaDB:
# db.url = jdbc:mariadb://<your-DB-IP>:3306/alfresco
#
db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
db.username = alfresco
db.password = alfresco
environment=default

View File

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

View File

@@ -1,4 +1,4 @@
TRANSFORMERS_TAG=2.5.3
TRANSFORMERS_TAG=2.5.4
SOLR6_TAG=2.0.2-RC1
POSTGRES_TAG=13.3
ACTIVEMQ_TAG=5.16.1

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
<properties>
@@ -108,7 +108,7 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -306,7 +306,7 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
}
}
private boolean isUnfiltered(NodeRef nodeRef)
protected boolean isUnfiltered(NodeRef nodeRef)
{
return !nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT);

View File

@@ -27,8 +27,9 @@
package org.alfresco.module.org_alfresco_module_rm.action.dm;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -352,7 +353,7 @@ public class DeclareAsVersionRecordActionUnitTest extends BaseActionUnitTest
private void setupMockedAspects()
{
doReturn(true).when(mockedNodeService).exists(actionedUponNodeRef);
doReturn(true).when(mockedDictionaryService).isSubClass(any(QName.class), eq(ContentModel.TYPE_CONTENT));
doReturn(true).when(mockedDictionaryService).isSubClass(nullable(QName.class), eq(ContentModel.TYPE_CONTENT));
doReturn(true).when(mockedNodeService).hasAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE);
doReturn(false).when(mockedNodeService).hasAspect(actionedUponNodeRef, ASPECT_RECORD);
doReturn(false).when(mockedNodeService).hasAspect(actionedUponNodeRef, ContentModel.ASPECT_WORKING_COPY);

View File

@@ -36,15 +36,13 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.Map;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
/**
* Unit tests for {@link AddToHoldAuditEvent}.
@@ -67,8 +65,6 @@ public class AddToHoldAuditEventUnitTest extends BaseUnitTest
@Before
public void setUp()
{
initMocks(this);
holdNodeRef = generateNodeRef();
String holdName = "Hold " + GUID.generate();
@@ -87,6 +83,6 @@ public class AddToHoldAuditEventUnitTest extends BaseUnitTest
public void testAddToHoldCausesAuditEvent()
{
addToHoldAuditEvent.onAddToHold(holdNodeRef, contentNodeRef);
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), isNull(Map.class), any(Map.class), eq(true), eq(false));
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), nullable(String.class), isNull(), anyMap(), eq(true), eq(false));
}
}

View File

@@ -37,15 +37,13 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.Map;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
/**
* Unit tests for {@link CreateHoldAuditEvent}.
@@ -68,8 +66,6 @@ public class CreateHoldAuditEventUnitTest extends BaseUnitTest
@Before
public void setUp()
{
initMocks(this);
holdNodeRef = generateNodeRef();
String holdName = "Hold " + GUID.generate();
String holdReason = "Reason " + GUID.generate();
@@ -88,6 +84,6 @@ public class CreateHoldAuditEventUnitTest extends BaseUnitTest
public void testCreateHoldCausesAuditEvent()
{
createHoldAuditEvent.onCreateNode(childAssociationRef);
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), any(String.class), isNull(Map.class), any(Map.class));
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), nullable(String.class), isNull(), anyMap());
}
}

View File

@@ -34,18 +34,15 @@ import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import java.util.Map;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
/**
* Unit tests for {@link DeleteHoldAuditEvent}.
@@ -67,8 +64,6 @@ public class DeleteHoldAuditEventUnitTest extends BaseUnitTest
@Before
public void setUp()
{
initMocks(this);
holdNodeRef = generateNodeRef();
String holdName = "Hold " + GUID.generate();
@@ -84,6 +79,6 @@ public class DeleteHoldAuditEventUnitTest extends BaseUnitTest
{
deleteHoldAuditEvent.beforeDeleteNode(holdNodeRef);
verify(mockedRecordsManagementAuditService, times(1))
.auditEvent(eq(holdNodeRef), any(String.class), any(Map.class), isNull(Map.class), Matchers.eq(true), Matchers.eq(false));
.auditEvent(eq(holdNodeRef), nullable(String.class), anyMap(), isNull(), eq(true), eq(false));
}
}

View File

@@ -27,25 +27,24 @@
package org.alfresco.module.org_alfresco_module_rm.audit.event;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Unit tests for {@link RemoveFromHoldAuditEvent}.
@@ -53,6 +52,7 @@ import org.mockito.Mock;
* @author Chris Shields
* @since 3.3
*/
@RunWith(MockitoJUnitRunner.class)
public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
{
@InjectMocks
@@ -70,16 +70,14 @@ public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
@Before
public void setUp()
{
initMocks(this);
holdNodeRef = generateNodeRef();
String holdName = "Hold " + GUID.generate();
contentNodeRef = generateNodeRef();
String contentName = "Content " + GUID.generate();
when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName);
when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName);
lenient().when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName);
lenient().when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName);
}
/**
@@ -89,7 +87,7 @@ public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
public void testRemoveFromHoldCausesAuditEvent()
{
removeFromHoldAuditEvent.onRemoveFromHold(holdNodeRef, contentNodeRef);
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), any(Map.class), isNull(Map.class), eq(true));
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), nullable(String.class), anyMap(), isNull(), eq(true));
}
}

View File

@@ -28,14 +28,14 @@
package org.alfresco.module.org_alfresco_module_rm.forms;
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
@@ -45,7 +45,6 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.repo.forms.Field;
import org.alfresco.repo.forms.FieldDefinition;
import org.alfresco.repo.forms.Form;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -81,7 +80,7 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
public void testAddCustomRMPropertiesNoneFound()
{
typeFormFilter.addCustomRMProperties(MY_CUSTOM_TYPE, mockForm);
verifyZeroInteractions(mockForm);
verifyNoMoreInteractions(mockForm);
}
/**
@@ -130,8 +129,8 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
typeFormFilter.afterGenerate(mockTypeDefinition, null, null, mockForm, null);
verify(mockedIdentifierService).generateIdentifier(any(QName.class), any(NodeRef.class));
verify(idDef).setDefaultValue(anyString());
verify(mockedIdentifierService).generateIdentifier(nullable(QName.class), nullable(NodeRef.class));
verify(idDef).setDefaultValue(nullable(String.class));
verify(vrDef).setDefaultValue(Boolean.FALSE.toString());
verify(rpDef).setDefaultValue("none|0");
}
@@ -162,7 +161,7 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
typeFormFilter.addCustomRMProperties(MY_CUSTOM_TYPE, mockForm);
// ensure that two custom properties have been added to the form
verify(mockForm, times(1)).addFields(anyListOf(Field.class));
verify(mockForm, times(1)).addFields(anyList());
}
/**

View File

@@ -30,16 +30,16 @@ package org.alfresco.module.org_alfresco_module_rm.job;
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.Arrays;
@@ -57,7 +57,6 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
@@ -98,7 +97,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
return callback.execute();
};
doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).doInTransaction(any(RetryingTransactionCallback.class),
Matchers.anyBoolean(), Matchers.anyBoolean());
anyBoolean(), anyBoolean());
// setup data
List<String> dispositionActions = buildList(CUTOFF, RETAIN);
@@ -141,7 +140,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
verifyQueryTimes(1);
// ensure nothing else happens becuase we have no results
verifyZeroInteractions(mockedNodeService, mockedRecordFolderService, mockedRetryingTransactionHelper);
verifyNoMoreInteractions(mockedNodeService, mockedRecordFolderService, mockedRetryingTransactionHelper);
}
/**
@@ -178,7 +177,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
// ensure work is executed in transaction for each node processed
verify(mockedNodeService, times(2)).exists(any(NodeRef.class));
verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class),
Matchers.anyBoolean(), Matchers.anyBoolean());
anyBoolean(), anyBoolean());
// ensure each node is process correctly
verify(mockedNodeService, times(1)).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION);
@@ -186,7 +185,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
// ensure no more interactions
verifyNoMoreInteractions(mockedNodeService);
verifyZeroInteractions(mockedRecordsManagementActionService);
verifyNoMoreInteractions(mockedRecordsManagementActionService);
}
@@ -216,7 +215,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
// ensure no more interactions
verifyNoMoreInteractions(mockedNodeService);
verifyZeroInteractions(mockedRecordsManagementActionService);
verifyNoMoreInteractions(mockedRecordsManagementActionService);
}
/**
@@ -258,7 +257,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
// ensure work is executed in transaction for each node processed
verify(mockedNodeService, times(2)).exists(any(NodeRef.class));
verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class),
Matchers.anyBoolean(), Matchers.anyBoolean());
anyBoolean(), anyBoolean());
// ensure each node is process correctly
// node1
@@ -307,7 +306,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
// mock the search service to return the right page
when(mockedSearchService.query(any(SearchParameters.class))).thenAnswer((Answer<ResultSet>) invocation -> {
SearchParameters params = invocation.getArgumentAt(0, SearchParameters.class);
SearchParameters params = invocation.getArgument(0, SearchParameters.class);
if (params.getSkipCount() == 0)
{
// mock first page

View File

@@ -27,17 +27,15 @@
package org.alfresco.module.org_alfresco_module_rm.model.rma.aspect;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_HELD_CHILDREN;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_RECORD;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_HELD_CHILDREN_COUNT;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
@@ -51,24 +49,22 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.context.ApplicationContext;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Test class for frozen aspect
* @author Ross Gale
* @since 3.2
*/
@RunWith(MockitoJUnitRunner.class)
public class FrozenAspectUnitTest
{
@Mock
private NodeService mockNodeService;
@Mock
private ApplicationContext mockApplicationContext;
@Mock
private ChildAssociationRef mockChildAssociationRef;
@@ -90,9 +86,6 @@ public class FrozenAspectUnitTest
@Mock
private ChildAssociationRef mockOldRef;
@Mock
private Set mockSet;
@Mock
private PropertyModificationAllowedCheck mockPropertyModificationAllowedCheck;
@@ -110,18 +103,17 @@ public class FrozenAspectUnitTest
@Before
public void setUp()
{
MockitoAnnotations.initMocks(this);
when(mockNodeService.exists(record)).thenReturn(true);
when(mockNodeService.getType(record)).thenReturn(ContentModel.TYPE_CONTENT);
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(record), ContentModel.TYPE_CONTENT)).thenReturn(true);
when(mockNodeService.exists(content)).thenReturn(true);
when(mockNodeService.hasAspect(folder, ASPECT_HELD_CHILDREN)).thenReturn(true);
when(mockNodeService.getProperty(folder, PROP_HELD_CHILDREN_COUNT)).thenReturn(1);
when(mockApplicationContext.getBean("dbNodeService")).thenReturn(mockNodeService);
when(mockFreezeService.isFrozen(content)).thenReturn(false);
children.add(mockChildRef);
when(mockNodeService.getChildAssocs(content)).thenReturn(children);
when(mockChildRef.isPrimary()).thenReturn(true);
frozenAspect.setNodeService(mockNodeService);
}
/**
@@ -142,7 +134,6 @@ public class FrozenAspectUnitTest
@Test
public void testRemoveAspectForContent()
{
when(mockNodeService.hasAspect(content, ASPECT_RECORD)).thenReturn(false);
when(mockNodeService.getType(content)).thenReturn(ContentModel.TYPE_CONTENT);
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(content), ContentModel.TYPE_CONTENT)).thenReturn(true);
when(mockNodeService.getPrimaryParent(content)).thenReturn(mockChildAssociationRef);
@@ -157,7 +148,6 @@ public class FrozenAspectUnitTest
@Test
public void testRemoveAspectForContentDoesntUpdateForOtherTypes()
{
when(mockNodeService.hasAspect(content, ASPECT_RECORD)).thenReturn(false);
when(mockNodeService.getType(content)).thenReturn(ContentModel.TYPE_FOLDER);
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(content), ContentModel.TYPE_CONTENT)).thenReturn(false);
frozenAspect.onRemoveAspect(content, null);
@@ -233,7 +223,6 @@ public class FrozenAspectUnitTest
@Test(expected = PermissionDeniedException.class)
public void testBeforeMoveThrowsExceptionForFrozenNode()
{
when(mockOldRef.getParentRef()).thenReturn(parent);
when(mockOldRef.getChildRef()).thenReturn(child);
when(mockNodeService.exists(child)).thenReturn(true);
when(mockFreezeService.isFrozen(child)).thenReturn(true);
@@ -247,8 +236,6 @@ public class FrozenAspectUnitTest
public void testUpdatePropertiesThrowsExceptionForFrozenNode()
{
when(mockFreezeService.isFrozen(content)).thenReturn(true);
when(mockResourceHelper.getSet(content)).thenReturn(mockSet);
when(mockSet.contains("frozen")).thenReturn(false);
when(mockPropertyModificationAllowedCheck.check(null, null)).thenReturn(false);
frozenAspect.onUpdateProperties(content, null, null);
}

View File

@@ -33,7 +33,6 @@ import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagement
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
@@ -43,14 +42,17 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Unit tests for the {@link RecordAspect}.
*
* @author Claudia Agache
*/
@RunWith(MockitoJUnitRunner.class)
public class RecordAspectUnitTest
{
private static final NodeRef NODE_REF = new NodeRef("node://Ref/");
@@ -72,7 +74,7 @@ public class RecordAspectUnitTest
@Before
public void setUp()
{
initMocks(this);
recordAspect.setNodeService(mockNodeService);
}
/** Check that the bin is duplicated before adding the aspect if the file has a copy. */

View File

@@ -45,13 +45,15 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
/**
* @author silviudinuta
*/
@RunWith(MockitoJUnitRunner.class)
public class NonElectronicRecordTypeUnitTest implements RecordsManagementModel, ContentModel
{
private final static NodeRef CHILD_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
@@ -74,17 +76,15 @@ public class NonElectronicRecordTypeUnitTest implements RecordsManagementModel,
@Before
public void setUp()
{
MockitoAnnotations.initMocks(this);
MockAuthenticationUtilHelper.setup(mockAuthenticationUtil);
when(mockedNodeService.exists(CHILD_NODE_REF)).thenReturn(true);
when(mockedNodeService.exists(PARENT_NODE_REF)).thenReturn(true);
ChildAssociationRef generateChildAssociationRef = mock(ChildAssociationRef.class);
when(generateChildAssociationRef.getParentRef()).thenReturn(PARENT_NODE_REF);
when(generateChildAssociationRef.getChildRef()).thenReturn(CHILD_NODE_REF);
when(mockedNodeService.getPrimaryParent(CHILD_NODE_REF)).thenReturn(generateChildAssociationRef);
when(mockedNodeService.getType(PARENT_NODE_REF)).thenReturn(TYPE_UNFILED_RECORD_FOLDER);
nonElectronicRecordType.setNodeService(mockedNodeService);
}
@Test

View File

@@ -27,6 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.script.hold;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
@@ -71,8 +72,8 @@ public abstract class BaseHoldWebScriptUnitTest extends BaseWebScriptUnitTest
// generate active content
dmNodeRef = generateNodeRef(TYPE_CONTENT);
when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED);
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true);
lenient().when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED);
lenient().when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true);
// list of active contents
activeContents = Collections.singletonList(dmNodeRef);

View File

@@ -37,9 +37,12 @@ import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
/**
@@ -48,6 +51,7 @@ import org.springframework.extensions.webscripts.DeclarativeWebScript;
* @author Roy Wetherall
* @since 2.2
*/
@RunWith(MockitoJUnitRunner.class)
public class HoldPutUnitTest extends BaseHoldWebScriptWithContentUnitTest
{
/** classpath location of ftl template for web script */
@@ -77,6 +81,12 @@ public class HoldPutUnitTest extends BaseHoldWebScriptWithContentUnitTest
/**
* Test that a record can be removed from holds.
*/
@Before
public void setUp(){
webScript.setHoldService(mockedHoldService);
}
@SuppressWarnings("unchecked")
@Test
public void removeRecordFromHolds() throws Exception

View File

@@ -34,11 +34,12 @@ import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anySet;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -75,10 +76,11 @@ import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
@@ -89,6 +91,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
* @author Roy Wetherall
* @since 2.5
*/
@RunWith(MockitoJUnitRunner.class)
public class ExtendedSecurityServiceImplUnitTest
{
/** service mocks*/
@@ -145,9 +148,6 @@ public class ExtendedSecurityServiceImplUnitTest
@SuppressWarnings("unchecked")
@Before public void before()
{
// initialise mocks
MockitoAnnotations.initMocks(this);
// setup node
nodeRef = AlfMock.generateNodeRef(mockedNodeService);
@@ -157,7 +157,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(filePlan);
// set-up application context
when(mockedApplicationContext.getBean("dbNodeService"))
lenient().when(mockedApplicationContext.getBean("dbNodeService"))
.thenReturn(mockedNodeService);
// setup retrying transaction helper
@@ -199,6 +199,7 @@ public class ExtendedSecurityServiceImplUnitTest
.forEach((a) ->
when(mockedAuthorityService.authorityExists(a))
.thenReturn(true));
extendedSecurityService.setNodeService(mockedNodeService);
}
/**
@@ -481,7 +482,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(mockedWritePagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream
@@ -560,7 +561,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(mockedWritePagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream
@@ -651,7 +652,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(mockedWritePagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream

View File

@@ -27,8 +27,9 @@
package org.alfresco.module.org_alfresco_module_rm.test.util;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import java.util.UUID;
@@ -119,7 +120,7 @@ public class AlfMock
public static NodeRef generateNodeRef(NodeService mockedNodeService, QName type, boolean exists)
{
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
lenient().when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
if (type != null)
{
when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);

View File

@@ -28,10 +28,10 @@
package org.alfresco.module.org_alfresco_module_rm.test.util;
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -168,7 +168,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
MockitoAnnotations.initMocks(this);
// setup application context
doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService");
lenient().doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService");
// setup retrying transaction helper
Answer<Object> doInTransactionAnswer = new Answer<Object>()
@@ -181,7 +181,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
return callback.execute();
}
};
doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object>doInTransaction(any(RetryingTransactionCallback.class));
lenient().doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object>doInTransaction(any(RetryingTransactionCallback.class));
// setup mocked authentication util
MockAuthenticationUtilHelper.setup(mockedAuthenticationUtil);
@@ -189,15 +189,15 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
// setup file plan
filePlan = generateNodeRef(TYPE_FILE_PLAN);
setupAsFilePlanComponent(filePlan);
doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan);
lenient().doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan);
// setup basic file plan component
filePlanComponent = generateNodeRef();
setupAsFilePlanComponent(filePlanComponent);
// setup namespace service
doReturn(RM_URI).when(mockedNamespaceService).getNamespaceURI(RM_PREFIX);
doReturn(CollectionUtils.unmodifiableSet(RM_PREFIX)).when(mockedNamespaceService).getPrefixes(RM_URI);
lenient().doReturn(RM_URI).when(mockedNamespaceService).getNamespaceURI(RM_PREFIX);
lenient().doReturn(CollectionUtils.unmodifiableSet(RM_PREFIX)).when(mockedNamespaceService).getPrefixes(RM_URI);
// setup record folder and record
recordFolder = generateRecordFolder();
@@ -206,10 +206,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
// set record as child of record folder
List<ChildAssociationRef> result = new ArrayList<>(1);
result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, recordFolder, generateQName(RM_URI), record, true, 1));
doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
doReturn(result).when(mockedNodeService).getParentAssocs(record);
doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
lenient().doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
lenient().doReturn(result).when(mockedNodeService).getParentAssocs(record);
lenient().doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
lenient().doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
}
/**
@@ -221,7 +221,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
protected NodeRef generateHoldNodeRef(String name)
{
NodeRef hold = generateNodeRef(TYPE_HOLD);
doReturn(name).when(mockedNodeService).getProperty(hold, ContentModel.PROP_NAME);
lenient().doReturn(name).when(mockedNodeService).getProperty(hold, ContentModel.PROP_NAME);
doReturn(true).when(mockedHoldService).isHold(hold);
return hold;
}
@@ -235,7 +235,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
{
NodeRef recordFolder = generateNodeRef(TYPE_RECORD_FOLDER);
setupAsFilePlanComponent(recordFolder);
doReturn(true).when(mockedRecordFolderService).isRecordFolder(recordFolder);
lenient().doReturn(true).when(mockedRecordFolderService).isRecordFolder(recordFolder);
return recordFolder;
}
@@ -248,8 +248,8 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
{
NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT);
setupAsFilePlanComponent(record);
doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD);
doReturn(true).when(mockedRecordService).isRecord(record);
lenient().doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD);
lenient().doReturn(true).when(mockedRecordService).isRecord(record);
return record;
}
@@ -260,10 +260,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
*/
protected void setupAsFilePlanComponent(NodeRef nodeRef)
{
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT);
doReturn(true).when(mockedFilePlanService).isFilePlanComponent(nodeRef);
doReturn(filePlan).when(mockedFilePlanService).getFilePlan(nodeRef);
doReturn(filePlan).when(mockedNodeService).getProperty(nodeRef, PROP_ROOT_NODEREF);
lenient().doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT);
lenient().doReturn(true).when(mockedFilePlanService).isFilePlanComponent(nodeRef);
lenient().doReturn(filePlan).when(mockedFilePlanService).getFilePlan(nodeRef);
lenient().doReturn(filePlan).when(mockedNodeService).getProperty(nodeRef, PROP_ROOT_NODEREF);
}
/**
@@ -297,7 +297,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
protected NodeRef generateCmContent(String name)
{
NodeRef nodeRef = generateNodeRef(ContentModel.TYPE_CONTENT, true);
doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
lenient().doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
return nodeRef;
}
@@ -312,11 +312,11 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
protected NodeRef generateNodeRef(QName type, boolean exists)
{
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
lenient().when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
if (type != null)
{
when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
when(mockedNodeTypeUtility.instanceOf(type, type)).thenReturn(true);
lenient().when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
lenient().when(mockedNodeTypeUtility.instanceOf(type, type)).thenReturn(true);
}
return nodeRef;
}
@@ -334,7 +334,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
if (parent != null)
{
doReturn(parent).when(mockedChildAssociationRef).getParentRef();
lenient().doReturn(parent).when(mockedChildAssociationRef).getParentRef();
}
if (child != null)

View File

@@ -29,10 +29,12 @@ package org.alfresco.module.org_alfresco_module_rm.test.util;
import static java.util.Collections.emptyMap;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -179,19 +181,19 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
org.springframework.extensions.webscripts.Runtime mockedRuntime = mock(org.springframework.extensions.webscripts.Runtime.class);
WebScriptRequest mockedRequest = mock(WebScriptRequest.class);
doReturn(match).when(mockedRequest).getServiceMatch();
doReturn(mockedRuntime).when(mockedRequest).getRuntime();
lenient().doReturn(match).when(mockedRequest).getServiceMatch();
lenient().doReturn(mockedRuntime).when(mockedRequest).getRuntime();
if (content != null && !content.isEmpty())
{
Content mockedContent = mock(Content.class);
doReturn(content).when(mockedContent).getContent();
doReturn(mockedContent).when(mockedRequest).getContent();
lenient().doReturn(content).when(mockedContent).getContent();
lenient().doReturn(mockedContent).when(mockedRequest).getContent();
}
String [] paramNames = (String[])parameters.keySet().toArray(new String[parameters.size()]);
doReturn(paramNames).when(mockedRequest).getParameterNames();
doAnswer(new Answer()
lenient().doReturn(paramNames).when(mockedRequest).getParameterNames();
lenient().doAnswer(new Answer()
{
@Override
public Object answer(InvocationOnMock invocation) throws Throwable
@@ -201,9 +203,9 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
}
}).when(mockedRequest).getParameter(anyString());
doReturn(new String[0]).when(mockedRequest).getHeaderNames();
doReturn("json").when(mockedRequest).getFormat();
lenient().doReturn(new String[0]).when(mockedRequest).getHeaderNames();
lenient().doReturn("json").when(mockedRequest).getFormat();
return mockedRequest;
}
@@ -217,7 +219,7 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
{
WebScriptResponse mockedResponse = mock(WebScriptResponse.class);
StringWriter writer = new StringWriter();
doReturn(writer).when(mockedResponse).getWriter();
lenient().doReturn(writer).when(mockedResponse).getWriter();
return mockedResponse;
}
@@ -230,13 +232,13 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
protected Container getMockedContainer(String template) throws Exception
{
FormatRegistry mockedFormatRegistry = mock(FormatRegistry.class);
doReturn("application/json").when(mockedFormatRegistry).getMimeType(anyString(), anyString());
lenient().doReturn("application/json").when(mockedFormatRegistry).getMimeType(nullable(String.class), nullable(String.class));
ScriptProcessorRegistry mockedScriptProcessorRegistry = mock(ScriptProcessorRegistry.class);
doReturn(null).when(mockedScriptProcessorRegistry).findValidScriptPath(anyString());
lenient().doReturn(null).when(mockedScriptProcessorRegistry).findValidScriptPath(anyString());
TemplateProcessorRegistry mockedTemplateProcessorRegistry = mock(TemplateProcessorRegistry.class);
doReturn(template).when(mockedTemplateProcessorRegistry).findValidTemplatePath(anyString());
lenient().doReturn(template).when(mockedTemplateProcessorRegistry).findValidTemplatePath(anyString());
FTLTemplateProcessor ftlTemplateProcessor = new FTLTemplateProcessor()
{
@@ -248,25 +250,25 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
};
ftlTemplateProcessor.init();
doReturn(ftlTemplateProcessor).when(mockedTemplateProcessorRegistry).getTemplateProcessor(anyString());
lenient().doReturn(ftlTemplateProcessor).when(mockedTemplateProcessorRegistry).getTemplateProcessor(anyString());
Container mockedContainer = mock(Container.class);
doReturn(mockedFormatRegistry).when(mockedContainer).getFormatRegistry();
doReturn(mockedScriptProcessorRegistry).when(mockedContainer).getScriptProcessorRegistry();
doReturn(mockedTemplateProcessorRegistry).when(mockedContainer).getTemplateProcessorRegistry();
lenient().doReturn(mockedFormatRegistry).when(mockedContainer).getFormatRegistry();
lenient().doReturn(mockedScriptProcessorRegistry).when(mockedContainer).getScriptProcessorRegistry();
lenient().doReturn(mockedTemplateProcessorRegistry).when(mockedContainer).getTemplateProcessorRegistry();
Map<String, Object> containerTemplateParameters = new HashMap<>(5);
containerTemplateParameters.put("jsonUtils", new JSONUtils());
containerTemplateParameters.put("people", getMockedPeopleObject());
doReturn(containerTemplateParameters).when(mockedContainer).getTemplateParameters();
lenient().doReturn(containerTemplateParameters).when(mockedContainer).getTemplateParameters();
SearchPath mockedSearchPath = mock(SearchPath.class);
doReturn(false).when(mockedSearchPath).hasDocument(anyString());
doReturn(mockedSearchPath).when(mockedContainer).getSearchPath();
lenient().doReturn(false).when(mockedSearchPath).hasDocument(anyString());
lenient().doReturn(mockedSearchPath).when(mockedContainer).getSearchPath();
// setup description
Description mockDescription = mock(Description.class);
doReturn(mock(RequiredCache.class)).when(mockDescription).getRequiredCache();
lenient().doReturn(mock(RequiredCache.class)).when(mockDescription).getRequiredCache();
return mockedContainer;
}

View File

@@ -27,11 +27,10 @@
package org.alfresco.module.org_alfresco_module_rm.test.util;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
@@ -74,7 +73,7 @@ public class MockAuthenticationUtilHelper
reset(mockAuthenticationUtil);
// just do the work
doAnswer(new Answer<Object>()
lenient().doAnswer(new Answer<Object>()
{
@SuppressWarnings("rawtypes")
@Override
@@ -87,7 +86,7 @@ public class MockAuthenticationUtilHelper
}).when(mockAuthenticationUtil).<Object> runAsSystem(any(RunAsWork.class));
// just do the work
doAnswer(new Answer<Object>()
lenient().doAnswer(new Answer<Object>()
{
@SuppressWarnings("rawtypes")
@Override
@@ -99,10 +98,10 @@ public class MockAuthenticationUtilHelper
}).when(mockAuthenticationUtil).<Object> runAs(any(RunAsWork.class), anyString());
when(mockAuthenticationUtil.getAdminUserName()).thenReturn(ADMIN_USER);
when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn(fullyAuthenticatedUser);
when(mockAuthenticationUtil.getRunAsUser()).thenReturn(fullyAuthenticatedUser);
when(mockAuthenticationUtil.getSystemUserName()).thenReturn(SYSTEM_USER);
when(mockAuthenticationUtil.getGuestUserName()).thenReturn(GUEST_USER);
lenient().when(mockAuthenticationUtil.getAdminUserName()).thenReturn(ADMIN_USER);
lenient().when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn(fullyAuthenticatedUser);
lenient().when(mockAuthenticationUtil.getRunAsUser()).thenReturn(fullyAuthenticatedUser);
lenient().when(mockAuthenticationUtil.getSystemUserName()).thenReturn(SYSTEM_USER);
lenient().when(mockAuthenticationUtil.getGuestUserName()).thenReturn(GUEST_USER);
}
}

View File

@@ -87,6 +87,7 @@ public class ContentBinDuplicationUtilityUnitTest
public void setUp()
{
MockitoAnnotations.initMocks(this);
contentBinDuplicationUtility.setNodeService(mockNodeService);
}
/**

View File

@@ -29,10 +29,11 @@ package org.alfresco.module.org_alfresco_module_rm.version;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -52,7 +53,6 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.repo.version.Version2Model;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.repo.version.common.VersionImpl;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -61,9 +61,11 @@ import org.alfresco.service.cmr.version.VersionType;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Recordable version service implementation unit test.
@@ -71,6 +73,7 @@ import org.mockito.Spy;
* @author Roy Wetherall
* @since 2.3
*/
@RunWith(MockitoJUnitRunner.class)
public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
{
/** versioned content name */
@@ -108,34 +111,23 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
recordableVersionService.initialise();
doReturn(generateChildAssociationRef(null, generateNodeRef(Version2Model.TYPE_QNAME_VERSION_HISTORY)))
.when(mockedDbNodeService).createNode(any(NodeRef.class),
any(QName.class),
any(QName.class),
.when(mockedDbNodeService).createNode(nullable(NodeRef.class),
nullable(QName.class),
nullable(QName.class),
eq(Version2Model.TYPE_QNAME_VERSION_HISTORY),
anyMap());
doReturn(generateChildAssociationRef(null, generateNodeRef(TYPE_CONTENT)))
.when(mockedDbNodeService).createNode(any(NodeRef.class),
any(QName.class),
any(QName.class),
eq(TYPE_CONTENT),
anyMap());
nullable(Map.class));
doReturn(filePlan).when(mockedFilePlanService).getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
doReturn(unfiledRecordContainer).when(mockedFilePlanService).getUnfiledContainer(any(NodeRef.class));
record = generateCmContent(CONTENT_NAME);
FileInfo mockedFileInfo = mock(FileInfo.class);
doReturn(record).when(mockedFileInfo).getNodeRef();
doReturn(mockedFileInfo).when(mockedFileFolderService).copy(any(NodeRef.class),
any(NodeRef.class),
any(String.class));
version = generateNodeRef(TYPE_CONTENT);
doReturn(generateChildAssociationRef(null, version)).when(mockedDbNodeService).createNode(
any(NodeRef.class),
nullable(NodeRef.class),
eq(Version2Model.CHILD_QNAME_VERSIONS),
any(QName.class),
nullable(QName.class),
eq(TYPE_CONTENT),
anyMap());
nullable(Map.class));
recordableVersionService.setDbNodeService(mockedDbNodeService);
}
/**
@@ -167,7 +159,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
{
// setup given conditions
doReturn(false).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
doReturn(null).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
// when version is created
@@ -357,7 +348,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
public void filePlanSpecifiedNoPolicy() throws Exception
{
// setup given conditions
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
@@ -376,7 +366,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
public void adHocRecordedVersionNoPolicy() throws Exception
{
// setup given conditions
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
@@ -391,8 +380,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
public void adHocRecordedVersionOverridePolicy() throws Exception
{
// setup given conditions
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
@@ -461,16 +448,15 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
// latest version is not recorded
Version mockedVersion = mock(VersionImpl.class);
NodeRef versionNodeRef = generateNodeRef();
doReturn(Collections.emptyMap()).when(mockedVersion).getVersionProperties();
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE);
// version history
NodeRef versionHistoryNodeRef = generateNodeRef();
doReturn(versionHistoryNodeRef).when(mockedDbNodeService).getChildByName(any(NodeRef.class), eq(Version2Model.CHILD_QNAME_VERSION_HISTORIES), any(String.class));
doReturn(versionHistoryNodeRef).when(mockedDbNodeService).getChildByName(nullable(NodeRef.class), eq(Version2Model.CHILD_QNAME_VERSION_HISTORIES), nullable(String.class));
// version number
doReturn(mockedVersion).when(recordableVersionService).getCurrentVersion(nodeRef);
doReturn(versionNodeRef).when(recordableVersionService).convertNodeRef(any(NodeRef.class));
doReturn(versionNodeRef).when(recordableVersionService).convertNodeRef(nullable(NodeRef.class));
makePrimaryParentOf(versionNodeRef, versionHistoryNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "something-0"), mockedDbNodeService);
// created version
@@ -478,36 +464,36 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
doReturn(generateChildAssociationRef(versionHistoryNodeRef, newVersionNodeRef)).when(mockedDbNodeService).createNode(
eq(versionHistoryNodeRef),
eq(Version2Model.CHILD_QNAME_VERSIONS),
any(QName.class),
any(QName.class),
any(Map.class));
nullable(QName.class),
nullable(QName.class),
nullable(Map.class));
// created record
NodeRef newRecordNodeRef = generateNodeRef();
doReturn(newRecordNodeRef).when(mockedRecordService).createRecordFromContent(
eq(filePlan),
any(String.class),
any(QName.class),
any(Map.class),
any(ContentReader.class));
eq(filePlan),
nullable(String.class),
nullable(QName.class),
nullable(Map.class),
nullable(ContentReader.class));
// create record from version
recordableVersionService.createRecordFromLatestVersion(filePlan, nodeRef);
// verify that the version is converted to a recorded version
verify(mockedRecordService, times(1)).createRecordFromContent(
eq(filePlan),
any(String.class),
any(QName.class),
any(Map.class),
any(ContentReader.class));
eq(filePlan),
nullable(String.class),
nullable(QName.class),
any(Map.class),
nullable(ContentReader.class));
verify(mockedDbNodeService, times(1)).deleteNode(any(NodeRef.class));
verify(mockedDbNodeService, times(1)).createNode(
eq(versionHistoryNodeRef),
eq(Version2Model.CHILD_QNAME_VERSIONS),
any(QName.class),
any(QName.class),
any(Map.class));
nullable(QName.class),
nullable(QName.class),
nullable(Map.class));
verify(mockedNodeService, times(1)).addAspect(eq(newVersionNodeRef), eq(Version2Model.ASPECT_VERSION), any(Map.class));
verify(mockedNodeService, times(1)).addAspect(
newVersionNodeRef,
@@ -605,20 +591,13 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
// set up version
Version mockedVersion = mock(VersionImpl.class);
NodeRef versionNodeRef = generateNodeRef();
NodeRef versionRecordNodeRef = generateNodeRef();
when(mockedVersion.getFrozenStateNodeRef())
.thenReturn(versionNodeRef);
when(mockedDbNodeService.exists(versionRecordNodeRef))
.thenReturn(true);
// indicate that the version doesn't have the aspect
when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
.thenReturn(true);
// indicate that the associated version record exists
when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
.thenReturn(versionRecordNodeRef);
// mark as destroyed
recordableVersionService.destroyRecordedVersion(mockedVersion);
@@ -643,20 +622,13 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
// set up version
Version mockedVersion = mock(VersionImpl.class);
NodeRef versionNodeRef = generateNodeRef();
NodeRef versionRecordNodeRef = generateNodeRef();
when(mockedVersion.getFrozenStateNodeRef())
.thenReturn(versionNodeRef);
when(mockedDbNodeService.exists(versionRecordNodeRef))
.thenReturn(false);
// indicate that the version doesn't have the aspect
when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
.thenReturn(true);
// indicate that the associated version record exists
when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
.thenReturn(versionRecordNodeRef);
// mark as destroyed
recordableVersionService.destroyRecordedVersion(mockedVersion);

View File

@@ -33,10 +33,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -562,7 +563,7 @@ public class DynamicAuthoritiesGetUnitTest extends BaseWebScriptUnitTest impleme
executeWebScript(parameters);
verify(contentStreamer, times(1)).streamContent(any(WebScriptRequest.class), any(WebScriptResponse.class),
csvFileCaptor.capture(), any(Long.class), any(Boolean.class), any(String.class), any(Map.class));
csvFileCaptor.capture(), nullable(Long.class), any(Boolean.class), any(String.class), any(Map.class));
File fileForDownload = csvFileCaptor.getValue();
assertNotNull(fileForDownload);

View File

@@ -28,8 +28,9 @@
package org.alfresco.rm.rest.api.impl;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -41,7 +42,6 @@ import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.api.impl.SiteImportPackageHandler;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.model.SiteUpdate;
@@ -59,10 +59,11 @@ import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Unit Test class for RMSitesImpl.
@@ -71,6 +72,7 @@ import org.mockito.MockitoAnnotations;
* @since 2.6
*
*/
@RunWith(MockitoJUnitRunner.class)
public class RMSitesImplUnitTest extends BaseUnitTest
{
private static final String RM_SITE_TITLE_AFTER_UPDATE = "Updated Title";
@@ -86,8 +88,6 @@ public class RMSitesImplUnitTest extends BaseUnitTest
@Mock
private SiteService mockedSiteService;
@Mock
AuthenticationUtil mockAuthenticationUtil;
@Mock
private ImporterService mockedImporterService;
@Mock
private FavouritesService mockedFavouritesService;
@@ -95,7 +95,6 @@ public class RMSitesImplUnitTest extends BaseUnitTest
@Before
public void before()
{
MockitoAnnotations.initMocks(this);
}
@Test
@@ -138,7 +137,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
verify(mockedImporterService, times(1)).importView(any(SiteImportPackageHandler.class), any(Location.class), any(ImporterBinding.class), eq(null));
verify(mockedSiteService, times(1)).createContainer(RM_SITE_ID, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
verify(mockedFavouritesService, times(1)).addFavourite(any(String.class), any(NodeRef.class));
verify(mockedFavouritesService, times(1)).addFavourite(nullable(String.class), any(NodeRef.class));
//verify returned values for RM site are the right ones
assertEquals(RMSiteCompliance.STANDARD, createdRMSite.getCompliance());
@@ -191,7 +190,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
verify(mockedImporterService, times(1)).importView(any(SiteImportPackageHandler.class), any(Location.class), any(ImporterBinding.class), eq(null));
verify(mockedSiteService, times(1)).createContainer(RM_SITE_ID, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
verify(mockedFavouritesService, times(1)).addFavourite(any(String.class), any(NodeRef.class));
verify(mockedFavouritesService, times(1)).addFavourite(nullable(String.class), any(NodeRef.class));
//verify returned values for RM site are the right ones
assertEquals(RMSiteCompliance.DOD5015, createdRMSite.getCompliance());
@@ -253,13 +252,12 @@ public class RMSitesImplUnitTest extends BaseUnitTest
when(mockedNodeService.getType(siteNodeRef)).thenReturn(RecordsManagementModel.TYPE_RM_SITE);
when(mockedSiteService.getSite(siteId)).thenReturn(mockedSiteInfo);
when(mockedSiteService.getMembersRole(eq(siteId), any(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
when(mockedSiteService.getMembersRole(eq(siteId), nullable(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
//mock UpdateSite
SiteUpdate mockedSiteUpdate= mock(SiteUpdate.class);
when(mockedSiteUpdate.getDescription()).thenReturn(RM_SITE_DESCRIPTION_AFTER_UPDATE);
when(mockedSiteUpdate.getTitle()).thenReturn(RM_SITE_TITLE_AFTER_UPDATE);
when(mockedSiteUpdate.getVisibility()).thenReturn(null);
when(mockedSiteUpdate.wasSet(Site.TITLE)).thenReturn(true);
when(mockedSiteUpdate.wasSet(Site.DESCRIPTION)).thenReturn(true);
@@ -309,7 +307,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
when(mockedNodeService.getType(siteNodeRef)).thenReturn(RecordsManagementModel.TYPE_RM_SITE);
when(mockedSiteService.getSite(siteId)).thenReturn(mockedSiteInfo);
when(mockedSiteService.getMembersRole(eq(siteId), any(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
when(mockedSiteService.getMembersRole(eq(siteId), nullable(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
//STANDARD compliance
RMSite rmSite = rmSitesImpl.getRMSite(siteId);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,6 +26,7 @@
package org.alfresco.repo.content;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ContentAccessor;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -33,6 +34,9 @@ import org.alfresco.service.cmr.repository.ContentStreamListener;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.DirectAccessUrl;
import java.util.Collections;
import java.util.Map;
/**
* Provides low-level retrieval of content
@@ -269,9 +273,25 @@ public interface ContentStore
* @return A direct access {@code URL} object for the content
* @throws UnsupportedOperationException if the store is unable to provide the information
*/
@Deprecated
default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName)
{
return requestContentDirectUrl(contentUrl, attachment, fileName, null);
return requestContentDirectUrl(contentUrl, attachment, fileName, null, null);
}
/**
* Gets a presigned URL to directly access the content. It is up to the actual store
* implementation if it can fulfil this request with an expiry time or not.
*
* @param contentUrl A content store {@code URL}
* @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}.
* @param fileName File name of the content
* @return A direct access {@code URL} object for the content
* @throws UnsupportedOperationException if the store is unable to provide the information
*/
default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype)
{
return requestContentDirectUrl(contentUrl, attachment, fileName, mimetype, null);
}
/**
@@ -285,9 +305,43 @@ public interface ContentStore
* @return A direct access {@code URL} object for the content.
* @throws UnsupportedOperationException if the store is unable to provide the information
*/
@Deprecated
default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, Long validFor)
{
return requestContentDirectUrl(contentUrl, attachment, fileName, null, validFor);
}
/**
* Gets a presigned URL to directly access the content. It is up to the actual store
* implementation if it can fulfil this request with an expiry time or not.
*
* @param contentUrl A content store {@code URL}
* @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}.
* @param fileName File name of the content
* @param mimetype Mimetype of the content
* @param validFor The time at which the direct access {@code URL} will expire.
* @return A direct access {@code URL} object for the content.
* @throws UnsupportedOperationException if the store is unable to provide the information
*/
default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype, Long validFor)
{
throw new UnsupportedOperationException(
"Retrieving direct access URLs is not supported by this content store.");
}
/**
* Gets a key-value (String-String) collection of storage headers/properties with their respective values.
* A particular Cloud Connector will fill in that data with Cloud Storage Provider generic data.
* Map may be also filled in with entries consisting of pre-defined Alfresco keys of {@code ObjectStorageProps} and their values.
* If empty Map is returned - no connector is present or connector is not supporting retrieval of the properties
* or cannot determine the properties.
*
* @param contentUrl the URL of the content for which the storage properties are to be retrieved.
* @return Returns a key-value (String-String) collection of storage headers/properties with their respective values.
*/
@Experimental
default Map<String, String> getStorageProperties(String contentUrl)
{
return Collections.emptyMap();
}
}

View File

@@ -0,0 +1,64 @@
/*
* #%L
* Alfresco Data model classes
* %%
* Copyright (C) 2005 - 2021 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.content;
import org.alfresco.service.Experimental;
/**
* Enumeration with "header" values for Alfresco derived Storage Properties
* Values of this enum should be used when adding Alfresco derived key-value pairs in Storage Properties map.
* Subject to expand/change.
*
* @author mpichura
*/
@Experimental
public enum ObjectStorageProps {
/**
* Object's content is archived and not immediately accessible.
*/
X_ALF_ARCHIVED("x-alf-archived"),
/**
* Object's content retrieval from archive is in progress
*/
X_ALF_ARCHIVE_RESTORE_IN_PROGRESS("x-alf-archive-restore-in-progress"),
/**
* Expiry date and time of object's content retrieved from archive.
* Use YYYYMMDDThhmmssZ (ISO-8601) datetime format when using this value as key in Storage Properties map.
*/
X_ALF_ARCHIVE_RESTORE_EXPIRY("x-alf-archive-restore-expiry");
ObjectStorageProps(String value) {
this.value = value;
}
private final String value;
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,55 @@
/*
* #%L
* Alfresco Data model classes
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.service;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to mark a type/method/field as experimental.
* <p>
* If this annotation is present on an element it marks it as experimental and subject to change without further notice.
* The element may even be deleted or renamed without any notice.
* Experimental element may likely become a valid one (not experimental anymore) in future releases but there is no guarantee when
* and if that happens.
*
* @author mpichura
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface Experimental {
/**
* Further description that can optionally be added to clarify possible future changes of annotated object.
*
* @return a String, the default is an empty String.
*/
String description() default "";
}

View File

@@ -0,0 +1,53 @@
/*
* #%L
* Alfresco Data model classes
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.service.cmr.repository;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.Experimental;
/**
* Unable to access as content is in an Archived state.
* Default status is <i>Precondition Failed<i> Client Error = 412
*
* @author David Edwards
*/
@Experimental
@AlfrescoPublicApi
public class ArchivedIOException extends ContentIOException
{
private static final long serialVersionUID = 3258135874596276087L;
public ArchivedIOException(String msg)
{
super(msg);
}
public ArchivedIOException(String msg, Throwable cause)
{
super(msg, cause);
}
}

112
mmt/pom.xml Normal file
View File

@@ -0,0 +1,112 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-mmt</artifactId>
<name>Alfresco Module Management Tool</name>
<packaging>jar</packaging>
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>14.35</version>
</parent>
<dependencies>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-repository</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>de.schlichtherle.truezip</groupId>
<artifactId>truezip-driver-zip</artifactId>
<version>${dependency.truezip.version}</version>
</dependency>
<dependency>
<groupId>de.schlichtherle.truezip</groupId>
<artifactId>truezip-file</artifactId>
<version>${dependency.truezip.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${dependency.maven-artifact.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>make-mmt</id>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.alfresco.repo.module.tool.ModuleManagementTool</Main-Class>
</manifestEntries>
</transformer>
</transformers>
<artifactSet>
<includes>
<include>de.schlichtherle.truezip:*</include>
<include>org.alfresco:alfresco-core</include>
<include>org.alfresco:alfresco-repository</include>
<include>org.apache.commons:commons-compress</include>
<include>org.safehaus.jug:jug</include>
<include>org.alfresco.surf:spring-surf-core</include>
<include>org.tukaani:xz</include>
<include>org.apache.maven:maven-artifact</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>org.alfresco:alfresco-core</artifact>
<includes>
<include>org/alfresco/error/AlfrescoRuntimeException.class</include>
<include>org/alfresco/util/Pair.class</include>
<include>org/alfresco/util/EqualsHelper.class</include>
<include>org/alfresco/util/VersionNumber.class</include>
</includes>
</filter>
<filter>
<artifact>org.apache.maven:maven-artifact</artifact>
<includes>
<include>org/apache/maven/artifact/versioning/**/*.class</include>
</includes>
</filter>
<filter>
<artifact>org.alfresco:alfresco-repository</artifact>
<includes>
<include>org/alfresco/repo/module/tool/default-file-mapping.properties</include>
<include>org/alfresco/repo/module/**/*.class</include>
<include>org/alfresco/service/cmr/module/**/*.class</include>
</includes>
</filter>
<filter>
<artifact>org.alfresco.surf:spring-surf-core</artifact>
<includes>
<include>org/springframework/extensions/surf/util/I18NUtil.class</include>
<include>org/springframework/extensions/surf/util/ISO8601DateFormat.class</include>
<include>org/springframework/extensions/surf/exception/PlatformRuntimeException.class</include>
</includes>
</filter>
<filter>
<!-- Duplicated file in truezip-driver-file, need to filter this one -->
<artifact>de.schlichtherle.truezip:truezip-driver-zip</artifact>
<excludes>
<exclude>META-INF/services/de.schlichtherle.truezip.fs.spi.FsDriverService</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
<properties>
@@ -71,6 +71,7 @@
<groupId>org.alfresco</groupId>
<artifactId>alfresco-mmt</artifactId>
<type>jar</type>
<version>${project.version}</version>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alfresco-mmt</outputDirectory>
</artifactItem>

View File

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

View File

@@ -1,4 +1,4 @@
TRANSFORMERS_TAG=2.5.3
TRANSFORMERS_TAG=2.5.4
SOLR6_TAG=2.0.2
POSTGRES_TAG=13.3
ACTIVEMQ_TAG=5.16.1

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
<developers>
@@ -93,7 +93,7 @@
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.5.0</version>
<version>${dependency.jakarta-json-path.version}</version>
</dependency>
</dependencies>

View File

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

View File

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

View File

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

59
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -17,13 +17,14 @@
<module>data-model</module>
<module>repository</module>
<module>remote-api</module>
<module>mmt</module>
<module>packaging</module>
<module>amps</module>
</modules>
<properties>
<acs.version.major>7</acs.version.major>
<acs.version.minor>1</acs.version.minor>
<acs.version.minor>2</acs.version.minor>
<acs.version.revision>0</acs.version.revision>
<acs.version.label />
<amp.min.version>${acs.version.major}.0.0</amp.min.version>
@@ -43,7 +44,6 @@
<dir.root>${project.build.directory}/alf_data</dir.root>
<dependency.alfresco-hb-data-sender.version>1.0.12</dependency.alfresco-hb-data-sender.version>
<dependency.alfresco-mmt.version>6.0</dependency.alfresco-mmt.version>
<dependency.alfresco-trashcan-cleaner.version>2.4.1</dependency.alfresco-trashcan-cleaner.version>
<dependency.alfresco-jlan.version>7.1</dependency.alfresco-jlan.version>
<dependency.alfresco-server-root.version>6.0.1</dependency.alfresco-server-root.version>
@@ -51,20 +51,19 @@
<dependency.alfresco-log-sanitizer.version>0.2</dependency.alfresco-log-sanitizer.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-model.version>1.4.0</dependency.alfresco-transform-model.version>
<dependency.alfresco-transform-model.version>1.4.3</dependency.alfresco-transform-model.version>
<dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.13</dependency.acs-event-model.version>
<dependency.spring.version>5.3.9</dependency.spring.version>
<dependency.spring.version>5.3.10</dependency.spring.version>
<dependency.antlr.version>3.5.2</dependency.antlr.version>
<dependency.jackson.version>2.12.3</dependency.jackson.version>
<dependency.jackson-databind.version>2.12.4</dependency.jackson-databind.version>
<dependency.cxf.version>3.4.4</dependency.cxf.version>
<dependency.cxf.version>3.4.5</dependency.cxf.version>
<dependency.opencmis.version>1.0.0</dependency.opencmis.version>
<dependency.webscripts.version>8.23</dependency.webscripts.version>
<dependency.webscripts.version>8.26</dependency.webscripts.version>
<dependency.bouncycastle.version>1.69</dependency.bouncycastle.version>
<dependency.mockito-core.version>3.11.2</dependency.mockito-core.version>
<dependency.mockito-all.version>1.10.19</dependency.mockito-all.version>
<dependency.org-json.version>20210307</dependency.org-json.version>
<dependency.commons-dbcp.version>1.4-DBCP330</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.11.0</dependency.commons-io.version>
@@ -73,15 +72,15 @@
<dependency.httpcore.version>4.4.14</dependency.httpcore.version>
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.1</dependency.xercesImpl.version>
<dependency.slf4j.version>1.7.30</dependency.slf4j.version>
<dependency.slf4j.version>1.7.32</dependency.slf4j.version>
<dependency.gytheio.version>0.12</dependency.gytheio.version>
<dependency.groovy.version>2.5.9</dependency.groovy.version>
<dependency.groovy.version>3.0.9</dependency.groovy.version>
<dependency.tika.version>1.27</dependency.tika.version>
<dependency.spring-security.version>5.5.1</dependency.spring-security.version>
<dependency.spring-security.version>5.5.2</dependency.spring-security.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>4.1.2</dependency.poi.version>
<dependency.ooxml-schemas.version>1.4</dependency.ooxml-schemas.version>
<dependency.keycloak.version>13.0.1</dependency.keycloak.version>
<dependency.keycloak.version>15.0.2</dependency.keycloak.version>
<dependency.jboss.logging.version>3.4.2.Final</dependency.jboss.logging.version>
<dependency.camel.version>3.7.4</dependency.camel.version>
<dependency.activemq.version>5.16.1</dependency.activemq.version>
@@ -91,6 +90,7 @@
<dependency.swagger-ui.version>3.38.0</dependency.swagger-ui.version>
<dependency.swagger-parser.version>1.0.52</dependency.swagger-parser.version>
<dependency.maven-filtering.version>3.1.1</dependency.maven-filtering.version>
<dependency.maven-artifact.version>3.8.3</dependency.maven-artifact.version>
<dependency.jakarta-jaxb-api.version>2.3.3</dependency.jakarta-jaxb-api.version>
<dependency.jakarta-ws-api.version>2.3.3</dependency.jakarta-ws-api.version>
@@ -101,6 +101,7 @@
<dependency.jakarta-jws-api.version>2.1.0</dependency.jakarta-jws-api.version>
<dependency.jakarta-mail-api.version>1.6.5</dependency.jakarta-mail-api.version>
<dependency.jakarta-json-api.version>1.1.6</dependency.jakarta-json-api.version>
<dependency.jakarta-json-path.version>2.5.0</dependency.jakarta-json-path.version>
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
<alfresco.googledrive.version>3.2.1.3</alfresco.googledrive.version>
@@ -108,14 +109,14 @@
<alfresco.api-explorer.version>7.1.0.1</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
<dependency.postgresql.version>42.2.20</dependency.postgresql.version>
<dependency.postgresql.version>42.2.24</dependency.postgresql.version>
<dependency.mysql.version>8.0.25</dependency.mysql.version>
<dependency.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.2</dependency.mariadb.version>
<dependency.tas-utility.version>3.0.45</dependency.tas-utility.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>3.0.47</dependency.tas-utility.version>
<dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
<dependency.tas-restapi.version>1.64</dependency.tas-restapi.version>
<dependency.tas-cmis.version>1.30</dependency.tas-cmis.version>
<dependency.tas-restapi.version>1.65</dependency.tas-restapi.version>
<dependency.tas-cmis.version>1.31</dependency.tas-cmis.version>
<dependency.tas-email.version>1.8</dependency.tas-email.version>
<dependency.tas-webdav.version>1.6</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.5</dependency.tas-ftp.version>
@@ -142,7 +143,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>HEAD</tag>
<tag>14.35</tag>
</scm>
<distributionManagement>
@@ -289,11 +290,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-mmt</artifactId>
<version>${dependency.alfresco-mmt.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-server-root</artifactId>
@@ -638,7 +634,7 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.2</version>
<version>1.14.3</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
@@ -711,7 +707,7 @@
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.10</version>
<version>2.10.12</version>
</dependency>
<!-- provided dependencies -->
@@ -733,11 +729,6 @@
<artifactId>gunit</artifactId>
<version>${dependency.antlr.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${dependency.mockito-all.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
@@ -850,7 +841,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -870,7 +861,7 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.34.1</version>
<version>0.37.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
@@ -886,12 +877,12 @@
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
<dependencies>
@@ -47,7 +47,7 @@
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>1.5.8</version>
<version>2.2.3</version>
</dependency>
<!-- newer version, see REPO-3133 -->
<dependency>

View File

@@ -27,17 +27,14 @@ package org.alfresco.opencmis;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -48,19 +45,17 @@ import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.opencmis.CMISDispatcherRegistry.Endpoint;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.rest.framework.core.exceptions.JsonpCallbackNotAllowedException;
import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.descriptor.DescriptorService;
import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
@@ -69,7 +64,6 @@ import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
import org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
/**
* Dispatches OpenCMIS requests to a servlet e.g. the OpenCMIS AtomPub servlet.
@@ -90,6 +84,8 @@ public abstract class CMISServletDispatcher implements CMISDispatcher
protected CmisVersion cmisVersion;
protected TenantAdminService tenantAdminService;
private boolean allowUnsecureCallbackJSONP;
private Set<String> nonAttachContentTypes = Collections.emptySet(); // pre-configured whitelist, eg. images & pdf
public void setTenantAdminService(TenantAdminService tenantAdminService)
@@ -151,7 +147,17 @@ public abstract class CMISServletDispatcher implements CMISDispatcher
return this.currentDescriptor;
}
public void setAllowUnsecureCallbackJSONP(boolean allowUnsecureCallbackJSONP)
{
this.allowUnsecureCallbackJSONP = allowUnsecureCallbackJSONP;
}
public boolean isAllowUnsecureCallbackJSONP()
{
return allowUnsecureCallbackJSONP;
}
public void init()
{
Endpoint endpoint = new Endpoint(getBinding(), version);
@@ -219,12 +225,22 @@ public abstract class CMISServletDispatcher implements CMISDispatcher
CMISHttpServletResponse httpResWrapper = getHttpResponse(res);
CMISHttpServletRequest httpReqWrapper = getHttpRequest(req);
servlet.service(httpReqWrapper, httpResWrapper);
// check for "callback" query param
if (!allowUnsecureCallbackJSONP && httpReqWrapper.getParameter("callback") != null)
{
throw new JsonpCallbackNotAllowedException();
}
servlet.service(httpReqWrapper, httpResWrapper);
}
catch(ServletException e)
{
throw new AlfrescoRuntimeException("", e);
}
catch (JsonpCallbackNotAllowedException e)
{
res.setStatus(403);
res.getWriter().append(e.getMessage());
}
}
/**

View File

@@ -30,8 +30,19 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.function.Function;
import java.util.function.Supplier;
import com.google.common.primitives.Ints;
import org.alfresco.repo.bulkimport.BulkFilesystemImporter;
import org.alfresco.repo.bulkimport.BulkImportParameters;
import org.alfresco.repo.bulkimport.NodeImporter;
import org.alfresco.repo.bulkimport.impl.MultiThreadedBulkFilesystemImporter;
import org.alfresco.repo.model.Repository;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
@@ -39,8 +50,12 @@ import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* contains common fields and methods for the import web scripts.
@@ -60,10 +75,10 @@ public class AbstractBulkFileSystemImportWebScript extends DeclarativeWebScript
// Web scripts parameters (common)
protected static final String PARAMETER_REPLACE_EXISTING = "replaceExisting";
protected static final String PARAMETER_EXISTING_FILE_MODE = "existingFileMode";
protected static final String PARAMETER_VALUE_REPLACE_EXISTING = "replaceExisting";
protected static final String PARAMETER_VALUE_REPLACE_EXISTING = "true";
protected static final String PARAMETER_SOURCE_DIRECTORY = "sourceDirectory";
protected static final String PARAMETER_DISABLE_RULES = "disableRules";
protected static final String PARAMETER_VALUE_DISABLE_RULES = "disableRules";
protected static final String PARAMETER_VALUE_DISABLE_RULES = "true";
protected static final String IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY = "importInProgress";
protected static final String IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY ="bfsit.error.importAlreadyInProgress";
@@ -75,7 +90,7 @@ public class AbstractBulkFileSystemImportWebScript extends DeclarativeWebScript
protected Repository repository;
protected volatile boolean importInProgress;
protected NodeRef getTargetNodeRef(String targetNodeRefStr, String targetPath) throws FileNotFoundException
{
NodeRef targetNodeRef;
@@ -219,4 +234,198 @@ public class AbstractBulkFileSystemImportWebScript extends DeclarativeWebScript
this.repository = repository;
}
protected class MultithreadedImportWebScriptLogic
{
private final MultiThreadedBulkFilesystemImporter bulkImporter;
private final Supplier<NodeImporter> nodeImporterFactory;
private final WebScriptRequest request;
private final Status status;
private final Cache cache;
public MultithreadedImportWebScriptLogic(MultiThreadedBulkFilesystemImporter bulkImporter, Supplier<NodeImporter> nodeImporterFactory, WebScriptRequest request, Status status, Cache cache)
{
this.bulkImporter = Objects.requireNonNull(bulkImporter);
this.nodeImporterFactory = Objects.requireNonNull(nodeImporterFactory);
this.request = Objects.requireNonNull(request);
this.status = Objects.requireNonNull(status);
this.cache = Objects.requireNonNull(cache);
}
public Map<String, Object> executeImport()
{
Map<String, Object> model = new HashMap<>();
cache.setNeverCache(true);
String targetPath = null;
try
{
targetPath = request.getParameter(PARAMETER_TARGET_PATH);
if (isRunning())
{
model.put(IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY, I18NUtil.getMessage(IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY));
return model;
}
final BulkImportParameters bulkImportParameters = getBulkImportParameters();
final NodeImporter nodeImporter = nodeImporterFactory.get();
bulkImporter.asyncBulkImport(bulkImportParameters, nodeImporter);
waitForImportToBegin();
// redirect to the status Web Script
status.setCode(Status.STATUS_MOVED_TEMPORARILY);
status.setRedirect(true);
status.setLocation(request.getServiceContextPath() + WEB_SCRIPT_URI_BULK_FILESYSTEM_IMPORT_STATUS);
}
catch (WebScriptException | IllegalArgumentException e)
{
status.setCode(Status.STATUS_BAD_REQUEST, e.getMessage());
status.setRedirect(true);
}
catch (FileNotFoundException fnfe)
{
status.setCode(Status.STATUS_BAD_REQUEST,"The repository path '" + targetPath + "' does not exist !");
status.setRedirect(true);
}
catch (Throwable t)
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, buildTextMessage(t), t);
}
return model;
}
private void waitForImportToBegin() throws InterruptedException
{
// ACE-3047 fix, since bulk import is started asynchronously there is a chance that client
// will get into the status page before import is actually started.
// In this case wrong information (for previous import) will be displayed.
// So lets ensure that import started before redirecting client to status page.
int i = 0;
while (!bulkImporter.getStatus().inProgress() && i < 10)
{
Thread.sleep(100);
i++;
}
}
private BulkImportParameters getBulkImportParameters() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = new BulkImportParametersExtractor(request::getParameter,
AbstractBulkFileSystemImportWebScript.this::getTargetNodeRef,
bulkImporter.getDefaultBatchSize(),
bulkImporter.getDefaultNumThreads());
return extractor.extract();
}
private boolean isRunning()
{
return bulkImporter.getStatus().inProgress();
}
}
protected static class BulkImportParametersExtractor
{
private final Function<String, String> paramsProvider;
private final NodeRefCreator nodeRefCreator;
private final int defaultBatchSize;
private final int defaultNumThreads;
public BulkImportParametersExtractor(final Function<String, String> paramsProvider, final NodeRefCreator nodeRefCreator,
final int defaultBatchSize, final int defaultNumThreads)
{
this.paramsProvider = Objects.requireNonNull(paramsProvider);
this.nodeRefCreator = Objects.requireNonNull(nodeRefCreator);
this.defaultBatchSize = defaultBatchSize;
this.defaultNumThreads = defaultNumThreads;
}
public BulkImportParameters extract() throws FileNotFoundException
{
BulkImportParameters result = new BulkImportParameters();
result.setTarget(getTargetNodeRef());
setExistingFileMode(result);
result.setNumThreads(getOptionalPositiveInteger(PARAMETER_NUM_THREADS).orElse(defaultNumThreads));
result.setBatchSize(getOptionalPositiveInteger(PARAMETER_BATCH_SIZE).orElse(defaultBatchSize));
setDisableRules(result);
return result;
}
private void setExistingFileMode(BulkImportParameters params)
{
String replaceExistingStr = getParamStringValue(PARAMETER_REPLACE_EXISTING);
String existingFileModeStr = getParamStringValue(PARAMETER_EXISTING_FILE_MODE);
if (!isNullOrEmpty(replaceExistingStr) && !isNullOrEmpty(existingFileModeStr))
{
// Check that we haven't had both the deprecated and new (existingFileMode)
// parameters supplied.
throw new IllegalStateException(
String.format("Only one of these parameters may be used, not both: %s, %s",
PARAMETER_REPLACE_EXISTING,
PARAMETER_EXISTING_FILE_MODE));
}
if (!isNullOrEmpty(existingFileModeStr))
{
params.setExistingFileMode(BulkImportParameters.ExistingFileMode.valueOf(existingFileModeStr));
}
else
{
params.setReplaceExisting(PARAMETER_VALUE_REPLACE_EXISTING.equals(replaceExistingStr));
}
}
private void setDisableRules(final BulkImportParameters params)
{
final String disableRulesStr = getParamStringValue(PARAMETER_DISABLE_RULES);
params.setDisableRulesService(!isNullOrEmpty(disableRulesStr) && PARAMETER_VALUE_DISABLE_RULES.equals(disableRulesStr));
}
private NodeRef getTargetNodeRef() throws FileNotFoundException
{
String targetNodeRefStr = getParamStringValue(PARAMETER_TARGET_NODEREF);
String targetPath = getParamStringValue(PARAMETER_TARGET_PATH);
return nodeRefCreator.fromNodeRefAndPath(targetNodeRefStr, targetPath);
}
private OptionalInt getOptionalPositiveInteger(final String paramName)
{
final String strValue = getParamStringValue(paramName);
if (isNullOrEmpty(strValue))
{
return OptionalInt.empty();
}
final Integer asInt = Ints.tryParse(strValue);
if (asInt == null || asInt < 1)
{
throw new WebScriptException("Error: parameter '" + paramName + "' must be an integer > 0.");
}
return OptionalInt.of(asInt);
}
private String getParamStringValue(String paramName)
{
Objects.requireNonNull(paramName);
return paramsProvider.apply(paramName);
}
private boolean isNullOrEmpty(String str)
{
return str == null || str.trim().length() == 0;
}
@FunctionalInterface
protected interface NodeRefCreator
{
NodeRef fromNodeRefAndPath(String nodeRef, String path) throws FileNotFoundException;
}
}
}

View File

@@ -27,17 +27,12 @@
package org.alfresco.repo.web.scripts.bulkimport.copy;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.bulkimport.BulkImportParameters;
import org.alfresco.repo.bulkimport.NodeImporter;
import org.alfresco.repo.bulkimport.impl.MultiThreadedBulkFilesystemImporter;
import org.alfresco.repo.bulkimport.impl.StreamingNodeImporterFactory;
import org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
@@ -69,170 +64,22 @@ public class BulkFilesystemImportWebScript extends AbstractBulkFileSystemImportW
@Override
protected Map<String, Object> executeImpl(final WebScriptRequest request, final Status status, final Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
String targetNodeRefStr = null;
String targetPath = null;
String sourceDirectoryStr = null;
@Deprecated String replaceExistingStr = null;
String existingFileModeStr = null;
String batchSizeStr = null;
String numThreadsStr = null;
String disableRulesStr = null;
final MultithreadedImportWebScriptLogic importLogic = new MultithreadedImportWebScriptLogic(bulkImporter,
() -> createNodeImporter(request), request, status, cache);
return importLogic.executeImport();
}
cache.setNeverCache(true);
try
private NodeImporter createNodeImporter(WebScriptRequest request)
{
final String sourceDirectoryStr = request.getParameter(PARAMETER_SOURCE_DIRECTORY);
if (sourceDirectoryStr == null || sourceDirectoryStr.trim().length() == 0)
{
if(!bulkImporter.getStatus().inProgress())
{
NodeRef targetNodeRef = null;
File sourceDirectory = null;
boolean replaceExisting = false;
BulkImportParameters.ExistingFileMode existingFileMode = null;
int batchSize = bulkImporter.getDefaultBatchSize();
int numThreads = bulkImporter.getDefaultNumThreads();
boolean disableRules = false;
// Retrieve, validate and convert parameters
targetNodeRefStr = request.getParameter(PARAMETER_TARGET_NODEREF);
targetPath = request.getParameter(PARAMETER_TARGET_PATH);
sourceDirectoryStr = request.getParameter(PARAMETER_SOURCE_DIRECTORY);
replaceExistingStr = request.getParameter(PARAMETER_REPLACE_EXISTING);
existingFileModeStr = request.getParameter(PARAMETER_EXISTING_FILE_MODE);
batchSizeStr = request.getParameter(PARAMETER_BATCH_SIZE);
numThreadsStr = request.getParameter(PARAMETER_NUM_THREADS);
disableRulesStr = request.getParameter(PARAMETER_DISABLE_RULES);
targetNodeRef = getTargetNodeRef(targetNodeRefStr, targetPath);
if (sourceDirectoryStr == null || sourceDirectoryStr.trim().length() == 0)
{
throw new RuntimeException("Error: mandatory parameter '" + PARAMETER_SOURCE_DIRECTORY + "' was not provided.");
}
sourceDirectory = new File(sourceDirectoryStr.trim());
if (replaceExistingStr != null && existingFileModeStr != null)
{
// Check that we haven't had both the deprecated and new (existingFileMode)
// parameters supplied.
throw new IllegalStateException(
String.format("Only one of these parameters may be used, not both: %s, %s",
PARAMETER_REPLACE_EXISTING,
PARAMETER_EXISTING_FILE_MODE));
}
if (replaceExistingStr != null && replaceExistingStr.trim().length() > 0)
{
replaceExisting = PARAMETER_VALUE_REPLACE_EXISTING.equals(replaceExistingStr);
}
if (existingFileModeStr != null && existingFileModeStr.trim().length() > 0)
{
existingFileMode = BulkImportParameters.ExistingFileMode.valueOf(existingFileModeStr);
}
if (disableRulesStr != null && disableRulesStr.trim().length() > 0)
{
disableRules = PARAMETER_VALUE_DISABLE_RULES.equals(disableRulesStr);
}
// Initiate the import
NodeImporter nodeImporter = nodeImporterFactory.getNodeImporter(sourceDirectory);
BulkImportParameters bulkImportParameters = new BulkImportParameters();
if (numThreadsStr != null && numThreadsStr.trim().length() > 0)
{
try
{
numThreads = Integer.parseInt(numThreadsStr);
if(numThreads < 1)
{
throw new RuntimeException("Error: parameter '" + PARAMETER_NUM_THREADS + "' must be an integer > 0.");
}
bulkImportParameters.setNumThreads(numThreads);
}
catch(NumberFormatException e)
{
throw new RuntimeException("Error: parameter '" + PARAMETER_NUM_THREADS + "' must be an integer > 0.");
}
}
if (batchSizeStr != null && batchSizeStr.trim().length() > 0)
{
try
{
batchSize = Integer.parseInt(batchSizeStr);
if(batchSize < 1)
{
throw new RuntimeException("Error: parameter '" + PARAMETER_BATCH_SIZE + "' must be an integer > 0.");
}
bulkImportParameters.setBatchSize(batchSize);
}
catch(NumberFormatException e)
{
throw new RuntimeException("Error: parameter '" + PARAMETER_BATCH_SIZE + "' must be an integer > 0.");
}
}
if (existingFileMode != null)
{
bulkImportParameters.setExistingFileMode(existingFileMode);
}
else
{
// Fall back to the old/deprecated way.
bulkImportParameters.setReplaceExisting(replaceExisting);
}
bulkImportParameters.setTarget(targetNodeRef);
bulkImportParameters.setDisableRulesService(disableRules);
bulkImporter.asyncBulkImport(bulkImportParameters, nodeImporter);
// ACE-3047 fix, since bulk import is started asynchronously there is a chance that client
// will get into the status page before import is actually started.
// In this case wrong information (for previous import) will be displayed.
// So lets ensure that import started before redirecting client to status page.
int i = 0;
while (!bulkImporter.getStatus().inProgress() && i < 10)
{
Thread.sleep(100);
i++;
}
// redirect to the status Web Script
status.setCode(Status.STATUS_MOVED_TEMPORARILY);
status.setRedirect(true);
status.setLocation(request.getServiceContextPath() + WEB_SCRIPT_URI_BULK_FILESYSTEM_IMPORT_STATUS);
}
else
{
model.put(IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY, I18NUtil.getMessage(IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY));
}
throw new WebScriptException("Error: mandatory parameter '" + PARAMETER_SOURCE_DIRECTORY + "' was not provided.");
}
catch (WebScriptException wse)
{
status.setCode(Status.STATUS_BAD_REQUEST, wse.getMessage());
status.setRedirect(true);
}
catch (FileNotFoundException fnfe)
{
status.setCode(Status.STATUS_BAD_REQUEST,"The repository path '" + targetPath + "' does not exist !");
status.setRedirect(true);
}
catch(IllegalArgumentException iae)
{
status.setCode(Status.STATUS_BAD_REQUEST,iae.getMessage());
status.setRedirect(true);
}
catch (Throwable t)
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, buildTextMessage(t), t);
}
return model;
final File sourceDirectory = new File(sourceDirectoryStr.trim());
return nodeImporterFactory.getNodeImporter(sourceDirectory);
}
}

View File

@@ -44,6 +44,7 @@ import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.sync.repo.events.EventPublisher;
import org.alfresco.repo.web.util.HttpRangeProcessor;
import org.alfresco.rest.framework.resource.content.CacheDirective;
import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
@@ -449,7 +450,11 @@ public class ContentStreamer implements ResourceLoaderAware
if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tcontent: " + reader);
}
catch (ContentIOException e2)
catch (ArchivedIOException e2)
{
throw e2;
}
catch (ContentIOException e3)
{
if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tcontent: " + reader);

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.quickshare;
import java.util.HashMap;
@@ -31,10 +31,12 @@ import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.QuickShareModel;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.service.cmr.quickshare.InvalidSharedIdException;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
@@ -82,14 +84,15 @@ public class UnshareContentDelete extends AbstractQuickShareContent
try
{
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
String networkTenantDomain = pair.getFirst();
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
TenantUtil.runAsSystemTenant(() ->
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
}
quickShareService.unshareContent(sharedId);
checkIfCanDeleteSharedLink(sharedId);
quickShareService.unshareContent(sharedId);
return null;
}, networkTenantDomain);
Map<String, Object> model = new HashMap<>(1);
model.put("success", Boolean.TRUE);
@@ -106,4 +109,14 @@ public class UnshareContentDelete extends AbstractQuickShareContent
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find: " + sharedId);
}
}
private void checkIfCanDeleteSharedLink(String sharedId) {
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
}
}
}

View File

@@ -274,15 +274,15 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
try
{
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
String networkTenantDomain = pair.getFirst();
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
TenantUtil.runAsSystemTenant(() ->
{
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
}
quickShareService.unshareContent(sharedId);
checkIfCanDeleteSharedLink(sharedId);
quickShareService.unshareContent(sharedId);
return null;
}, networkTenantDomain);
}
catch (InvalidSharedIdException ex)
{
@@ -698,4 +698,14 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
throw new InvalidArgumentException("A valid recipientEmail must be specified.");
}
}
private void checkIfCanDeleteSharedLink(String sharedId) {
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
{
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
}
}
}

View File

@@ -23,8 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.probes;
import org.alfresco.repo.admin.RepoHealthChecker;
import org.alfresco.rest.api.discovery.DiscoveryApiWebscript;
import org.alfresco.rest.api.model.Probe;
import org.alfresco.rest.framework.WebApiDescription;
@@ -35,29 +37,26 @@ import org.alfresco.rest.framework.core.exceptions.ServiceUnavailableException;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An implementation of an Entity Resource for Probes.
*/
@EntityResource(name="probes", title = "Probes")
public class ProbeEntityResource implements EntityResourceAction.ReadById<Probe>
@EntityResource(name = "probes", title = "Probes") public class ProbeEntityResource
implements EntityResourceAction.ReadById<Probe>
{
public static final String LIVE = "-live-";
public static final String READY = "-ready-";
public static final long CHECK_PERIOD = 10 * 1000; // Maximum of only one checkResult every 10 seconds.
protected static Log logger = LogFactory.getLog(ProbeEntityResource.class);;
private long nextCheckTime = 0;
private final static Logger logger = LoggerFactory.getLogger(ProbeEntityResource.class);
private final Object lock = new Object();
private final Probe liveProbe = new Probe("liveProbe: Success - Tested");
private long lastCheckTime = 0;
private Boolean checkResult;
private Boolean checking = false;
private boolean readySent;
private DiscoveryApiWebscript discovery;
private RepoHealthChecker repoHealthChecker;
public DiscoveryApiWebscript setDiscovery(DiscoveryApiWebscript discovery)
{
DiscoveryApiWebscript result = this.discovery;
@@ -65,145 +64,141 @@ public class ProbeEntityResource implements EntityResourceAction.ReadById<Probe>
return result;
}
public void setRepoHealthChecker(RepoHealthChecker repoHealthChecker)
{
this.repoHealthChecker = repoHealthChecker;
}
/**
* Returns a status code of 200 for okay. The probe contains little information for security reasons.
*
* Note: does *not* require authenticated access, so limits the amount of work performed to avoid a DDOS.
*/
@Override
@WebApiDescription(title="Get probe status", description = "Returns 200 if valid")
@WebApiParam(name = "probeName", title = "The probe's name")
@WebApiNoAuth
public Probe readById(String name, Parameters parameters)
@Override @WebApiDescription(title = "Get probe status", description = "Returns 200 if valid") @WebApiParam(name = "probeName", title = "The probe's name") @WebApiNoAuth public Probe readById(
String name, Parameters parameters)
{
boolean isLiveProbe = LIVE.equalsIgnoreCase(name);
if (!isLiveProbe && !READY.equalsIgnoreCase(name))
ProbeType probeType = ProbeType.fromString(name);
Probe probeResponse = null;
switch (probeType)
{
throw new InvalidArgumentException("Bad probe name");
case LIVE:
probeResponse = liveProbe;
break;
case READY:
String message = doReadyCheck();
probeResponse = new Probe(message);
break;
case UNKNOWN:
throw new InvalidArgumentException("Bad probe name");
}
String message = doCheckOrNothing(isLiveProbe);
return new Probe(message);
return probeResponse;
}
// We don't want to be doing checks all the time or holding monitors for a long time to avoid a DDOS.
public String doCheckOrNothing(boolean isLiveProbe)
public String doReadyCheck()
{
boolean doCheck = false;
long now = 0;
boolean result;
String message = "No test";
boolean logInfo = false;
synchronized(checking)
synchronized (lock)
{
// Initially ready needs to be false so we don't get requests and live true so the pod is not killed.
if (checkResult == null)
String message;
long now = System.currentTimeMillis();
if (checkResult == null || isAfterCheckPeriod(now))
{
result = isLiveProbe;
try
{
performReadinessCheck();
checkResult = true;
}
catch (Exception e)
{
checkResult = false;
logger.debug("Exception during readiness check", e);
}
finally
{
setLastCheckTime(now);
message = getMessage(checkResult, "Tested");
logger.info(message);
}
}
else
{
result = checkResult;
// if no check is performed, use previous check result
message = getMessage(checkResult, "No test");
logger.debug(message);
}
if (checkResult)
{
return message;
}
if (checking) // Is another thread is checking?
{
if (!readySent && result && !isLiveProbe)
{
readySent = true;
logInfo = true;
}
}
else // This thread will do a check
{
now = System.currentTimeMillis();
if (checkResult == null || nextCheckTime <= now)
{
doCheck = true;
checking = true;
}
}
throw new ServiceUnavailableException(message);
}
if (doCheck)
{
try
{
message = "Tested";
doCheck(isLiveProbe);
result = true;
}
catch (Exception e)
{
result = false;
}
finally
{
synchronized (checking)
{
checking = false;
checkResult = result;
setNextCheckTime(now);
if (result && !readySent && !isLiveProbe) // Are we initially ready
{
readySent = true;
logInfo = true;
}
else if (!result && (isLiveProbe || readySent)) // Are we sick
{
logInfo = true;
}
}
}
}
message = getMessage(isLiveProbe, result, message);
if (logInfo)
{
logger.info(message);
}
else
{
logger.debug(message);
}
if (result)
{
return message;
}
throw new ServiceUnavailableException(message);
}
private String getMessage(boolean isLiveProbe, boolean result, String message)
private String getMessage(boolean result, String message)
{
return (isLiveProbe ? "liveProbe" : "readyProbe")+": "+
(result ? "Success" : "Failure") +
" - "+message;
return "readyProbe: " + (result ? "Success" : "Failure") + " - " + message;
}
private void doCheck(boolean isLiveProbe)
private void performReadinessCheck()
{
discovery.getRepositoryInfo();
repoHealthChecker.checkDatabase();
logger.debug("All checks complete");
}
private void setNextCheckTime(long now)
private void setLastCheckTime(long time)
{
long oldValue = nextCheckTime;
if (nextCheckTime == 0)
this.lastCheckTime = time;
long nextCheckTime = lastCheckTime + CHECK_PERIOD;
logger.trace("nextCheckTime: {} (+{} secs)", nextCheckTime, ((CHECK_PERIOD) / 1000));
}
private boolean isAfterCheckPeriod(long currentTime)
{
return ((currentTime - lastCheckTime) >= CHECK_PERIOD);
}
public enum ProbeType
{
LIVE("-live-"), READY("-ready-"), UNKNOWN("");
String value;
ProbeType(String strValue)
{
nextCheckTime = (now / 60000) * 60000;
value = strValue;
}
do
public static ProbeType fromString(String text)
{
nextCheckTime += CHECK_PERIOD;
for (ProbeType p : ProbeType.values())
{
if (p.value.equalsIgnoreCase(text))
{
return p;
}
}
return UNKNOWN;
}
while (nextCheckTime <= now);
if (logger.isTraceEnabled())
public String getValue()
{
logger.trace("nextCheckTime: " + nextCheckTime + " (+" + ((nextCheckTime - oldValue) / 1000) + " secs)");
return value;
}
}
}

View File

@@ -78,6 +78,7 @@ import org.alfresco.rest.api.search.model.SearchSQLQuery;
import org.alfresco.rest.api.search.model.TupleEntry;
import org.alfresco.rest.api.search.model.TupleList;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Params;
@@ -152,7 +153,7 @@ public class ResultMapper
* Turns the results into a CollectionWithPagingInfo
* @param params
* @param searchQuery
*@param results @return CollectionWithPagingInfo<Node>
* @param results @return CollectionWithPagingInfo<Node>
*/
public CollectionWithPagingInfo<Node> toCollectionWithPagingInfo(Params params, SearchRequestContext searchRequestContext, SearchQuery searchQuery, ResultSet results)
{
@@ -205,61 +206,69 @@ public class ResultMapper
* @param params
* @param mapUserInfo
* @param isHistory
* @return Node
* @return The node object or null if the user does not have permission to view it.
*/
public Node getNode(ResultSetRow aRow, Params params, Map<String, UserInfo> mapUserInfo, boolean isHistory)
{
String nodeStore = storeMapper.getStore(aRow.getNodeRef());
if (isHistory) nodeStore = HISTORY;
String nodeStore = isHistory ? HISTORY : storeMapper.getStore(aRow.getNodeRef());
Node aNode = null;
switch (nodeStore)
try
{
case LIVE_NODES:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break;
case HISTORY:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break;
case VERSIONS:
Map<QName, Serializable> properties = serviceRegistry.getNodeService().getProperties(aRow.getNodeRef());
NodeRef frozenNodeRef = ((NodeRef) properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF));
String versionLabelId = (String) properties.get(Version2Model.PROP_QNAME_VERSION_LABEL);
Version v = null;
try
{
if (frozenNodeRef != null && versionLabelId != null)
switch (nodeStore)
{
case LIVE_NODES:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break;
case HISTORY:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break;
case VERSIONS:
Map<QName, Serializable> properties = serviceRegistry.getNodeService().getProperties(aRow.getNodeRef());
NodeRef frozenNodeRef = ((NodeRef) properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF));
String versionLabelId = (String) properties.get(Version2Model.PROP_QNAME_VERSION_LABEL);
Version v = null;
try
{
v = nodeVersions.findVersion(frozenNodeRef.getId(),versionLabelId);
aNode = nodes.getFolderOrDocument(v.getFrozenStateNodeRef(), null, null, params.getInclude(), mapUserInfo);
if (frozenNodeRef != null && versionLabelId != null)
{
v = nodeVersions.findVersion(frozenNodeRef.getId(), versionLabelId);
aNode = nodes.getFolderOrDocument(v.getFrozenStateNodeRef(), null, null, params.getInclude(), mapUserInfo);
}
}
}
catch (EntityNotFoundException|InvalidNodeRefException e)
{
//Solr says there is a node but we can't find it
logger.debug("Failed to find a versioned node with id of "+frozenNodeRef
catch (EntityNotFoundException | InvalidNodeRefException e)
{
//Solr says there is a node but we can't find it
logger.debug("Failed to find a versioned node with id of " + frozenNodeRef
+ " this is probably because the original node has been deleted.");
}
}
if (v != null && aNode != null)
{
nodeVersions.mapVersionInfo(v, aNode, aRow.getNodeRef());
aNode.setNodeId(frozenNodeRef.getId());
aNode.setVersionLabel(versionLabelId);
}
break;
case DELETED:
try
{
aNode = deletedNodes.getDeletedNode(aRow.getNodeRef().getId(), params, false, mapUserInfo);
}
catch (EntityNotFoundException enfe)
{
//Solr says there is a deleted node but we can't find it, we want the rest of the search to return so lets ignore it.
logger.debug("Failed to find a deleted node with id of "+aRow.getNodeRef().getId());
}
break;
if (v != null && aNode != null)
{
nodeVersions.mapVersionInfo(v, aNode, aRow.getNodeRef());
aNode.setNodeId(frozenNodeRef.getId());
aNode.setVersionLabel(versionLabelId);
}
break;
case DELETED:
try
{
aNode = deletedNodes.getDeletedNode(aRow.getNodeRef().getId(), params, false, mapUserInfo);
}
catch (EntityNotFoundException enfe)
{
//Solr says there is a deleted node but we can't find it, we want the rest of the search to return so lets ignore it.
logger.debug("Failed to find a deleted node with id of " + aRow.getNodeRef().getId());
}
break;
}
}
catch (PermissionDeniedException e)
{
logger.debug("Unable to access node: " + aRow.toString());
return null;
}
if (aNode != null)
{
aNode.setLocation(nodeStore);

View File

@@ -64,6 +64,18 @@ public class ApiException extends PlatformRuntimeException
super(msgId, cause);
this.msgId = msgId;
}
public ApiException(String msgId, String message)
{
super(message);
this.msgId = msgId;
}
public ApiException(String msgId, String message, Throwable cause)
{
super(message, cause);
this.msgId = msgId;
}
public ApiException(String msgId, Throwable cause, Map<String,Object> additionalState)
{

View File

@@ -0,0 +1,72 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.framework.core.exceptions;
import org.alfresco.service.Experimental;
/**
* Thrown when the content is archived and not readily accessible.
* Status is <i>Precondition Failed</i> client error = 412.
*
* @author David Edwards
*/
@Experimental
public class ArchivedContentException extends ApiException
{
public static String DEFAULT_MESSAGE_ID = "framework.exception.ArchivedContent";
public ArchivedContentException()
{
super(DEFAULT_MESSAGE_ID);
}
public ArchivedContentException(String message)
{
this(DEFAULT_MESSAGE_ID, message);
}
private ArchivedContentException(String msgId, String message)
{
super(msgId, message);
}
public ArchivedContentException(Throwable cause)
{
this(DEFAULT_MESSAGE_ID, cause.getLocalizedMessage(), cause);
}
public ArchivedContentException(String message, Throwable cause)
{
this(DEFAULT_MESSAGE_ID, message, cause);
}
private ArchivedContentException(String msgId, String message, Throwable cause)
{
super(msgId, message, cause);
}
}

View File

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

View File

@@ -42,6 +42,7 @@ import org.alfresco.rest.framework.core.ResourceLocator;
import org.alfresco.rest.framework.core.ResourceOperation;
import org.alfresco.rest.framework.core.ResourceWithMetadata;
import org.alfresco.rest.framework.core.exceptions.ApiException;
import org.alfresco.rest.framework.core.exceptions.ArchivedContentException;
import org.alfresco.rest.framework.resource.actions.ActionExecutor;
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
@@ -52,6 +53,8 @@ import org.alfresco.rest.framework.resource.content.FileBinaryResource;
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.alfresco.rest.framework.tools.ResponseWriter;
import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -84,6 +87,8 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
private ContentStreamer streamer;
protected ResourceWebScriptHelper helper;
private static final String HEADER_CONTENT_LENGTH = "Content-Length";
@SuppressWarnings("rawtypes")
@Override
public void execute(final Api api, final WebScriptRequest req, final WebScriptResponse res) throws IOException
@@ -173,6 +178,10 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
}
}
catch (ContentIOException cioe)
{
handleContentIOException(res, cioe);
}
catch (AlfrescoRuntimeException | ApiException | WebScriptException xception )
{
renderException(xception, res, assistant);
@@ -215,6 +224,20 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
return toReturn;
}
private void handleContentIOException(final WebScriptResponse res, ContentIOException exception) throws IOException
{
// If the Content-Length is not set back to -1 any client will expect to receive binary and will hang until it times out
res.setHeader(HEADER_CONTENT_LENGTH, String.valueOf(-1));
if (exception instanceof ArchivedIOException)
{
renderException(new ArchivedContentException(exception.getMsgId(), exception), res, assistant);
}
else
{
renderException(exception, res, assistant);
}
}
protected RetryingTransactionHelper getTransactionHelper(String api)
{
RetryingTransactionHelper transHelper = transactionService.getRetryingTransactionHelper();

View File

@@ -14,4 +14,6 @@ framework.exception.UnsupportedResourceOperation=The operation is unsupported
framework.exception.DeletedResource=In this version of the REST API resource {0} has been deleted
framework.exception.RequestEntityTooLarge=The file can't be uploaded because it's larger than the maximum upload size
framework.exception.InsufficientStorage=The file upload exceeds the content storage allowance
framework.exception.JsonpCallbackNotAllowed=For security reasons the callback parameter is not allowed
framework.no.stacktrace=For security reasons the stack trace is no longer displayed, but the property is kept for previous versions

View File

@@ -174,6 +174,7 @@
<entry key="org.springframework.http.InvalidMediaTypeException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_UNSUPPORTED_MEDIA_TYPE}" />
<entry key="org.alfresco.rest.framework.core.exceptions.ServiceUnavailableException" value="503" />
<entry key="org.alfresco.service.cmr.dictionary.InvalidTypeException" value="409" />
<entry key="org.alfresco.rest.framework.core.exceptions.ArchivedContentException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_PRECONDITION_FAILED}" />
</map>
</property>
</bean>
@@ -1070,11 +1071,12 @@
<property name="enabled" value="${system.api.discovery.enabled}" />
<property name="thumbnailService" ref="ThumbnailService" />
<property name="restApiDirectUrlConfig" ref="restApiDirectUrlConfig" />
<property name="contentService" ref="ContentService" />
<property name="contentService" ref="contentService" />
</bean>
<bean id="org.alfresco.rest.api.probes.ProbeEntityResource.get" class="org.alfresco.rest.api.probes.ProbeEntityResource">
<property name="discovery" ref="webscript.org.alfresco.api.DiscoveryApiWebscript.get" />
<property name="repoHealthChecker" ref="repoHealthChecker" />
</bean>
<!-- REST API direct access URL configuration settings -->
@@ -1138,6 +1140,7 @@
<property name="cmisVersion" value="1.1"/>
<property name="tenantAdminService" ref="tenantAdminService"/>
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
<property name="allowUnsecureCallbackJSONP" value="${allow.unsecure.callback.jsonp}"/>
</bean>
<bean id="webscript.org.alfresco.api.opencmis.OpenCMIS.get"

View File

@@ -33,7 +33,7 @@
<#elseif v?is_number>
${v?c}
<#elseif v?is_string>
"${v?string}"
"${v?html}"
<#elseif v?is_hash>
<#if v?keys?size gt maxDepth >
<#stop "Max depth of object achieved">
@@ -188,7 +188,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
</tr>
<#list result.children as n>
<tr>
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.QName}</a></td>
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.QName?html}</a></td>
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.childRef}</a></td>
<td>${n.primary?string}</td>
<td>${n.typeQName}</td>
@@ -222,7 +222,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
</tr>
<#list result.parents as p>
<tr>
<td>${p.name.prefixedName}</td>
<td>${p.name.prefixedName?html}</td>
<td>${p.parentTypeName.prefixedName}</td>
<td><a href="#" onclick="AdminConsole_parentClick('${p.parentRef}');return false;">${p.parentRef}</a></td></td>
<td>${p.primary?string}</td>
@@ -280,7 +280,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
<@section label=msg("nodebrowser.permissions") />
<table id="perminfo-table" class="node">
<tr><td>${msg("nodebrowser.inherits")}: ${result.permissions.inherit?string}</td></tr>
<tr><td>${msg("nodebrowser.owner")}: ${result.permissions.owner!""}</td></tr>
<tr><td>${msg("nodebrowser.owner")}: <#if result.permissions.owner??>${result.permissions.owner?html}</#if></td></tr>
</table>
<table id="permissions-table" class="node grid">
<tr>
@@ -291,7 +291,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
<#list result.permissions.entries as p>
<tr>
<td>${p.permission}</td>
<td>${p.authority}</td>
<td>${p.authority?html}</td>
<td>${p.accessStatus}</td>
</tr>
</#list>

View File

@@ -42,6 +42,7 @@ import org.junit.runners.Suite;
org.alfresco.rest.api.tests.TestPublicApiAtomPub10TCK.class,
org.alfresco.rest.api.tests.TestPublicApiAtomPub11TCK.class,
org.alfresco.rest.api.tests.TestPublicApiBrowser11TCK.class,
org.alfresco.repo.web.scripts.bulkimport.BulkImportParametersExtractorTest.class
})
public class AppContext01TestSuite
{

View File

@@ -0,0 +1,252 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2021 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.web.scripts.bulkimport;
import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_BATCH_SIZE;
import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_DISABLE_RULES;
import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_NUM_THREADS;
import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_TARGET_NODEREF;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Map;
import org.alfresco.repo.bulkimport.BulkImportParameters;
import org.alfresco.repo.bulkimport.BulkImportParameters.ExistingFileMode;
import org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.BulkImportParametersExtractor;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.junit.Test;
import org.springframework.extensions.webscripts.WebScriptException;
public class BulkImportParametersExtractorTest
{
private static final String TEST_NODE_REF = "workspace://SpacesStore/this-is-just-a-test-ref";
private static final String TEST_MISSING_NODE_REF = "workspace://SpacesStore/this-is-just-a-not-existing-test-ref";
private static final Integer DEFAULT_BATCH_SIZE = 1234;
private static final Integer DEFAULT_NUMBER_OF_THREADS = 4321;
@Test
public void shouldExtractTargetRef() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF));
final BulkImportParameters params = extractor.extract();
assertNotNull(params);
assertNotNull(params.getTarget());
assertEquals(TEST_NODE_REF, params.getTarget().toString());
}
@Test
public void shouldFallbackToDefaultValues() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF));
final BulkImportParameters params = extractor.extract();
assertEquals(DEFAULT_BATCH_SIZE, params.getBatchSize());
assertEquals(DEFAULT_NUMBER_OF_THREADS, params.getNumThreads());
assertFalse(params.isDisableRulesService());
assertEquals(ExistingFileMode.SKIP, params.getExistingFileMode());
assertNull(params.getLoggingInterval());
}
@Test
public void shouldExtractDisableFolderRulesFlagWhenSetToTrue() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_DISABLE_RULES, "true"
));
final BulkImportParameters params = extractor.extract();
assertTrue(params.isDisableRulesService());
}
@Test
public void shouldExtractDisableFolderRulesFlagWhenSetToFalse() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_DISABLE_RULES, "false"
));
final BulkImportParameters params = extractor.extract();
assertFalse(params.isDisableRulesService());
}
@Test
public void shouldExtractDisableFolderRulesFlagWhenSetToNotBooleanValue() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_DISABLE_RULES, "unknown"
));
final BulkImportParameters params = extractor.extract();
assertFalse(params.isDisableRulesService());
}
@Test
public void shouldPropagateFileNotFoundExceptionWhenTargetIsNotFound()
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_MISSING_NODE_REF));
assertThrows(FileNotFoundException.class, extractor::extract);
}
@Test
public void shouldExtractValidBatchSize() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_BATCH_SIZE, "1"));
final BulkImportParameters params = extractor.extract();
assertEquals(Integer.valueOf(1), params.getBatchSize());
}
@Test
public void shouldFailWithWebScriptExceptionWhenInvalidBatchSizeIsRequested() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_BATCH_SIZE, "not-a-number"));
try
{
extractor.extract();
} catch (WebScriptException e)
{
assertNotNull(e.getMessage());
assertTrue(e.getMessage().contains(PARAMETER_BATCH_SIZE));
return;
}
fail("Expected exception to be thrown.");
}
@Test
public void shouldFailWithWebScriptExceptionWhenNegativeBatchSizeIsRequested() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_BATCH_SIZE, "-1"));
try
{
extractor.extract();
} catch (WebScriptException e)
{
assertNotNull(e.getMessage());
assertTrue(e.getMessage().contains(PARAMETER_BATCH_SIZE));
return;
}
fail("Expected exception to be thrown.");
}
@Test
public void shouldExtractValidNumberOfThreads() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_NUM_THREADS, "1"));
final BulkImportParameters params = extractor.extract();
assertEquals(Integer.valueOf(1), params.getNumThreads());
}
@Test
public void shouldFailWithWebScriptExceptionWhenInvalidNumberOfThreadsIsRequested() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_NUM_THREADS, "not-a-number"));
try
{
extractor.extract();
} catch (WebScriptException e)
{
assertNotNull(e.getMessage());
assertTrue(e.getMessage().contains(PARAMETER_NUM_THREADS));
return;
}
fail("Expected exception to be thrown.");
}
@Test
public void shouldFailWithWebScriptExceptionWhenNegativeNumberOfThreadsIsRequested() throws FileNotFoundException
{
final BulkImportParametersExtractor extractor = givenExtractor(Map.of(
PARAMETER_TARGET_NODEREF, TEST_NODE_REF,
PARAMETER_NUM_THREADS, "-1"));
try
{
extractor.extract();
} catch (WebScriptException e)
{
assertNotNull(e.getMessage());
assertTrue(e.getMessage().contains(PARAMETER_NUM_THREADS));
return;
}
fail("Expected exception to be thrown.");
}
private BulkImportParametersExtractor givenExtractor(Map<String, String> params)
{
return new BulkImportParametersExtractor(params::get, this::testRefCreator, DEFAULT_BATCH_SIZE, DEFAULT_NUMBER_OF_THREADS);
}
private NodeRef testRefCreator(String nodeRef, String path) throws FileNotFoundException
{
if (TEST_MISSING_NODE_REF.equals(nodeRef))
{
throw new FileNotFoundException(new NodeRef(nodeRef));
}
return new NodeRef(nodeRef);
}
}

View File

@@ -37,7 +37,6 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.PropertyMap;
import org.alfresco.util.testing.category.FrequentlyFailingTests;
import org.alfresco.util.testing.category.IntermittentlyFailingTests;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;

View File

@@ -25,24 +25,27 @@
*/
package org.alfresco.rest.api.search;
import static java.util.Arrays.asList;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.notNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -85,6 +88,7 @@ import org.alfresco.rest.api.search.model.SearchQuery;
import org.alfresco.rest.api.search.model.SearchSQLQuery;
import org.alfresco.rest.api.search.model.TupleList;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.Params;
@@ -96,6 +100,7 @@ import org.alfresco.service.cmr.search.FieldHighlightParameters;
import org.alfresco.service.cmr.search.GeneralHighlightParameters;
import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionHistory;
@@ -103,14 +108,11 @@ import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Tests the ResultMapper class
@@ -138,21 +140,22 @@ public class ResultMapperTests
+ "},"
+ "\"stats\":{\"stats_fields\":{\"numericLabel\":{\"sumOfSquares\":0,\"min\":null,\"max\":null,\"mean\":\"NaN\",\"percentiles\":[\"0.0\",12,\"0.99\",20.0685], \"count\":0,\"missing\":0,\"sum\":0,\"distinctValues\":[12,13,14,15,16,17,1],\"stddev\":0}, \"creator\":{\"min\":\"System\",\"max\":\"mjackson\",\"count\":\"990\",\"missing\":\"290\"}, \"created\":{\"sumOfSquares\":2.1513045770343806E27,\"min\":\"2011-02-15T20:16:27.080Z\",\"max\":\"2017-04-10T15:06:30.143Z\",\"mean\":\"2016-09-05T04:20:12.898Z\",\"count\":990,\"missing\":290,\"sum\":1.458318720769983E15,\"stddev\":5.6250677994522545E10}}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
public static final Params EMPTY_PARAMS = Params.valueOf((String)null,(String)null,(WebScriptRequest) null);
public static final Params EMPTY_PARAMS = Params.valueOf((String) null, null, null);
public static final String FROZEN_ID = "frozen";
public static final String FROZEN_VER = "1.1";
private static final long VERSIONED_ID = 521l;
private static SerializerTestHelper helper;
private static NodesImpl nodes;
@BeforeClass
public static void setupTests() throws Exception
public static void setupTests()
{
Map<String, UserInfo> mapUserInfo = new HashMap<>();
mapUserInfo.put(AuthenticationUtil.getSystemUserName(), new UserInfo(AuthenticationUtil.getSystemUserName(), "sys", "sys"));
Map<QName, Serializable> nodeProps = new HashMap<>();
NodesImpl nodes = mock(NodesImpl.class);
nodes = mock(NodesImpl.class);
ServiceRegistry sr = mock(ServiceRegistry.class);
DeletedNodes deletedNodes = mock(DeletedNodes.class);
nodes.setServiceRegistry(sr);
@@ -163,17 +166,10 @@ public class ResultMapperTests
versionProperties.put(Version.PROP_DESCRIPTION, "ver desc");
versionProperties.put(Version2Model.PROP_VERSION_TYPE, "v type");
when(versionHistory.getVersion(anyString())).thenAnswer(invocation ->
{
return new VersionImpl(versionProperties,new NodeRef(StoreMapper.STORE_REF_VERSION2_SPACESSTORE, GUID.generate()));
});
new VersionImpl(versionProperties, new NodeRef(StoreMapper.STORE_REF_VERSION2_SPACESSTORE, GUID.generate())));
NodeService nodeService = mock(NodeService.class);
when(versionService.getVersionHistory(any(NodeRef.class))).thenAnswer(invocation ->
{
Object[] args = invocation.getArguments();
NodeRef aNode = (NodeRef)args[0];
return versionHistory;
});
when(versionService.getVersionHistory(any(NodeRef.class))).thenReturn(versionHistory);
when(nodeService.getProperties(any(NodeRef.class))).thenAnswer(invocation ->
{
@@ -204,31 +200,26 @@ public class ResultMapperTests
}
});
// // NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null);
when(nodes.getFolderOrDocument(any(NodeRef.class), nullable(NodeRef.class), nullable(QName.class), nullable(List.class), nullable(Map.class))).thenAnswer(new Answer<Node>() {
@Override
public Node answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
NodeRef aNode = (NodeRef)args[0];
if (StoreRef.STORE_REF_ARCHIVE_SPACESSTORE.equals(aNode.getStoreRef()))
{
//Return NULL if its from the archive store.
return null;
}
return new Node(aNode, (NodeRef)args[1], nodeProps, mapUserInfo, sr);
when(nodes.getFolderOrDocument(any(NodeRef.class), nullable(NodeRef.class), nullable(QName.class), nullable(List.class), nullable(Map.class))).thenAnswer((Answer<Node>) invocation ->
{
Object[] args = invocation.getArguments();
NodeRef aNode = (NodeRef)args[0];
if (StoreRef.STORE_REF_ARCHIVE_SPACESSTORE.equals(aNode.getStoreRef()))
{
//Return NULL if its from the archive store.
return null;
}
return new Node(aNode, (NodeRef)args[1], nodeProps, mapUserInfo, sr);
});
when(deletedNodes.getDeletedNode(nullable(String.class), nullable(
Parameters.class), anyBoolean(), nullable(Map.class))).thenAnswer(new Answer<Node>() {
@Override
public Node answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String nodeId = (String)args[0];
if (FROZEN_ID.equals(nodeId)) throw new EntityNotFoundException(nodeId);
NodeRef aNode = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, nodeId);
return new Node(aNode, new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE,"unknown"), nodeProps, mapUserInfo, sr);
}
Parameters.class), anyBoolean(), nullable(Map.class))).thenAnswer((Answer<Node>) invocation ->
{
Object[] args = invocation.getArguments();
String nodeId = (String)args[0];
if (FROZEN_ID.equals(nodeId)) throw new EntityNotFoundException(nodeId);
NodeRef aNode = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, nodeId);
return new Node(aNode, new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE,"unknown"), nodeProps, mapUserInfo, sr);
});
PersonPropertyLookup propertyLookups = mock(PersonPropertyLookup.class);
@@ -236,11 +227,10 @@ public class ResultMapperTests
when(propertyLookups.lookup(notNull(String.class))).thenAnswer(invocation -> {
Object[] args = invocation.getArguments();
String value = (String)args[0];
if ("mjackson".equals(value)) return "Michael Jackson";
return null;
return "mjackson".equals(value) ? "Michael Jackson" : null;
});
PropertyLookupRegistry propertyLookupRegistry = new PropertyLookupRegistry();
propertyLookupRegistry.setLookups(Arrays.asList(propertyLookups));
propertyLookupRegistry.setLookups(asList(propertyLookups));
mapper = new ResultMapper();
mapper.setNodes(nodes);
mapper.setStoreMapper(new StoreMapper());
@@ -258,7 +248,7 @@ public class ResultMapperTests
}
@Test
public void testNoResults() throws Exception
public void testNoResults()
{
SearchRequestContext searchRequest = SearchRequestContext.from(SearchQuery.EMPTY);
CollectionWithPagingInfo<Node> collection = mapper.toCollectionWithPagingInfo(EMPTY_PARAMS, searchRequest, null, new EmptyResultSet());
@@ -269,9 +259,9 @@ public class ResultMapperTests
}
@Test
public void testToCollectionWithPagingInfo() throws Exception
public void testToCollectionWithPagingInfo()
{
ResultSet results = mockResultset(Arrays.asList(514l), Arrays.asList(566l, VERSIONED_ID));
ResultSet results = mockResultSet(asList(514l), asList(566l, VERSIONED_ID));
SearchRequestContext searchRequest = SearchRequestContext.from(SearchQuery.EMPTY);
CollectionWithPagingInfo<Node> collectionWithPage = mapper.toCollectionWithPagingInfo(EMPTY_PARAMS, searchRequest, SearchQuery.EMPTY, results);
assertNotNull(collectionWithPage);
@@ -298,12 +288,12 @@ public class ResultMapperTests
}
@Test
public void testToSearchContext() throws Exception
public void testToSearchContext()
{
ResultSet results = mockResultset(Collections.emptyList(),Collections.emptyList());
ResultSet results = mockResultSet(Collections.emptyList(),Collections.emptyList());
SearchQuery searchQuery = helper.searchQueryFromJson();
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
assertEquals(34l, searchContext.getConsistency().getlastTxId());
assertEquals(6, searchContext.getFacetQueries().size());
@@ -384,9 +374,9 @@ public class ResultMapperTests
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.missing, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.sum, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.stddev, 0)));
JSONArray dVals = new JSONArray(Arrays.asList(12, 13, 14, 15, 16, 17, 1));
JSONArray dVals = new JSONArray(asList(12, 13, 14, 15, 16, 17, 1));
assertTrue(statsMetrics.contains(new ListMetric(METRIC_TYPE.distinctValues, dVals)));
JSONArray pers = new JSONArray(Arrays.asList("0.99",20.0685, "0.0", 12.0));
JSONArray pers = new JSONArray(asList("0.99",20.0685, "0.0", 12.0));
assertTrue(statsMetrics.contains(new PercentileMetric(METRIC_TYPE.percentiles, pers)));
assertEquals("min must be excluded because its null",0,statsMetrics.stream().filter(metric -> METRIC_TYPE.min.equals(metric.getType())).count());
@@ -395,18 +385,18 @@ public class ResultMapperTests
}
@Test
public void testIsNullContext() throws Exception
public void testIsNullContext()
{
assertTrue(mapper.isNullContext(new SearchContext(0l,null,null,null,null, null)));
assertFalse(mapper.isNullContext(new SearchContext(1l,null,null,null,null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,null,null,null,new SpellCheckContext(null, null), null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,null, Arrays.asList(new FacetQueryContext(null, null, 0)),null,null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,null,null,Arrays.asList(new FacetFieldContext(null, null)),null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,Arrays.asList(new GenericFacetResponse(null,null, null)),null,null, null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,null, asList(new FacetQueryContext(null, null, 0)),null,null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l,null,null, asList(new FacetFieldContext(null, null)),null, null)));
assertFalse(mapper.isNullContext(new SearchContext(0l, asList(new GenericFacetResponse(null,null, null)),null,null, null, null)));
}
@Test
public void testHighlight() throws Exception
public void testHighlight()
{
SearchParameters sp = new SearchParameters();
sp.setBulkFetchEnabled(false);
@@ -432,12 +422,11 @@ public class ResultMapperTests
@Test
public void testInterval() throws Exception
public void testInterval()
{
ResultSet results = mockResultset(Collections.emptyList(),Collections.emptyList());
ResultSet results = mockResultSet(Collections.emptyList(),Collections.emptyList());
SearchQuery searchQuery = helper.searchQueryFromJson();
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
//Facet intervals
@@ -471,13 +460,13 @@ public class ResultMapperTests
assertEquals(METRIC_TYPE.count,((SimpleMetric) metrics[0]).getType());
assertEquals("854",((SimpleMetric) metrics[0]).getValue().get("count"));
}
@Test
public void testRange() throws Exception
public void testRange()
{
ResultSet results = mockResultset(Collections.emptyList(),Collections.emptyList());
ResultSet results = mockResultSet(Collections.emptyList(),Collections.emptyList());
SearchQuery searchQuery = helper.searchQueryFromJson();
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
//Numeric facet range
@@ -524,14 +513,14 @@ public class ResultMapperTests
assertEquals("300",facetInfo.get("end"));
assertEquals("content.size:[\"200\" TO \"300\">", rangeFacets.get(1).getBuckets().get(2).getFilterQuery());
}
@Test
public void testRangeExclusiec() throws Exception
public void testRangeExclusiec()
{
ResultSet results = mockResultset(Collections.emptyList(),Collections.emptyList());
ResultSet results = mockResultSet(Collections.emptyList(),Collections.emptyList());
String updatedJSON = helper.JSON.replace("lower", "upper");
SearchQuery searchQuery = helper.extractFromJson(updatedJSON);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
//Numeric facet range
@@ -554,26 +543,25 @@ public class ResultMapperTests
}
@Test
/**
* Test facet group with out facet fields
* @throws Exception
*/
public void testFacetingGroupResponse() throws Exception
@Test
public void testFacetingGroupResponse()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"},"
+ "\"facetQueries\": ["
+ "{\"query\": \"content.size:[o TO 102400]\", \"label\": \"small\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[102400 TO 1048576]\", \"label\": \"medium\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[1048576 TO 16777216]\", \"label\": \"large\",\"group\":\"foo\"}]"
+ "}";
String expectedResponse = "{\"responseHeader\":{\"status\":0,\"QTime\":9},\"_original_parameters_\":\"org.apache.solr.common.params.DefaultSolrParams:{params(df=TEXT&alternativeDic=DEFAULT_DICTIONARY&fl=DBID,score&start=0&fq={!afts}AUTHORITY_FILTER_FROM_JSON&fq={!afts}TENANT_FILTER_FROM_JSON&rows=1000&locale=en_US&wt=json),defaults(carrot.url=id&spellcheck.collateExtendedResults=true&carrot.produceSummary=true&spellcheck.maxCollations=3&spellcheck.maxCollationTries=5&spellcheck.alternativeTermCount=2&spellcheck.extendedResults=false&defType=afts&spellcheck.maxResultsForSuggest=5&spellcheck=false&carrot.outputSubClusters=false&spellcheck.count=5&carrot.title=mltext@m___t@{http://www.alfresco.org/model/content/1.0}title&carrot.snippet=content@s___t@{http://www.alfresco.org/model/content/1.0}content&spellcheck.collate=true)}\",\"_field_mappings_\":{},\"_date_mappings_\":{},\"_range_mappings_\":{},\"_pivot_mappings_\":{},\"_interval_mappings_\":{},\"_stats_field_mappings_\":{},\"_stats_facet_mappings_\":{},\"_facet_function_mappings_\":{},\"response\":{\"numFound\":6,\"start\":0,\"maxScore\":0.7849362,\"docs\":[{\"DBID\":565,\"score\":0.7849362},{\"DBID\":566,\"score\":0.7849362},{\"DBID\":521,\"score\":0.3540957},{\"DBID\":514,\"score\":0.33025497},{\"DBID\":420,\"score\":0.32440513},{\"DBID\":415,\"score\":0.2780319}]},"
+ "\"spellcheck\":{\"searchInsteadFor\":\"alfresco\"},"
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
+ "\"facetQueries\": ["
+ "{\"query\": \"content.size:[o TO 102400]\", \"label\": \"small\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[102400 TO 1048576]\", \"label\": \"medium\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[1048576 TO 16777216]\", \"label\": \"large\",\"group\":\"foo\"}]"
+ "}";
ResultSet results = mockResultset(expectedResponse);
String expectedResponse = "{\"responseHeader\":{\"status\":0,\"QTime\":9},\"_original_parameters_\":\"org.apache.solr.common.params.DefaultSolrParams:{params(df=TEXT&alternativeDic=DEFAULT_DICTIONARY&fl=DBID,score&start=0&fq={!afts}AUTHORITY_FILTER_FROM_JSON&fq={!afts}TENANT_FILTER_FROM_JSON&rows=1000&locale=en_US&wt=json),defaults(carrot.url=id&spellcheck.collateExtendedResults=true&carrot.produceSummary=true&spellcheck.maxCollations=3&spellcheck.maxCollationTries=5&spellcheck.alternativeTermCount=2&spellcheck.extendedResults=false&defType=afts&spellcheck.maxResultsForSuggest=5&spellcheck=false&carrot.outputSubClusters=false&spellcheck.count=5&carrot.title=mltext@m___t@{http://www.alfresco.org/model/content/1.0}title&carrot.snippet=content@s___t@{http://www.alfresco.org/model/content/1.0}content&spellcheck.collate=true)}\",\"_field_mappings_\":{},\"_date_mappings_\":{},\"_range_mappings_\":{},\"_pivot_mappings_\":{},\"_interval_mappings_\":{},\"_stats_field_mappings_\":{},\"_stats_facet_mappings_\":{},\"_facet_function_mappings_\":{},\"response\":{\"numFound\":6,\"start\":0,\"maxScore\":0.7849362,\"docs\":[{\"DBID\":565,\"score\":0.7849362},{\"DBID\":566,\"score\":0.7849362},{\"DBID\":521,\"score\":0.3540957},{\"DBID\":514,\"score\":0.33025497},{\"DBID\":420,\"score\":0.32440513},{\"DBID\":415,\"score\":0.2780319}]},"
+ "\"spellcheck\":{\"searchInsteadFor\":\"alfresco\"},"
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
ResultSet results = mockResultSet(expectedResponse);
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
@@ -587,28 +575,28 @@ public class ResultMapperTests
Metric[] metrics = searchContext.getFacets().get(0).getBuckets().get(0).getMetrics().toArray(new Metric[searchContext.getFacets().get(0).getBuckets().get(0).getMetrics().size()]);
assertEquals(METRIC_TYPE.count, metrics[0].getType());
assertEquals("{count=52}", metrics[0].getValue().toString());
}
@Test
/**
* Test facet group with out facet fields
* @throws Exception
*/
public void testFacetingGroupResponseV1() throws Exception
@Test
public void testFacetingGroupResponseV1()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"}, \"facetFormat\":\"V1\","
+ "\"facetQueries\": ["
+ "\"facetQueries\": ["
+ "{\"query\": \"content.size:[o TO 102400]\", \"label\": \"small\"},"
+ "{\"query\": \"content.size:[102400 TO 1048576]\", \"label\": \"medium\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[102400 TO 1048576]\", \"label\": \"medium\",\"group\":\"foo\"},"
+ "{\"query\": \"content.size:[1048576 TO 16777216]\", \"label\": \"large\"}]"
+ "}";
String expectedResponse = "{\"responseHeader\":{\"status\":0,\"QTime\":9},\"_original_parameters_\":\"org.apache.solr.common.params.DefaultSolrParams:{params(df=TEXT&alternativeDic=DEFAULT_DICTIONARY&fl=DBID,score&start=0&fq={!afts}AUTHORITY_FILTER_FROM_JSON&fq={!afts}TENANT_FILTER_FROM_JSON&rows=1000&locale=en_US&wt=json),defaults(carrot.url=id&spellcheck.collateExtendedResults=true&carrot.produceSummary=true&spellcheck.maxCollations=3&spellcheck.maxCollationTries=5&spellcheck.alternativeTermCount=2&spellcheck.extendedResults=false&defType=afts&spellcheck.maxResultsForSuggest=5&spellcheck=false&carrot.outputSubClusters=false&spellcheck.count=5&carrot.title=mltext@m___t@{http://www.alfresco.org/model/content/1.0}title&carrot.snippet=content@s___t@{http://www.alfresco.org/model/content/1.0}content&spellcheck.collate=true)}\",\"_field_mappings_\":{},\"_date_mappings_\":{},\"_range_mappings_\":{},\"_pivot_mappings_\":{},\"_interval_mappings_\":{},\"_stats_field_mappings_\":{},\"_stats_facet_mappings_\":{},\"_facet_function_mappings_\":{},\"response\":{\"numFound\":6,\"start\":0,\"maxScore\":0.7849362,\"docs\":[{\"DBID\":565,\"score\":0.7849362},{\"DBID\":566,\"score\":0.7849362},{\"DBID\":521,\"score\":0.3540957},{\"DBID\":514,\"score\":0.33025497},{\"DBID\":420,\"score\":0.32440513},{\"DBID\":415,\"score\":0.2780319}]},"
+ "\"spellcheck\":{\"searchInsteadFor\":\"alfresco\"},"
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
ResultSet results = mockResultset(expectedResponse);
ResultSet results = mockResultSet(expectedResponse);
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
@@ -622,17 +610,15 @@ public class ResultMapperTests
Metric[] metrics = searchContext.getFacets().get(0).getBuckets().get(0).getMetrics().toArray(new Metric[searchContext.getFacets().get(0).getBuckets().get(0).getMetrics().size()]);
assertEquals(METRIC_TYPE.count, metrics[0].getType());
assertEquals("{count=52}", metrics[0].getValue().toString());
}
@Test
/**
* Test facet fields with out group label in the query.
* This is to support original api methods query for facet query.
*
*
* @throws Exception
*/
public void testFacetQueryWithoutGroupResponse() throws Exception
@Test
public void testFacetQueryWithoutGroupResponse()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"},"
+ "\"facetQueries\": ["
@@ -646,7 +632,7 @@ public class ResultMapperTests
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
ResultSet results = mockResultset(expectedResponse);
ResultSet results = mockResultSet(expectedResponse);
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
@@ -663,7 +649,8 @@ public class ResultMapperTests
assertEquals("content.size:[102400 TO 1048576]",searchContext.getFacetQueries().get(2).getFilterQuery());
assertEquals(0, searchContext.getFacetQueries().get(2).getCount());
}
private ResultSet mockResultset(String json) throws Exception
private ResultSet mockResultSet(String json)
{
NodeService nodeService = mock(NodeService.class);
JSONObject jsonObj = new JSONObject(new JSONTokener(json));
@@ -678,19 +665,17 @@ public class ResultMapperTests
return results;
}
private ResultSet mockResultset(List<Long> archivedNodes, List<Long> versionNodes) throws JSONException
private ResultSet mockResultSet(List<Long> archivedNodes, List<Long> versionNodes)
{
NodeService nodeService = mock(NodeService.class);
when(nodeService.getNodeRef(any())).thenAnswer(new Answer<NodeRef>() {
@Override
public NodeRef answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
//If the DBID is in the list archivedNodes, instead of returning a noderef return achivestore noderef
if (archivedNodes.contains(args[0])) return new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, GUID.generate());
if (versionNodes.contains(args[0])) return new NodeRef(StoreMapper.STORE_REF_VERSION2_SPACESSTORE, GUID.generate()+args[0]);
return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
}
when(nodeService.getNodeRef(any())).thenAnswer((Answer<NodeRef>) invocation ->
{
Object[] args = invocation.getArguments();
//If the DBID is in the list archivedNodes, instead of returning a noderef return achivestore noderef
if (archivedNodes.contains(args[0])) return new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, GUID.generate());
if (versionNodes.contains(args[0])) return new NodeRef(StoreMapper.STORE_REF_VERSION2_SPACESSTORE, GUID.generate()+args[0]);
return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
});
SearchParameters sp = new SearchParameters();
@@ -700,12 +685,12 @@ public class ResultMapperTests
return results;
}
@Test
/**
* Validates that when facetFormat is specified then all facets are returned
* in the generic facet response format AKA V2.
*/
public void facetFormatTest() throws Exception
@Test
public void facetFormatTest()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"},"
+ "\"facetQueries\": ["
@@ -720,7 +705,7 @@ public class ResultMapperTests
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
ResultSet results = mockResultset(expectedResponse);
ResultSet results = mockResultSet(expectedResponse);
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
@@ -737,7 +722,7 @@ public class ResultMapperTests
jsonQuery = jsonQuery.replace("V2", "V1");
searchQuery = helper.extractFromJson(jsonQuery);
results = mockResultset(expectedResponse);
results = mockResultSet(expectedResponse);
searchRequest = SearchRequestContext.from(searchQuery);
searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
assertEquals(34l, searchContext.getConsistency().getlastTxId());
@@ -758,7 +743,7 @@ public class ResultMapperTests
+ "\"spellcheck\":{\"searchInsteadFor\":\"alfresco\"},"
+ "\"facet_counts\":{\"facet_fields\":{\"creator\":[\"System\",124,\"mjackson\",11,\"abeecher\",4],\"modifier\":[\"System\",124,\"mjackson\",8,\"admin\",7]}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
results = mockResultset(expectedResponse);
results = mockResultSet(expectedResponse);
searchQuery = helper.extractFromJson(jsonQuery);
searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
assertFalse(searchContext.getFacetsFields().isEmpty());
@@ -784,7 +769,7 @@ public class ResultMapperTests
}
@Test
public void hasGroupTest() throws IOException
public void hasGroupTest()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"},"
+ "\"facetQueries\": ["
@@ -809,7 +794,7 @@ public class ResultMapperTests
SearchQuery searchQuery3 = helper.extractFromJson(noFacetQueries);
assertFalse(ResultMapper.hasGroup(searchQuery3));
}
@Test
/**
* When the following is passed
* "facetQueries": [
@@ -817,9 +802,9 @@ public class ResultMapperTests
* {"query": "content.size:[102400 TO 1048576]", "label": "medium", "group": "two"},
* {"query": "content.size:[1048576 TO 16777216]", "label": "large"}
* We expect to see 3 groups of 1,2,null.
* @throws Exception
*/
public void testFacetingWithPartialGroup() throws Exception
@Test
public void testFacetingWithPartialGroup()
{
String jsonQuery = "{\"query\": {\"query\": \"alfresco\"},"
+ "\"facetQueries\": ["
@@ -833,7 +818,7 @@ public class ResultMapperTests
+ "\"facet_counts\":{\"facet_queries\": {\"small\": 52,\"large\": 0,\"medium\": 0}},"
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
ResultSet results = mockResultset(expectedResponse);
ResultSet results = mockResultSet(expectedResponse);
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
@@ -853,8 +838,9 @@ public class ResultMapperTests
assertEquals("{count=52}", metrics[0].getValue().toString());
}
@Test
public void testSqlResponse() throws IOException, JSONException
public void testSqlResponse()
{
JSONObject response = new JSONObject("{\"docs\":[{\"SITE\":\"_REPOSITORY_\"},{\"SITE\":\"surf-config\"},{\"SITE\":\"swsdp\"},{\"EOF\":true,\"RESPONSE_TIME\":96}]}");
JSONArray docs = response.getJSONArray("docs");
@@ -888,4 +874,18 @@ public class ResultMapperTests
assertEquals("SearchSQLQuery is required", e.getMessage());
}
}
/** Check that when a node is returned from the index the permissions are still checked in the DB. */
@Test
public void testGetNode()
{
ResultSetRow mockRow = mock(ResultSetRow.class);
NodeRef nodeRef = new NodeRef("workspace://SpacesStore/testNode");
when(mockRow.getNodeRef()).thenReturn(nodeRef);
when(nodes.getFolderOrDocument(eq(nodeRef), any(), any(), any(), any())).thenThrow(new PermissionDeniedException());
Node node = mapper.getNode(mockRow, EMPTY_PARAMS, null, false);
assertNull("Expected node to be filtered due to permission exception.", node);
}
}

View File

@@ -52,7 +52,7 @@ import java.io.StringReader;
public class SerializerTestHelper implements RequestReader
{
JacksonHelper jsonHelper = null;
JacksonHelper jsonHelper;
public static final String JSON = "{ \"query\": {\"query\": \"g*\",\"userQuery\": \"great\",\"language\": \"afts\"}, "
+ "\"paging\": {\"maxItems\": \"99\",\"skipCount\": \"4\"},"
@@ -99,16 +99,23 @@ public class SerializerTestHelper implements RequestReader
}
}
public SearchQuery extractFromJson(String json) throws IOException
public SearchQuery extractFromJson(String json)
{
Content content = mock(Content.class);
when(content.getReader()).thenReturn(new StringReader(json));
try
{
when(content.getReader()).thenReturn(new StringReader(json));
}
catch (IOException e)
{
throw new IllegalStateException("Unexpectedly received exception when configuring mock.", e);
}
WebScriptRequest request = mock(WebScriptRequest.class);
when(request.getContent()).thenReturn(content);
return extractJsonContent(request, jsonHelper, SearchQuery.class);
}
public SearchQuery searchQueryFromJson() throws IOException
public SearchQuery searchQueryFromJson()
{
return extractFromJson(JSON);
}

View File

@@ -26,21 +26,26 @@
package org.alfresco.rest.api.tests;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.admin.RepoHealthChecker;
import org.alfresco.rest.api.discovery.DiscoveryApiWebscript;
import org.alfresco.rest.api.probes.ProbeEntityResource;
import org.alfresco.rest.api.tests.client.HttpResponse;
import org.json.simple.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.alfresco.rest.api.probes.ProbeEntityResource.*;
import static org.alfresco.rest.api.probes.ProbeEntityResource.ProbeType.LIVE;
import static org.alfresco.rest.api.probes.ProbeEntityResource.ProbeType.READY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.lenient;
/**
* V1 REST API tests for Probes (Live and Ready)
@@ -53,7 +58,6 @@ import static org.mockito.Mockito.when;
public class ProbeApiTest extends AbstractBaseApiTest
{
private static final boolean OK = true;
private static final boolean ERROR = false;
private ProbeEntityResource probe;
private DiscoveryApiWebscript origDiscovery;
@@ -64,6 +68,9 @@ public class ProbeApiTest extends AbstractBaseApiTest
@Mock
private DiscoveryApiWebscript badDiscovery;
@Mock
private RepoHealthChecker repoHealthChecker;
@Before
@Override
public void setup() throws Exception
@@ -73,7 +80,9 @@ public class ProbeApiTest extends AbstractBaseApiTest
String beanName = ProbeEntityResource.class.getCanonicalName()+".get";
probe = applicationContext.getBean(beanName, ProbeEntityResource.class);
when(badDiscovery.getRepositoryInfo()).thenThrow(AlfrescoRuntimeException.class);
lenient().when(badDiscovery.getRepositoryInfo()).thenThrow(AlfrescoRuntimeException.class);
Mockito.doNothing().when(repoHealthChecker).checkDatabase();
probe.setRepoHealthChecker(repoHealthChecker);
origDiscovery = probe.setDiscovery(badDiscovery);
}
@@ -91,7 +100,7 @@ public class ProbeApiTest extends AbstractBaseApiTest
return "public";
}
private void assertResponse(String probeName, Boolean ready, String expected, int expectedStatus) throws Exception
private void assertResponse(ProbeType probeType, Boolean ready, String expected, int expectedStatus) throws Exception
{
String[] keys = expectedStatus == 200
? new String[]{"entry", "message"}
@@ -103,7 +112,7 @@ public class ProbeApiTest extends AbstractBaseApiTest
? goodDiscovery
: badDiscovery);
HttpResponse response = getSingle(ProbeEntityResource.class, probeName, null, expectedStatus);
HttpResponse response = getSingle(ProbeEntityResource.class, probeType.getValue(), null, expectedStatus);
Object object = response.getJsonResponse();
for (String key: keys)
{
@@ -128,32 +137,29 @@ public class ProbeApiTest extends AbstractBaseApiTest
public void testProbes() throws Exception
{
// Live first
assertResponse(LIVE, ERROR, "liveProbe: Failure - Tested", 503);
assertResponse(LIVE, null, "liveProbe: Failure - No test", 503); // Need to wait 10 seconds.
assertResponse(LIVE, null, "liveProbe: Failure - No test", 503);
assertResponse(READY, null, "readyProbe: Failure - No test", 503);
assertResponse(LIVE, OK, "liveProbe: Success - Tested", 200);
assertResponse(READY, null, "readyProbe: Failure - Tested", 503);
Thread.currentThread().sleep(CHECK_PERIOD);
assertResponse(READY, OK, "readyProbe: Success - Tested", 200);
assertResponse(READY, null, "readyProbe: Success - No test", 200);
Thread.currentThread().sleep(CHECK_PERIOD);
assertResponse(LIVE, OK, "liveProbe: Success - Tested", 200);
assertResponse(LIVE, null, "liveProbe: Success - No test", 200);
assertResponse(READY, null, "readyProbe: Success - No test", 200);
assertResponse(LIVE, null, "liveProbe: Success - No test", 200);
Thread.currentThread().sleep(CHECK_PERIOD);
assertResponse(LIVE, ERROR, "liveProbe: Failure - Tested", 503);
assertResponse(LIVE, null, "liveProbe: Failure - No test", 503);
assertResponse(READY, null, "readyProbe: Failure - No test", 503);
assertResponse(READY, null, "readyProbe: Failure - Tested", 503);
// Ready first
Thread.currentThread().sleep(CHECK_PERIOD);
assertResponse(READY, OK, "readyProbe: Success - Tested", 200);
assertResponse(LIVE, null, "liveProbe: Success - No test", 200);
assertResponse(LIVE, OK, "liveProbe: Success - Tested", 200);
assertResponse(READY, null, "readyProbe: Success - No test", 200);
// check db failure
Thread.currentThread().sleep(CHECK_PERIOD);
assertResponse(READY, ERROR, "readyProbe: Failure - Tested", 503);
assertResponse(LIVE, null, "liveProbe: Failure - No test", 503);
Mockito.doThrow(AlfrescoRuntimeException.class).when(repoHealthChecker).checkDatabase();
assertResponse(READY, OK, "readyProbe: Failure - Tested", 503);
assertResponse(READY, OK, "readyProbe: Failure - No test", 503);
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,7 +25,6 @@
*/
package org.alfresco.rest.api.tests;
import org.alfresco.repo.action.ActionServiceImpl;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.quickshare.QuickShareLinkExpiryActionImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -65,7 +64,6 @@ import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.testing.category.FrequentlyFailingTests;
import org.alfresco.util.testing.category.LuceneTests;
import org.alfresco.util.testing.category.RedundantTests;
import org.joda.time.DateTime;

View File

@@ -60,8 +60,11 @@ import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl;
import org.alfresco.cmis.client.type.AlfrescoType;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.opencmis.CMISDispatcher;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.opencmis.CMISServletDispatcher;
import org.alfresco.opencmis.PublicApiAlfrescoCmisServiceFactory;
import org.alfresco.opencmis.PublicApiBrowserCMISDispatcher;
import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService;
import org.alfresco.opencmis.dictionary.QNameFilter;
import org.alfresco.opencmis.dictionary.QNameFilterImpl;
@@ -99,6 +102,7 @@ import org.alfresco.rest.api.tests.client.data.NodeRating.Aggregate;
import org.alfresco.rest.api.tests.client.data.Person;
import org.alfresco.rest.api.tests.client.data.SiteRole;
import org.alfresco.rest.api.tests.client.data.Tag;
import org.alfresco.rest.framework.core.exceptions.JsonpCallbackNotAllowedException;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.model.FileFolderService;
@@ -153,6 +157,7 @@ import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.surf.util.URLEncoder;
public class TestCMIS extends EnterpriseTestApi
@@ -517,6 +522,73 @@ public class TestCMIS extends EnterpriseTestApi
assertEquals(200, response.getStatusCode());
}
/**
* MNT-22428 Check the return from http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/browser/root&callback= when jsonp callback is disabled
*
* @throws Exception
*/
@Test
public void testBrowserDisabledJSONPCallback() throws Exception
{
// disables unsecure callback jsonp
final PublicApiBrowserCMISDispatcher dispatcher = ctx.getBean(PublicApiBrowserCMISDispatcher.class);
dispatcher.setAllowUnsecureCallbackJSONP(false);
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String personId = personIt.next();
assertNotNull(personId);
Person person = repoService.getPerson(personId);
assertNotNull(person);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
// request with a callback parameter
HttpResponse response;
final Map<String, String> params = Map.of("callback", "");
response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/browser/root", params);
assertEquals(403, response.getStatusCode());
String exceptionMessage = I18NUtil.getMessage(JsonpCallbackNotAllowedException.DEFAULT_MESSAGE_ID, params);
assertTrue(response.getResponse().endsWith(exceptionMessage));
// request without a callback parameter
response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/browser/root", null);
assertEquals(200, response.getStatusCode());
}
/*
* MNT-22428 Check the return from http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/browser/root&callback= when jsonp callback is enabled
*
* @throws Exception
*/
@Test
public void testBrowserEnabledJSONPCallback() throws Exception
{
// enables unsecure callback jsonp
final PublicApiBrowserCMISDispatcher dispatcher = ctx.getBean(PublicApiBrowserCMISDispatcher.class);
dispatcher.setAllowUnsecureCallbackJSONP(true);
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String personId = personIt.next();
assertNotNull(personId);
Person person = repoService.getPerson(personId);
assertNotNull(person);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
// request with a callback parameter
HttpResponse response;
final Map<String, String> params = Map.of("callback", "someFunction");
response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/browser/root", params);
assertEquals(200, response.getStatusCode());
// request without a callback parameter
response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/browser/root", null);
assertEquals(200, response.getStatusCode());
}
/**
* REPO-2041 / MNT-16236 Upload via cmis binding atom and browser files with different maxContentSize
*/

View File

@@ -82,8 +82,7 @@ Sometimes it is desirable to create a version automatically. Whether this happe
When _cm:autoVersion_ is true, a new version is created when the _cm:content_ of a content node changes.
When _cm:autoVersionOnUpdateProps_ is true, a new version is created when any of the properties of a content node change.
The defaults for these properties are set in the contentModel.xml file in the usual way. But to simplify the admin experience, the values of these properties can also set using global properties:
The defaults for these properties are set in the contentModel.xml file in the usual way. But to simplify the admin experience, the values of these properties can also be set using global properties:
* version.store.enableAutoVersioning
* version.store.enableAutoVersionOnUpdateProps

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>11.141-SNAPSHOT</version>
<version>14.35</version>
</parent>
<dependencies>
@@ -191,7 +191,7 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.8.1</version>
<version>${dependency.maven-artifact.version}</version>
</dependency>
<dependency>
<groupId>de.schlichtherle.truezip</groupId>

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.encryption;
import java.io.Serializable;
@@ -241,6 +241,12 @@ public class ReEncryptor implements ApplicationContextAware
return properties.size();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return properties.size();
}
@Override
public Collection<NodePropertyEntity> getNextWork()
{

View File

@@ -1959,6 +1959,12 @@ public class AlfrescoCmisServiceImpl extends AbstractCmisService implements Alfr
return size;
}
@Override
public synchronized long getTotalEstimatedWorkSizeLong()
{
return size;
}
@Override
public synchronized Collection<BulkEntry> getNextWork()
{

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.activities.feed;
import java.util.Collection;
@@ -427,6 +427,12 @@ public class FeedNotifierImpl implements FeedNotifier, ApplicationContextAware
return personService.countPeople();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return personService.countPeople();
}
@Override
public Collection<PersonInfo> getNextWork()
{

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.activities.feed.local;
import java.util.ArrayList;
@@ -155,13 +155,25 @@ public class LocalFeedGenerator extends AbstractFeedGenerator
@Override
public int getTotalEstimatedWorkSize()
{
return (int) calculateEstimatedWorkSize();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return calculateEstimatedWorkSize();
}
private long calculateEstimatedWorkSize()
{
long size = maxSequence - minSequence + 1;
long remain = size % batchSize;
long workSize = (remain == 0) ? (size / batchSize) : (size / batchSize + 1);
return (int) workSize;
return workSize;
}
@Override
public Collection<JobSettings> getNextWork()
{

View File

@@ -0,0 +1,47 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2018 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.admin;
import org.alfresco.repo.domain.schema.DataSourceCheck;
/**
* A utility service to do the database and other health checks.
*/
public class RepoHealthChecker
{
private final DataSourceCheck dataSourceCheck;
public RepoHealthChecker(DataSourceCheck dataSourceCheck)
{
this.dataSourceCheck = dataSourceCheck;
}
public void checkDatabase()
{
dataSourceCheck.init();
}
}

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch;
import java.io.PrintWriter;
@@ -486,6 +486,11 @@ public abstract class AbstractPatch implements Patch, ApplicationEventPublisher
return tenants.size();
}
public long getTotalEstimatedWorkSizeLong()
{
return tenants.size();
}
@Override
public Collection<Tenant> getNextWork()
{
@@ -554,13 +559,13 @@ public abstract class AbstractPatch implements Patch, ApplicationEventPublisher
logger.debug("batch worker finished processing id:" + id);
}
if (batchProcessor.getTotalErrors() > 0)
if (batchProcessor.getTotalErrorsLong() > 0)
{
sb.append("\n" + " and failure during update of tennants total success: " + batchProcessor.getSuccessfullyProcessedEntries() + " number of errors: " +batchProcessor.getTotalErrors() + " lastError" + batchProcessor.getLastError());
sb.append("\n" + " and failure during update of tennants total success: " + batchProcessor.getSuccessfullyProcessedEntriesLong() + " number of errors: " +batchProcessor.getTotalErrorsLong() + " lastError" + batchProcessor.getLastError());
}
else
{
sb.append("\n" + " and successful batch update of " + batchProcessor.getTotalResults() + "tennants");
sb.append("\n" + " and successful batch update of " + batchProcessor.getTotalResultsLong() + "tennants");
}
}

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
@@ -90,6 +90,12 @@ public class AddUnmovableAspectToSitesPatch extends AsynchronousPatch
return sites.size();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return sites.size();
}
@Override
public Collection<ChildAssociationRef> getNextWork()
{

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
@@ -93,6 +93,11 @@ public class AliasableAspectPatch extends AbstractPatch
return result.size();
}
public long getTotalEstimatedWorkSizeLong()
{
return result.size();
}
public Collection<NodeRef> getNextWork()
{
if(val != null)

View File

@@ -237,6 +237,12 @@ public class FixBpmPackagesPatch extends AbstractPatch
return assocCount;
}
@Override
public synchronized long getTotalEstimatedWorkSizeLong()
{
return assocCount;
}
@Override
public synchronized Collection<ChildAssociationRef> getNextWork()
{

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
@@ -76,6 +76,11 @@ public class ImapUnsubscribedAspectPatch extends AbstractPatch
return result.size();
}
public long getTotalEstimatedWorkSizeLong()
{
return result.size();
}
public Collection<NodeRef> getNextWork()
{
result.clear();

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
@@ -143,6 +143,12 @@ public class RenameSiteAuthorityDisplayName extends AbstractPatch
{
return siteInfos.size();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return siteInfos.size();
}
@Override
public Collection<SiteInfo> getNextWork()

View File

@@ -1,37 +1,31 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AsynchronousPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
@@ -55,6 +49,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Patch to add <i>cm:indexControl</i> aspect to sites' surf-config folders and
* their children as well as to the shared surf-config folder(s) and its/their children.
@@ -382,8 +382,12 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
this.siteTypeQNameId = qnameDAO.getQName(SiteModel.TYPE_SITE);
}
@Override
public synchronized int getTotalEstimatedWorkSize()
@Override public synchronized int getTotalEstimatedWorkSize()
{
return (int) getTotalEstimatedWorkSizeLong();
}
@Override public synchronized long getTotalEstimatedWorkSizeLong()
{
if (maxId == Long.MAX_VALUE)
{
@@ -405,7 +409,7 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
logger.debug("\tQ: Work count: " + workCount);
}
}
return (int) workCount;
return workCount;
}
@Override
@@ -449,6 +453,12 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
@Override
public synchronized int getTotalEstimatedWorkSize()
{
return (int)getTotalEstimatedWorkSizeLong();
}
@Override
public synchronized long getTotalEstimatedWorkSizeLong()
{
if (maxId == Long.MAX_VALUE)
{
@@ -459,6 +469,7 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
}
}
return 0;
}
@Override

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.batch;
import java.util.Date;
@@ -50,10 +50,10 @@ public interface BatchMonitor
/**
* Gets the total number of results.
*
* @deprecated use {@link #getTotalResultsLong()} instead
* @return the total number of results
*/
public int getTotalResults();
@Deprecated public int getTotalResults();
/**
* Gets the ID of the entry being processed
@@ -64,10 +64,10 @@ public interface BatchMonitor
/**
* Gets the number of successfully processed entries.
*
* @deprecated use {@link #getSuccessfullyProcessedEntriesLong()} instead
* @return the successfully processed entries
*/
public int getSuccessfullyProcessedEntries();
@Deprecated public int getSuccessfullyProcessedEntries();
/**
* Gets the progress expressed as a percentage.
@@ -78,10 +78,10 @@ public interface BatchMonitor
/**
* Gets the total number of errors.
*
* @deprecated use {@link #getTotalErrorsLong()} instead
* @return the total number of errors
*/
public int getTotalErrors();
@Deprecated public int getTotalErrors();
/**
* Gets the stack trace of the last error.
@@ -103,4 +103,35 @@ public interface BatchMonitor
* @return the end time
*/
public Date getEndTime();
/**
* Gets the total number of results.
*
* @return the total number of results
*/
public default long getTotalResultsLong()
{
throw new UnsupportedOperationException("getTotalResultsLong need to be implemented");
}
/**
* Gets the total number of errors.
*
* @return the total number of errors
*/
public default long getTotalErrorsLong()
{
throw new UnsupportedOperationException("getTotalErrorsLong need to be implemented");
}
/**
* Gets the number of successfully processed entries.
*
* @return the successfully processed entries
*/
public default long getSuccessfullyProcessedEntriesLong()
{
throw new UnsupportedOperationException("getSuccessfullyProcessedEntriesLong need to be implemented");
}
}

View File

@@ -43,10 +43,10 @@ public interface BatchProcessWorkProvider<T>
* Instances can provide accurate answers on each call, but only if the answer can be
* provided quickly and efficiently; usually it is enough to to cache the result after
* providing an initial estimate.
*
* @deprecated use {@link #getTotalEstimatedWorkSizeLong()} instead.
* @return a total work size estimate
*/
int getTotalEstimatedWorkSize();
@Deprecated int getTotalEstimatedWorkSize();
/**
* Get the next lot of work for the batch processor. Implementations should return
@@ -58,4 +58,18 @@ public interface BatchProcessWorkProvider<T>
* if there is no more work remaining.
*/
Collection<T> getNextWork();
/**
* Get an estimate of the total number of objects that will be provided by this instance.
* Instances can provide accurate answers on each call, but only if the answer can be
* provided quickly and efficiently; usually it is enough to to cache the result after
* providing an initial estimate.
*
* @return a total work size estimate
*/
default long getTotalEstimatedWorkSizeLong()
{
throw new UnsupportedOperationException("getTotalEstimatedWorkSizeLong need to implemented");
}
}

View File

@@ -25,6 +25,18 @@
*/
package org.alfresco.repo.batch;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.node.integrity.IntegrityException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.util.TraceableThreadFactory;
import org.alfresco.util.transaction.TransactionListenerAdapter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEventPublisher;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
@@ -43,18 +55,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.node.integrity.IntegrityException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.util.TraceableThreadFactory;
import org.alfresco.util.transaction.TransactionListenerAdapter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEventPublisher;
/**
* A <code>BatchProcessor</code> manages the running and monitoring of a potentially long-running transactional batch
* process. It iterates over a collection, and queues jobs that fire a worker on a batch of members. The queued jobs
@@ -110,10 +110,10 @@ public class BatchProcessor<T> implements BatchMonitor
private String lastErrorEntryId;
/** The total number of errors. */
private int totalErrors;
private long totalErrors;
/** The number of successfully processed entries. */
private int successfullyProcessedEntries;
private long successfullyProcessedEntries;
/** The start time. */
private Date startTime;
@@ -158,10 +158,17 @@ public class BatchProcessor<T> implements BatchMonitor
new BatchProcessWorkProvider<T>()
{
boolean hasMore = true;
public int getTotalEstimatedWorkSize()
@Override public int getTotalEstimatedWorkSize()
{
return (int) getTotalEstimatedWorkSizeLong();
}
@Override public long getTotalEstimatedWorkSizeLong()
{
return collection.size();
}
public Collection<T> getNextWork()
{
// Only return the collection once
@@ -280,7 +287,15 @@ public class BatchProcessor<T> implements BatchMonitor
/**
* {@inheritDoc}
*/
public synchronized int getSuccessfullyProcessedEntries()
@Deprecated public synchronized int getSuccessfullyProcessedEntries()
{
return Math.toIntExact(this.successfullyProcessedEntries);
}
/**
* {@inheritDoc}
*/
public synchronized long getSuccessfullyProcessedEntriesLong()
{
return this.successfullyProcessedEntries;
}
@@ -290,8 +305,8 @@ public class BatchProcessor<T> implements BatchMonitor
*/
public synchronized String getPercentComplete()
{
int totalResults = this.workProvider.getTotalEstimatedWorkSize();
int processed = this.successfullyProcessedEntries + this.totalErrors;
long totalResults = this.workProvider.getTotalEstimatedWorkSizeLong();
long processed = this.successfullyProcessedEntries + this.totalErrors;
return processed <= totalResults ? NumberFormat.getPercentInstance().format(
totalResults == 0 ? 1.0F : (float) processed / totalResults) : "Unknown";
}
@@ -299,7 +314,23 @@ public class BatchProcessor<T> implements BatchMonitor
/**
* {@inheritDoc}
*/
public synchronized int getTotalErrors()
@Deprecated public synchronized int getTotalErrors()
{
return Math.toIntExact(this.totalErrors);
}
/**
* {@inheritDoc}
*/
@Deprecated public int getTotalResults()
{
return this.workProvider.getTotalEstimatedWorkSize();
}
/**
* {@inheritDoc}
*/
public synchronized long getTotalErrorsLong()
{
return this.totalErrors;
}
@@ -307,9 +338,9 @@ public class BatchProcessor<T> implements BatchMonitor
/**
* {@inheritDoc}
*/
public int getTotalResults()
public long getTotalResultsLong()
{
return this.workProvider.getTotalEstimatedWorkSize();
return this.workProvider.getTotalEstimatedWorkSizeLong();
}
/**
@@ -340,12 +371,42 @@ public class BatchProcessor<T> implements BatchMonitor
* increased performance. If <code>false</code>, all invocations are performed in the current
* transaction. This is required if calling synchronously (e.g. in response to an authentication event in
* the same transaction).
* @deprecated use {@link #processLong(BatchProcessWorker, boolean)} instead
* @return the number of invocations
*/
@SuppressWarnings("serial")
public int process(final BatchProcessWorker<T> worker, final boolean splitTxns)
@Deprecated public int process(final BatchProcessWorker<T> worker, final boolean splitTxns)
{
int count = workProvider.getTotalEstimatedWorkSize();
return (int)process(worker, splitTxns, count);
}
/**
* Invokes the worker for each entry in the collection, managing transactions and collating success / failure
* information.
*
* @param worker
* the worker
* @param splitTxns
* Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
* <code>true</code>, worker invocations are isolated in separate transactions in batches for
* increased performance. If <code>false</code>, all invocations are performed in the current
* transaction. This is required if calling synchronously (e.g. in response to an authentication event in
* the same transaction).
* @return the number of invocations
*/
@SuppressWarnings("serial")
public long processLong(final BatchProcessWorker<T> worker, final boolean splitTxns)
{
long count = workProvider.getTotalEstimatedWorkSizeLong();
return process(worker, splitTxns, count);
}
private long process(final BatchProcessWorker<T> worker, final boolean splitTxns, long count)
{
synchronized (this)
{
this.startTime = new Date();
@@ -365,27 +426,27 @@ public class BatchProcessor<T> implements BatchMonitor
// Create a thread pool executor with the specified number of threads and a finite blocking queue of jobs
ExecutorService executorService = splitTxns && this.workerThreads > 1 ?
new ThreadPoolExecutor(
this.workerThreads, this.workerThreads, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(this.workerThreads * this.batchSize * 10)
{
// Add blocking behaviour to work queue
@Override
public boolean offer(Runnable o)
{
try
{
put(o);
}
catch (InterruptedException e)
{
return false;
}
return true;
}
new ThreadPoolExecutor(
this.workerThreads, this.workerThreads, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(this.workerThreads * this.batchSize * 10)
{
// Add blocking behaviour to work queue
@Override
public boolean offer(Runnable o)
{
try
{
put(o);
}
catch (InterruptedException e)
{
return false;
}
return true;
}
},
threadFactory) : null;
},
threadFactory) : null;
try
{
Iterator<T> iterator = new WorkProviderIterator<T>(this.workProvider);
@@ -402,7 +463,7 @@ public class BatchProcessor<T> implements BatchMonitor
{
batch = new ArrayList<T>(this.batchSize);
}
if (executorService == null)
{
callback.run();
@@ -447,13 +508,12 @@ public class BatchProcessor<T> implements BatchMonitor
if (this.totalErrors > 0 && this.logger.isErrorEnabled())
{
this.logger.error(getProcessName() + ": " + this.totalErrors
+ " error(s) detected. Last error from entry \"" + this.lastErrorEntryId + "\"",
this.lastError);
+ " error(s) detected. Last error from entry \"" + this.lastErrorEntryId + "\"",
this.lastError);
}
}
}
}
/**
* Reports the current progress.
*
@@ -464,12 +524,20 @@ public class BatchProcessor<T> implements BatchMonitor
*/
private synchronized void reportProgress(boolean last)
{
int processed = this.successfullyProcessedEntries + this.totalErrors;
long processed = this.successfullyProcessedEntries + this.totalErrors;
if (processed % this.loggingInterval == 0 ^ last)
{
StringBuilder message = new StringBuilder(100).append(getProcessName()).append(": Processed ").append(
processed).append(" entries");
int totalResults = this.workProvider.getTotalEstimatedWorkSize();
long totalResults = 0;
try
{
totalResults = this.workProvider.getTotalEstimatedWorkSizeLong();
}
catch (UnsupportedOperationException uoe)
{
totalResults = this.workProvider.getTotalEstimatedWorkSize();
}
if (totalResults >= processed)
{
message.append(" out of ").append(totalResults).append(". ").append(
@@ -830,11 +898,11 @@ public class BatchProcessor<T> implements BatchMonitor
{
if (this.txnErrors > 0)
{
int processed = BatchProcessor.this.successfullyProcessedEntries + BatchProcessor.this.totalErrors;
int currentIncrement = processed % BatchProcessor.this.loggingInterval;
int newErrors = BatchProcessor.this.totalErrors + this.txnErrors;
long processed = BatchProcessor.this.successfullyProcessedEntries + BatchProcessor.this.totalErrors;
long currentIncrement = processed % BatchProcessor.this.loggingInterval;
long newErrors = BatchProcessor.this.totalErrors + this.txnErrors;
// Work out the number of logging intervals we will cross and report them
int intervals = (this.txnErrors + currentIncrement) / BatchProcessor.this.loggingInterval;
long intervals = (this.txnErrors + currentIncrement) / BatchProcessor.this.loggingInterval;
if (intervals > 0)
{
BatchProcessor.this.totalErrors += BatchProcessor.this.loggingInterval - currentIncrement;
@@ -850,11 +918,11 @@ public class BatchProcessor<T> implements BatchMonitor
if (this.txnSuccesses > 0)
{
int processed = BatchProcessor.this.successfullyProcessedEntries + BatchProcessor.this.totalErrors;
int currentIncrement = processed % BatchProcessor.this.loggingInterval;
int newSuccess = BatchProcessor.this.successfullyProcessedEntries + this.txnSuccesses;
long processed = BatchProcessor.this.successfullyProcessedEntries + BatchProcessor.this.totalErrors;
long currentIncrement = processed % BatchProcessor.this.loggingInterval;
long newSuccess = BatchProcessor.this.successfullyProcessedEntries + this.txnSuccesses;
// Work out the number of logging intervals we will cross and report them
int intervals = (this.txnSuccesses + currentIncrement) / BatchProcessor.this.loggingInterval;
long intervals = (this.txnSuccesses + currentIncrement) / BatchProcessor.this.loggingInterval;
if (intervals > 0)
{
BatchProcessor.this.successfullyProcessedEntries += BatchProcessor.this.loggingInterval

View File

@@ -1,20 +1,20 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
@@ -195,6 +195,12 @@ public class StripingFilesystemTracker extends AbstractFilesystemTracker
return count();
}
@Override
public long getTotalEstimatedWorkSizeLong()
{
return count();
}
@Override
public Collection<ImportableItem> getNextWork()
{

View File

@@ -47,6 +47,7 @@ import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.filestore.FileContentWriter;
import org.alfresco.repo.content.transform.TransformerDebug;
import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.ContentAccessor;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -429,6 +430,7 @@ public abstract class AbstractContentReader extends AbstractContentAccessor impl
}
catch (Throwable e)
{
if (e instanceof ArchivedIOException) throw e;
throw new ContentIOException("Failed to open stream onto channel: \n" +
" accessor: " + this,
e);
@@ -541,6 +543,10 @@ public abstract class AbstractContentReader extends AbstractContentAccessor impl
// done
return content;
}
catch (ArchivedIOException e)
{
throw e;
}
catch (Exception e)
{
throw new ContentIOException("Failed to copy content to string: \n" +

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