From c1a56ee22f16a3852359c28683d0a214349a5881 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Fri, 9 Oct 2020 13:25:44 +0100 Subject: [PATCH] Merge changes on 6.2.N (6.2.3-A1) projects since 15/7/2020 16:22 to release/6.2.N (#29) * Changes originally made to acs-packaging * Changes originally made to acs-packaging * MNT-21702 : Kerberos SSO fallback mechanism for WebDAV (#766) Reinstated 'part' of the reverted code change originally made in MNT-16931 to handle fallback correctly for WebDAV in a kerberos environment. (cherry picked from commit 91e6af0974bbc9255d5053237abdd10104420042) [MNT-21758] Cannot map an AOS / WebDAV drive with Kerberos SSO enabled (#785) - Add multi catch for Illegal Argument and Not Found when findWebScript is called. (cherry picked from commit 7c135ae8c990f65cf7901d6d6f72dc6c70e44c13) SEARCH-2363: Escape special characters when serializing ChildAssociationRefs and AssociationRefs objects Cherry Picked from f941a6e (cherry picked from commit 3a8ac4417370ec3dad5e9283c3d41e2fd3dd91ce) * SEARCH-2273: Add detailed message when ignoring nodes in SOLR without type or with types not registered in Dictionary Service. Cherry-picked from f4bdc8c (cherry picked from commit a01c6ddf816fed57c28a5bd873da5e4835d90488) SEARCH-800: Get values in DBResultSetRow in the same way they are recovered in SolrJSONResultSetRow. Cherry-picked from 695113f (cherry picked from commit 1c98d6f29c5b9fd8081af76d63add762af833dc1) MNT-21317 Move on Update Folder Rule triggers unexpectedly for MOVED content. (#1115) * MNT-21317_fix folder rule trigger * MNT-21317_folder rule test case added * Update .travis.yml * Update OnPropertyUpdateRuleTrigger.java * MNT-21317 updated test cherry picked from commit 33ca87046019416875fd23b72293e84b912f4cd9 master to 6.2.N (cherry picked from commit 1d4e7002543f6425da9e9f26047b8d42c84b2bd3) Bump gytheio-messaging-camel from 0.11.3 to 0.11.6 (#1095) Bumps gytheio-messaging-camel from 0.11.3 to 0.11.6. Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> (cherry picked from commit 16179db5fc4524c339097f1f3a9a6409dd895b11) (cherry picked from commit af0080e336b7f5505f47d72b9b063c9ce5caedd0) REPO-5235: Use unforked tika (#1081) * REPO-5235: Use latst unforked tika version from the updated alfresco-data-model * Recognise new Exif properties and use a previous workaround to set correct tiff:ImageLength and tiff:ImageWidth (cherry picked from commit 7f576b1d329b997630d3b6d0a9881760e58d25c6) (cherry picked from commit ab91ec354a14e8c20c4a2deb0a73149362d5155b) support/SP/7.N: Updated T-engines to 2.3.3 (Cherry-picked from master) (cherry picked from commit ca4e978e6874869de0bb5a56843f9caf8d8874ac) MNT-21614: LDAP sync communication error leads to group members deletion (#1149) * Catch reported exceptions to filter ldap sync aborts (cherry picked from commit 4d0a1966297db0cc4e219d9693236b879b5f12c7) support/SP/7.N: Updated T-engines to 2.3.4 (Cherry-picked from master) (cherry picked from commit 8078e1ce7e81a5bee15f15d7bfa156427ebcccbc) SEARCH-2289: Restore the support for SOLR 4 in ACS 6.2+ deployments. Cherry pick from e8bba3c (cherry picked from commit f4b653ba5577629fae0ba8e193b151dd7bbdb7be) [MNT-21847] - Aync permissions fail when new nodes are created (#1188) (#1195) Fix: *Changed method setFixedAcls on class ADMAccessControlListDAO to continue to propagate through children to apply the correct acl not only when the current child acl matches the shared acl to replace but also when the current child acl matches the new shared acl Unit Test: *Refactored the unit test FixedAclUpdaterTest to be able to add in a new test without repeating code: separating the operations that set the permissions from the one that triggers the job into separate methods *As it was if one test failed, leaving aspects to be processed, the test would run indefinitely (it was programmed to keep running the job while there where nodes with the aspect). Added a verification to stop triggering the job if the number of nodes with the pendingFixAcl did not change between executions. *Also, if one test failed, it would leave nodes with pendingFixAcl aspect in the database, and the other tests that ran after would also fail, not completing the goal of processing all nodes with the aspect. If a test fails, the folder structure it ran is now deleted so no nodes with the aspect from that structure are processed by the other tests. *Added a test to find the first folder in a tree where permissions where set async that has the pendingFixAcl aspect and that creates a new node in it to verify the issue (cherry picked from commit 443e5e226430a2760492fb82214ad520e7e1cb75) (cherry picked from commit 65a48f3c36a6fc3567c5b0edafb949629f705d8a) ATS-825 : Updated T-engines to 2.3.5 (#1224) (cherry picked from commit 6dcf985acc4f238ae8c9af22e84a61ad9b476429) SEARCH-2450 Don't expose properties from solr endpoint if the model says not to index them. (#1228) (#1229) (cherry picked from commit 2fea6c9484def402e2bfd7c3717071ff8df69c01) (cherry picked from commit 8db009c9505c5d01ba08d2427f549e54ea13fbc6) Fix/MNT-21800 CMIS Web Service Check Out returns error (#1232) (#1233) * MNT-21800 : CMIS Web Service Check Out returns error Integrate path into codebase. (cherry picked from commit 51a7793668ba1c969c5de37603190244e3839cd0) (cherry picked from commit 0cd801a6c12d7ac7e1ff7f05b8b8acfaacdb58e4) * SOLR Test class should be under repository/src/test and not repository/src/main [skip ci] * Test build * Undo README dummy change. [skip ci] * Remove READMEs that have been moved to the top level. * Same jars as in 6.2.3-A1 - needed to correct tika and poi. * Fix location of keystore Only copy win64 and linux pdf-renderer to dist zip Sort out what get included in dist jar and zip (cherry picked from commit 779f8af717bec001717094d1ce885ac63e601887) * aos-module had the wrong version --- .travis.yml | 8 +- core/README.md | 42 ------ core/pom.xml | 3 - data-model/README.md | 47 ------- data-model/pom.xml | 4 - packaging/docker-alfresco/Dockerfile | 4 +- packaging/tests/environment/.env | 4 +- packaging/war/pom.xml | 4 - pom.xml | 19 +-- remote-api/README.md | 41 ------ remote-api/pom.xml | 60 --------- .../repo/web/scripts/solr/SOLRSerializer.java | 4 +- .../BaseKerberosAuthenticationFilter.java | 17 ++- .../auth/BaseSSOAuthenticationFilter.java | 2 +- .../web/scripts/solr/SOLRSerializerTest.java | 120 ++++++++++++++---- repository/README.md | 41 ------ repository/pom.xml | 79 ------------ .../opencmis/TransactionAwareHolder.java | 18 ++- .../metadata/TikaAutoMetadataExtracter.java | 20 +-- .../permissions/ADMAccessControlListDAO.java | 4 +- .../OnPropertyUpdateRuleTrigger.java | 52 ++++---- .../impl/querymodel/impl/db/DBResultSet.java | 7 +- .../querymodel/impl/db/DBResultSetRow.java | 11 +- .../security/sync/ldap/LDAPUserRegistry.java | 11 ++ .../repo/solr/SOLRTrackingComponentImpl.java | 27 +++- .../Search/solr4/solr-search-context.xml | 11 +- .../permissions/FixedAclUpdaterTest.java | 84 +++++++++++- .../rule/ruletrigger/RuleTriggerTest.java | 29 ++++- .../impl/querymodel/impl/db/DBQueryTest.java | 24 ++++ .../security/sync/LDAPUserRegistryTest.java | 52 +++++++- .../repo/solr/SOLRTrackingComponentTest.java | 97 ++++++++++++++ .../solr/SOLRTrackingComponentUnitTest.java | 115 +++++++++++++++++ 32 files changed, 617 insertions(+), 444 deletions(-) delete mode 100644 core/README.md delete mode 100644 data-model/README.md delete mode 100644 remote-api/README.md delete mode 100644 repository/README.md create mode 100644 repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentUnitTest.java diff --git a/.travis.yml b/.travis.yml index 359fcf58ca..c7804b1eaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,14 +80,14 @@ jobs: before_script: - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300' - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8 - - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.4 + - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5 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 -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/ - name: "Repository - AppContext04TestSuite" before_script: - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300' - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8 - - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.4 + - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5 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" @@ -104,7 +104,7 @@ jobs: before_script: - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300' - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8 - - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.4 + - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5 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 -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/ - name: "Repository - AppContextExtraTestSuite" @@ -117,7 +117,7 @@ jobs: before_script: - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300' - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8 - - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.4 + - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5 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 -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/ - name: "Repository - MySQL tests" diff --git a/core/README.md b/core/README.md deleted file mode 100644 index 13462dd056..0000000000 --- a/core/README.md +++ /dev/null @@ -1,42 +0,0 @@ -### Alfresco Core -[![Build Status](https://travis-ci.com/Alfresco/alfresco-core.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-core) - -Alfresco Core is a library packaged as a jar file which is part of [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository). -The library contains the following: -* Various helpers and utils -* 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. - -### Building and testing -The project can be built and tested by running Maven command: -~~~ -mvn clean install -~~~ - -### Artifacts -The artifacts can be obtained by: -* downloading from [Alfresco repository](https://artifacts.alfresco.com/nexus/content/groups/public) -* getting as Maven dependency by adding the dependency to your pom file: -~~~ - - org.alfresco - alfresco-core - version - -~~~ -and Alfresco repository: -~~~ - - alfresco-maven-repo - https://artifacts.alfresco.com/nexus/content/groups/public - -~~~ -The SNAPSHOT version of the artifact is **never** published. - -### Old version history -The history for older 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. diff --git a/core/pom.xml b/core/pom.xml index 1dd65445f6..6ce964ca99 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -112,7 +112,6 @@ javax.servlet javax.servlet-api - 3.0.1 provided @@ -130,13 +129,11 @@ org.mockito mockito-core - 3.2.4 test commons-dbcp commons-dbcp - 1.4-DBCP330 test diff --git a/data-model/README.md b/data-model/README.md deleted file mode 100644 index 3d9f56bc6c..0000000000 --- a/data-model/README.md +++ /dev/null @@ -1,47 +0,0 @@ -### Alfresco Data Model -[![Build Status](https://travis-ci.com/Alfresco/alfresco-data-model.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-data-model) - -Data model is a library packaged as a jar file which is part of [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository). -The library contains the following: -* Dictionary, Repository and Search Services interfaces -* Models for data types and Dictionary implementation -* Parsers - -Please note that the data model uses version 2 of the Jackson libraries. -The upgrade from version 1 was not backward compatible, any projects -that are dependent on data model using Jackson 1.x should use the data-model 6.N branch. - -Version 8.0 of data-model depends on alfresco-core 7.0 which is based on Spring 5. - - -### Building and testing -The project can be built and tested by running Maven command: -~~~ -mvn clean install -~~~ - -### Artifacts -The artifacts can be obtained by: -* downloading from [Alfresco repository](https://artifacts.alfresco.com/nexus/content/groups/public) -* getting as Maven dependency by adding the dependency to your pom file: -~~~ - - org.alfresco - alfresco-data-model - version - -~~~ -and Alfresco repository: -~~~ - - alfresco-maven-repo - https://artifacts.alfresco.com/nexus/content/groups/public - -~~~ -The SNAPSHOT version of the artifact is **never** published. - -### Old version history -The history for older versions can be found in [Alfresco SVN](https://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/data-model) - -### Contributing guide -Please use [this guide](CONTRIBUTING.md) to make a contribution to the project. diff --git a/data-model/pom.xml b/data-model/pom.xml index f34a937270..bd243f0a61 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -133,7 +133,6 @@ javax.servlet javax.servlet-api - 3.0.1 provided @@ -230,13 +228,11 @@ org.antlr gunit - 3.5.2 test org.mockito mockito-core - 3.2.4 test diff --git a/packaging/docker-alfresco/Dockerfile b/packaging/docker-alfresco/Dockerfile index 927490233d..71d44d63ac 100644 --- a/packaging/docker-alfresco/Dockerfile +++ b/packaging/docker-alfresco/Dockerfile @@ -1,6 +1,6 @@ # Fetch image based on Tomcat 8.5.43 and Java 11 # More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat -FROM alfresco/alfresco-base-tomcat:8.5.43-java-11-openjdk-centos-7 +FROM alfresco/alfresco-base-tomcat:8.5.51-java-11-openjdk-centos-7 # Set default docker_context. ARG resource_path=target @@ -34,7 +34,7 @@ COPY ${resource_path}/war ${TOMCAT_DIR}/webapps COPY ${resource_path}/connector/* ${TOMCAT_DIR}/lib/ COPY ${resource_path}/alfresco-mmt/* ${TOMCAT_DIR}/alfresco-mmt/ COPY ${resource_path}/dependency/licenses/ /licenses/ -COPY ${resource_path}/dependency/keystore/metadata-keystore ${TOMCAT_DIR}/shared/classes/alfresco/extension/keystore/ +COPY ${resource_path}/dependency/keystore/metadata-keystore/keystore ${TOMCAT_DIR}/shared/classes/alfresco/extension/keystore # Change the value of the shared.loader= property to the following: # shared.loader=${catalina.base}/shared/classes diff --git a/packaging/tests/environment/.env b/packaging/tests/environment/.env index f13d730f80..b60ffc632e 100644 --- a/packaging/tests/environment/.env +++ b/packaging/tests/environment/.env @@ -1,4 +1,4 @@ -TRANSFORMERS_TAG=2.3.1 -SOLR6_TAG=1.4.2 +TRANSFORMERS_TAG=2.3.5 +SOLR6_TAG=2.0.0 POSTGRES_TAG=11.7 ACTIVEMQ_TAG=5.15.8 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 378645abbf..2ab2c486a8 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -103,13 +103,11 @@ org.springframework spring-test - ${dependency.spring.version} test org.mockito mockito-core - 3.3.3 test @@ -121,13 +119,11 @@ org.postgresql postgresql - ${dependency.postgresql.version} test mysql mysql-connector-java - ${dependency.mysql.version} test diff --git a/pom.xml b/pom.xml index 1bf362bc24..0f5a772cbc 100644 --- a/pom.xml +++ b/pom.xml @@ -75,14 +75,14 @@ 3.1-HTTPCLIENT-1265 2.12.0-alfresco-patched-20191004 1.7.30 - 0.11.3 + 0.11.6 2.3.2 2.5.9 1.6.2 - 1.21-20190624-alfresco-patched + 1.24.1 5.1.9.RELEASE 7.7.10 - 4.1.1 + 4.1.2 1.4 11.0.0-alfresco-001 3.4.1.Final @@ -91,7 +91,7 @@ 1.2.5 3.2.0 - 1.3.1 + 1.3.2-RC1 42.2.14 8.0.19 @@ -172,11 +172,6 @@ win64 tgz - - org.alfresco - alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} - org.alfresco alfresco-server-root @@ -488,12 +483,6 @@ xercesImpl ${dependency.xercesImpl.version} - - - com.drewnoakes - metadata-extractor - 2.13.0 - com.github.junrar diff --git a/remote-api/README.md b/remote-api/README.md deleted file mode 100644 index 8065f12c9d..0000000000 --- a/remote-api/README.md +++ /dev/null @@ -1,41 +0,0 @@ -### Alfresco Remote API -[![Build Status](https://travis-ci.com/Alfresco/alfresco-remote-api.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-remote-api) - -Remote API is a library packaged as a jar file which is part of [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository). -The library contains the following: -* REST API framework -* 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 - -### Building and testing -The project can be built by running Maven command: -~~~ -mvn clean install -~~~ -The tests are combined in 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, for example: -~~~ -mvn clean test -Dtest=SomeTest -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql:alfresco -Ddb.username=alfresco -Ddb.password=alfresco -~~~ - -### Artifacts -The artifacts can be obtained by: -* downloading from [Alfresco repository](https://artifacts.alfresco.com/nexus/content/groups/public) -* getting as Maven dependency by adding the dependency to your pom file: -~~~ - - org.alfresco - alfresco-remote-api - version - -~~~ -and Alfresco Maven repository: -~~~ - - alfresco-maven-repo - https://artifacts.alfresco.com/nexus/content/groups/public - -~~~ -The SNAPSHOT version of the artifact is **never** published. - -### Contributing guide -Please use [this guide](CONTRIBUTING.md) to make a contribution to the project. diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 9f34d5f37a..761b001553 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -24,28 +24,23 @@ com.fasterxml.jackson.core jackson-core - ${dependency.jackson.version} com.fasterxml.jackson.core jackson-databind - ${dependency.jackson-databind.version} com.fasterxml.jackson.core jackson-annotations - ${dependency.jackson.version} javax.servlet javax.servlet-api - 3.0.1 provided org.apache.commons commons-csv - 1.8 org.apache.santuario @@ -56,7 +51,6 @@ org.alfresco.surf spring-webscripts - ${dependency.webscripts.version} javax.xml @@ -83,13 +77,11 @@ org.mockito mockito-core - 3.3.0 test org.springframework spring-test - ${dependency.spring.version} test @@ -109,14 +101,12 @@ org.alfresco.surf spring-webscripts - ${dependency.webscripts.version} tests test org.postgresql postgresql - ${dependency.postgresql.version} test @@ -157,7 +147,6 @@ org.alfresco alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} win64 tgz @@ -202,7 +191,6 @@ org.alfresco alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} linux tgz @@ -239,54 +227,6 @@ ${project.build.directory}/test-binaries/alfresco-pdf-renderer/alfresco-pdf-renderer - - osx-alfresco-pdf-renderer-test - - - mac - - - - - org.alfresco - alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} - osx - tgz - - - - - - false - maven-antrun-plugin - - - extract-alfresco-pdf-renderer-test - generate-test-resources - - run - - - ${skipTests} - - - - - - - - - - - - - - - - ${project.build.directory}/test-binaries/alfresco-pdf-renderer/alfresco-pdf-renderer - - diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java index b483948b12..ecffd579a7 100644 --- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java +++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java @@ -438,7 +438,7 @@ import org.springframework.extensions.webscripts.json.JSONUtils; { public String convert(ChildAssociationRef source) { - return source.toString(); + return org.json.simple.JSONObject.escape(source.toString()); } }); @@ -454,7 +454,7 @@ import org.springframework.extensions.webscripts.json.JSONUtils; { public String convert(AssociationRef source) { - return source.toString(); + return org.json.simple.JSONObject.escape(source.toString()); } }); diff --git a/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java b/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java index 2b0bfd7096..b08ea6d271 100644 --- a/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java +++ b/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java @@ -366,7 +366,22 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica } // Send back a request for SPNEGO authentication - logonStartAgain(context, req, resp, true); + + // MNT-21702 fixing Kerberos SSO fallback machanism for WebDAV + if (req.getRequestURL().toString().contains("webdav")) + { + if ( getLogger().isDebugEnabled()) { + getLogger().debug("WebDAV request, fallback"); + } + logonStartAgain(context, req, resp, false); + } + else + { + if ( getLogger().isDebugEnabled()) { + getLogger().debug("Non-WebDAV request, don't fallback"); + } + logonStartAgain(context, req, resp, true); + } return false; } diff --git a/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java b/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java index 3c4bcdb90f..a99a30e68b 100644 --- a/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java +++ b/remote-api/src/main/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java @@ -208,7 +208,7 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt { match = container.getRegistry().findWebScript(req.getMethod(), getScriptUrl(req)); } - catch (NotFoundException notFoundEx) + catch (NotFoundException | IllegalArgumentException Ex) { getLogger().debug(req.getMethod() + " " + getScriptUrl(req) + "not found in Public API Container."); } diff --git a/remote-api/src/test/java/org/alfresco/repo/web/scripts/solr/SOLRSerializerTest.java b/remote-api/src/test/java/org/alfresco/repo/web/scripts/solr/SOLRSerializerTest.java index 5594dfa7e0..0cb5271feb 100644 --- a/remote-api/src/test/java/org/alfresco/repo/web/scripts/solr/SOLRSerializerTest.java +++ b/remote-api/src/test/java/org/alfresco/repo/web/scripts/solr/SOLRSerializerTest.java @@ -4,57 +4,121 @@ * %% * 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 + * 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 + * 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 . * #L% */ package org.alfresco.repo.web.scripts.solr; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.Date; +import org.alfresco.model.ContentModel; import org.alfresco.repo.web.scripts.solr.SOLRSerializer.SOLRTypeConverter; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO8601DateFormat; +import org.json.JSONException; +import org.json.JSONObject; import org.junit.Test; +import org.mockito.Mockito; -public class SOLRSerializerTest +public class SOLRSerializerTest { - @Test + @Test public void testDateSerializer() { - SOLRTypeConverter typeConverter = new SOLRTypeConverter(null); - - trip(typeConverter, "1912-01-01T00:40:00-06:00", "1912-01-01T06:40:00.000Z"); - trip(typeConverter, "1812-01-01T00:40:00-06:00", "1812-01-01T06:40:00.000Z"); - trip(typeConverter, "1845-01-01T00:40:00-06:00", "1845-01-01T06:40:00.000Z"); - trip(typeConverter, "1846-01-01T00:40:00-06:00", "1846-01-01T06:40:00.000Z"); - trip(typeConverter, "1847-01-01T00:40:00-06:00", "1847-01-01T06:40:00.000Z"); - trip(typeConverter, "1848-01-01T00:40:00-06:00", "1848-01-01T06:40:00.000Z"); - - + SOLRTypeConverter typeConverter = new SOLRTypeConverter(null); + + trip(typeConverter, "1912-01-01T00:40:00-06:00", "1912-01-01T06:40:00.000Z"); + trip(typeConverter, "1812-01-01T00:40:00-06:00", "1812-01-01T06:40:00.000Z"); + trip(typeConverter, "1845-01-01T00:40:00-06:00", "1845-01-01T06:40:00.000Z"); + trip(typeConverter, "1846-01-01T00:40:00-06:00", "1846-01-01T06:40:00.000Z"); + trip(typeConverter, "1847-01-01T00:40:00-06:00", "1847-01-01T06:40:00.000Z"); + trip(typeConverter, "1848-01-01T00:40:00-06:00", "1848-01-01T06:40:00.000Z"); + } - - - private void trip( SOLRTypeConverter typeConverter, String iso, String zulu) - { - Date testDate = ISO8601DateFormat.parse(iso); - String strDate = typeConverter.INSTANCE.convert(String.class, testDate); - assertEquals(zulu, strDate); - } + + private void trip(SOLRTypeConverter typeConverter, String iso, String zulu) + { + Date testDate = ISO8601DateFormat.parse(iso); + String strDate = typeConverter.INSTANCE.convert(String.class, testDate); + assertEquals(zulu, strDate); + } + + /** + * Test SOLR Serialization including values with special characters for ChildAssociationRef + */ + @Test + public void testChildAssociationRefToJSONString() + { + SOLRSerializer solrSerializer = new SOLRSerializer(); + solrSerializer.setDictionaryService(Mockito.mock(DictionaryService.class)); + solrSerializer.setNamespaceService(Mockito.mock(NamespaceService.class)); + solrSerializer.init(); + + // Create a Child QName including special character \ + QName childQName = QName.createQName("hello", "wo\rld"); + + ChildAssociationRef childAssociationRef = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + new NodeRef("workspace://SpacesStore/parent"), childQName, + new NodeRef("workspace://SpacesStore/child")); + String validJsonString = solrSerializer.serializeToJSONString(childAssociationRef); + String jsonObjectString = String.format("{ \"key\": \"%s\" }", validJsonString); + + try + { + new JSONObject(jsonObjectString); + } + catch (JSONException e) + { + assertTrue("JSON String " + jsonObjectString + " is not a valid JSON", false); + } + } + + /** + * Test SOLR Serialization including values with special characters for AssociationRef + */ + @Test + public void testAssociationRefToJSONString() + { + SOLRSerializer solrSerializer = new SOLRSerializer(); + solrSerializer.setDictionaryService(Mockito.mock(DictionaryService.class)); + solrSerializer.setNamespaceService(Mockito.mock(NamespaceService.class)); + solrSerializer.init(); + AssociationRef associationRef = new AssociationRef( + new NodeRef("workspace://SpacesStore/wo\rld"), + ContentModel.ASSOC_ATTACHMENTS, + new NodeRef("workspace://SpacesStore/hello")); + String validJsonString = solrSerializer.serializeToJSONString(associationRef); + String jsonObjectString = String.format("{ \"key\": \"%s\" }", validJsonString); + + try + { + new JSONObject(jsonObjectString); + } + catch (JSONException e) + { + assertTrue("JSON String " + jsonObjectString + " is not a valid JSON", false); + } + } + } diff --git a/repository/README.md b/repository/README.md deleted file mode 100644 index ae8a2cd64a..0000000000 --- a/repository/README.md +++ /dev/null @@ -1,41 +0,0 @@ -### Alfresco Repository -[![Build Status](https://travis-ci.com/Alfresco/alfresco-repository.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-repository) - -Repository is a library packaged as a jar file which is part of [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository). -The library contains the following: -* DAOs and SQL scripts -* Various Service implementations -* Utility classes - -### Building and testing -The project can be built by running Maven command: -~~~ -mvn clean install -~~~ -The tests are combined in 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, 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 -~~~ - -### Artifacts -The artifacts can be obtained by: -* downloading from [Alfresco repository](https://artifacts.alfresco.com/nexus/content/groups/public) -* getting as Maven dependency by adding the dependency to your pom file: -~~~ - - org.alfresco - alfresco-repository - version - -~~~ -and Alfresco Maven repository: -~~~ - - alfresco-maven-repo - https://artifacts.alfresco.com/nexus/content/groups/public - -~~~ -The SNAPSHOT version of the artifact is **never** published. - -### Contributing guide -Please use [this guide](CONTRIBUTING.md) to make a contribution to the project. diff --git a/repository/pom.xml b/repository/pom.xml index d65694c0ac..07aae8ee3d 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -19,7 +19,6 @@ org.alfresco alfresco-jlan-embed - ${dependency.alfresco-jlan.version} * @@ -40,7 +39,6 @@ org.alfresco alfresco-heartbeat-data-sender - ${dependency.alfresco-hb-data-sender.version} com.sun.mail @@ -55,17 +53,14 @@ commons-dbcp commons-dbcp - 1.4-DBCP330 commons-fileupload commons-fileupload - 1.4 org.apache.commons commons-compress - 1.19 org.apache.commons @@ -75,17 +70,14 @@ commons-codec commons-codec - 1.14 commons-beanutils commons-beanutils - 1.9.4 commons-collections commons-collections - 3.2.2 commons-io @@ -129,7 +121,6 @@ org.springframework spring-core - ${dependency.spring.version} @@ -142,7 +133,6 @@ org.springframework spring-orm - ${dependency.spring.version} @@ -155,17 +145,14 @@ org.springframework spring-context - ${dependency.spring.version} org.springframework spring-context-support - ${dependency.spring.version} org.springframework spring-web - ${dependency.spring.version} org.subethamail @@ -226,12 +213,10 @@ xerces xercesImpl - 2.12.0-alfresco-patched-20191004 xalan xalan - 2.7.2-alfresco xml-apis @@ -272,7 +257,6 @@ org.apache.pdfbox pdfbox - ${dependency.pdfbox.version} org.apache.pdfbox @@ -379,7 +363,6 @@ javax.servlet javax.servlet-api - 3.0.1 provided @@ -392,19 +375,16 @@ com.fasterxml.jackson.core jackson-databind - ${dependency.jackson-databind.version} org.alfresco.surf spring-surf-core-configservice - ${dependency.webscripts.version} org.alfresco.surf spring-webscripts - ${dependency.webscripts.version} com.sun @@ -427,7 +407,6 @@ org.alfresco.surf spring-webscripts-api - ${dependency.webscripts.version} @@ -451,7 +430,6 @@ com.google.guava guava - 28.2-jre org.springframework.security @@ -800,13 +778,11 @@ org.mockito mockito-core - 3.3.0 test org.springframework spring-test - ${dependency.spring.version} test @@ -850,19 +826,16 @@ org.postgresql postgresql - ${dependency.postgresql.version} test mysql mysql-connector-java - ${dependency.mysql.version} test org.mariadb.jdbc mariadb-java-client - ${dependency.mariadb.version} test @@ -874,13 +847,11 @@ org.antlr gunit - ${dependency.antlr.version} test org.alfresco.surf spring-webscripts - ${dependency.webscripts.version} tests test @@ -938,7 +909,6 @@ org.alfresco alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} win64 tgz @@ -983,7 +953,6 @@ org.alfresco alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} linux tgz @@ -1020,54 +989,6 @@ ${project.build.directory}/test-binaries/alfresco-pdf-renderer/alfresco-pdf-renderer - - osx-alfresco-pdf-renderer-test - - - mac - - - - - org.alfresco - alfresco-pdf-renderer - ${dependency.alfresco-pdf-renderer.version} - osx - tgz - - - - - - false - maven-antrun-plugin - - - extract-alfresco-pdf-renderer-test - generate-test-resources - - run - - - ${skipTests} - - - - - - - - - - - - - - - - ${project.build.directory}/test-binaries/alfresco-pdf-renderer/alfresco-pdf-renderer - - diff --git a/repository/src/main/java/org/alfresco/opencmis/TransactionAwareHolder.java b/repository/src/main/java/org/alfresco/opencmis/TransactionAwareHolder.java index a5c5991583..e35d75d413 100644 --- a/repository/src/main/java/org/alfresco/opencmis/TransactionAwareHolder.java +++ b/repository/src/main/java/org/alfresco/opencmis/TransactionAwareHolder.java @@ -81,22 +81,19 @@ public class TransactionAwareHolder extends Holder { this.internalHolder = internalHolder; this.value = internalHolder.getValue(); - txListener = new TxAwareHolderListener(); } @Override public T getValue() { - if (TransactionSynchronizationManager.isSynchronizationActive()) - { - AlfrescoTransactionSupport.bindListener(txListener); - } + registerTxListenerIfNeeded(); return this.value; } @Override public void setValue(T value) { + registerTxListenerIfNeeded(); this.value = value; } @@ -109,6 +106,17 @@ public class TransactionAwareHolder extends Holder '}'; } + // MNT-21800 CMIS Web Service Check Out returns error + private void registerTxListenerIfNeeded() + { + if (this.txListener == null && TransactionSynchronizationManager.isSynchronizationActive()) + { + TxAwareHolderListener listener = new TxAwareHolderListener(); + AlfrescoTransactionSupport.bindListener(listener); + this.txListener = listener; + } + } + private class TxAwareHolderListener extends TransactionListenerAdapter { @Override diff --git a/repository/src/main/java/org/alfresco/repo/content/metadata/TikaAutoMetadataExtracter.java b/repository/src/main/java/org/alfresco/repo/content/metadata/TikaAutoMetadataExtracter.java index 74bec7fe45..63c1ad441a 100644 --- a/repository/src/main/java/org/alfresco/repo/content/metadata/TikaAutoMetadataExtracter.java +++ b/repository/src/main/java/org/alfresco/repo/content/metadata/TikaAutoMetadataExtracter.java @@ -68,11 +68,10 @@ public class TikaAutoMetadataExtracter extends TikaPoweredMetadataExtracter protected static Log logger = LogFactory.getLog(TikaAutoMetadataExtracter.class); private static AutoDetectParser parser; private static TikaConfig config; - private static String EXIF_IMAGE_HEIGHT_TAG = "Exif Image Height"; - private static String EXIF_IMAGE_WIDTH_TAG = "Exif Image Width"; + private static String EXIF_IMAGE_HEIGHT_TAG = "Exif SubIFD:Exif Image Height"; + private static String EXIF_IMAGE_WIDTH_TAG = "Exif SubIFD:Exif Image Width"; private static String JPEG_IMAGE_HEIGHT_TAG = "Image Height"; private static String JPEG_IMAGE_WIDTH_TAG = "Image Width"; - private static String COMPRESSION_TAG = "Compression"; public static ArrayList SUPPORTED_MIMETYPES; private static ArrayList buildMimeTypes(TikaConfig tikaConfig) @@ -122,24 +121,19 @@ public class TikaAutoMetadataExtracter extends TikaPoweredMetadataExtracter */ @Override protected Map extractSpecific(Metadata metadata, - Map properties, Map headers) + Map properties, Map headers) { - if(MimetypeMap.MIMETYPE_IMAGE_JPEG.equals(metadata.get(Metadata.CONTENT_TYPE))) + if (MimetypeMap.MIMETYPE_IMAGE_JPEG.equals(metadata.get(Metadata.CONTENT_TYPE))) { //check if the image has exif information - if(metadata.get(EXIF_IMAGE_WIDTH_TAG) != null - && metadata.get(EXIF_IMAGE_HEIGHT_TAG) != null - && metadata.get(COMPRESSION_TAG) != null) + if (metadata.get(EXIF_IMAGE_WIDTH_TAG) != null && metadata.get(EXIF_IMAGE_HEIGHT_TAG) != null) { //replace the exif size properties that will be embedded in the node with //the guessed dimensions from Tika - putRawValue(TIFF.IMAGE_LENGTH.getName(), extractSize(metadata.get(EXIF_IMAGE_HEIGHT_TAG)), properties); - putRawValue(TIFF.IMAGE_WIDTH.getName(), extractSize(metadata.get(EXIF_IMAGE_WIDTH_TAG)), properties); - putRawValue(JPEG_IMAGE_HEIGHT_TAG, metadata.get(EXIF_IMAGE_HEIGHT_TAG), properties); - putRawValue(JPEG_IMAGE_WIDTH_TAG, metadata.get(EXIF_IMAGE_WIDTH_TAG), properties); + putRawValue(TIFF.IMAGE_LENGTH.getName(), extractSize(metadata.get(JPEG_IMAGE_HEIGHT_TAG)), properties); + putRawValue(TIFF.IMAGE_WIDTH.getName(), extractSize(metadata.get(JPEG_IMAGE_WIDTH_TAG)), properties); } } return properties; } - } diff --git a/repository/src/main/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java b/repository/src/main/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java index 774cccc9bd..8d7b54d07d 100644 --- a/repository/src/main/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java +++ b/repository/src/main/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java @@ -430,8 +430,8 @@ public class ADMAccessControlListDAO implements AccessControlListDAO // { // setFixedAcls(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false); // } - // Already replaced - if(acl.equals(sharedAclToReplace)) + // Still has old shared ACL or already replaced + if(acl.equals(sharedAclToReplace) || acl.equals(mergeFrom)) { propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren); } diff --git a/repository/src/main/java/org/alfresco/repo/rule/ruletrigger/OnPropertyUpdateRuleTrigger.java b/repository/src/main/java/org/alfresco/repo/rule/ruletrigger/OnPropertyUpdateRuleTrigger.java index 75407a717a..0122b60b2a 100644 --- a/repository/src/main/java/org/alfresco/repo/rule/ruletrigger/OnPropertyUpdateRuleTrigger.java +++ b/repository/src/main/java/org/alfresco/repo/rule/ruletrigger/OnPropertyUpdateRuleTrigger.java @@ -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 . - * #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 . + * #L% + */ package org.alfresco.repo.rule.ruletrigger; import java.io.Serializable; @@ -141,7 +141,7 @@ public class OnPropertyUpdateRuleTrigger extends RuleTriggerAbstractBase for (QName name : keys) { // Skip rule firing on this content property for performance reasons - if (name.equals(ContentModel.PROP_PREFERENCE_VALUES)) + if (name.equals(ContentModel.PROP_PREFERENCE_VALUES) || name.equals(ContentModel.PROP_CASCADE_CRC)) { continue; } diff --git a/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSet.java b/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSet.java index aef0e99ac1..bc55077c99 100644 --- a/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSet.java +++ b/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSet.java @@ -240,6 +240,11 @@ public class DBResultSet extends AbstractResultSet nodeRefs[n+1] = nodeRef == null ? null : tenantService.getBaseName(nodeRef); } } - } + } + + public NodeService getNodeService() + { + return nodeService; + } } diff --git a/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSetRow.java b/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSetRow.java index 9ee6f6c8c4..40de48db15 100644 --- a/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSetRow.java +++ b/repository/src/main/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBResultSetRow.java @@ -25,11 +25,13 @@ */ package org.alfresco.repo.search.impl.querymodel.impl.db; +import java.io.Serializable; import java.util.Map; import org.alfresco.repo.search.AbstractResultSetRow; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.namespace.QName; /** * @author Andy @@ -82,6 +84,13 @@ public class DBResultSetRow extends AbstractResultSetRow public float getScore(String selectorName) { throw new UnsupportedOperationException(); + } + + @Override + protected Map getDirectProperties() + { + DBResultSet rs = (DBResultSet) getResultSet(); + return rs.getNodeService().getProperties(rs.getNodeRef(getIndex())); } diff --git a/repository/src/main/java/org/alfresco/repo/security/sync/ldap/LDAPUserRegistry.java b/repository/src/main/java/org/alfresco/repo/security/sync/ldap/LDAPUserRegistry.java index c85f6af5cc..d72512d726 100644 --- a/repository/src/main/java/org/alfresco/repo/security/sync/ldap/LDAPUserRegistry.java +++ b/repository/src/main/java/org/alfresco/repo/security/sync/ldap/LDAPUserRegistry.java @@ -54,6 +54,7 @@ import javax.naming.InvalidNameException; import javax.naming.Name; import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.ServiceUnavailableException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; @@ -882,6 +883,16 @@ public class LDAPUserRegistry implements UserRegistry, LDAPNameResolver, Initial continue; } } + catch (ServiceUnavailableException | CommunicationException e) + { + // MNT-21614: Check & fail if communication breaks due to ServiceUnavailableException or CommunicationException + if (e.getMessage() != null) + { + Object[] params = {e.getLocalizedMessage() }; + throw new AlfrescoRuntimeException("synchronization.err.ldap.search", params, e); + } + continue; + } catch (NamingException e) { // Check if it is a timeout and fail diff --git a/repository/src/main/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java b/repository/src/main/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java index 84701bef66..4a45bc649b 100644 --- a/repository/src/main/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java +++ b/repository/src/main/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java @@ -691,20 +691,18 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent return new ArrayList(visited); } - + /** Get properties that we want to be indexed. */ protected Map getProperties(Long nodeId) { - Map props = null; - // ALF-10641 - // Residual properties are un-indexed -> break serlialisation + // Residual properties are un-indexed -> break serialisation nodeDAO.setCheckNodeConsistency(); Map sourceProps = nodeDAO.getNodeProperties(nodeId); - props = new HashMap((int)(sourceProps.size() * 1.3)); + Map props = new HashMap<>(sourceProps.size()); for(QName propertyQName : sourceProps.keySet()) { PropertyDefinition propDef = dictionaryService.getProperty(propertyQName); - if(propDef != null) + if(propDef != null && propDef.isIndexed()) { props.put(propertyQName, sourceProps.get(propertyQName)); } @@ -865,7 +863,22 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent } else { - throw new AlfrescoRuntimeException("Nodes with no type are ignored by SOLR"); + QName typeQName = null; + TypeDefinition typeDefinition = null; + + String errorMessage = "NodeId " + nodeId + " with nodeRef " + nodeRef; + + typeQName = nodeDAO.getNodeType(nodeId); + if (typeQName != null) + { + errorMessage += " has type " + typeQName + ", but this type is not registered in DictionaryService."; + } + else + { + errorMessage += " has no type."; + } + + throw new AlfrescoRuntimeException(errorMessage + " It will be ignored by SOLR."); } } diff --git a/repository/src/main/resources/alfresco/subsystems/Search/solr4/solr-search-context.xml b/repository/src/main/resources/alfresco/subsystems/Search/solr4/solr-search-context.xml index c111fb94ac..52f5a18f82 100644 --- a/repository/src/main/resources/alfresco/subsystems/Search/solr4/solr-search-context.xml +++ b/repository/src/main/resources/alfresco/subsystems/Search/solr4/solr-search-context.xml @@ -153,18 +153,15 @@ - - - - - - - + + + + diff --git a/repository/src/test/java/org/alfresco/repo/domain/permissions/FixedAclUpdaterTest.java b/repository/src/test/java/org/alfresco/repo/domain/permissions/FixedAclUpdaterTest.java index 16b787afb2..70566e8d0f 100644 --- a/repository/src/test/java/org/alfresco/repo/domain/permissions/FixedAclUpdaterTest.java +++ b/repository/src/test/java/org/alfresco/repo/domain/permissions/FixedAclUpdaterTest.java @@ -25,7 +25,10 @@ */ package org.alfresco.repo.domain.permissions; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.alfresco.model.ContentModel; @@ -41,6 +44,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.repo.transaction.TransactionListenerAdapter; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; @@ -69,6 +73,7 @@ public class FixedAclUpdaterTest extends TestCase private Repository repository; private FixedAclUpdater fixedAclUpdater; private NodeRef folderAsyncCallNodeRef; + private NodeRef folderAsyncCallWithCreateNodeRef; private NodeRef folderSyncCallNodeRef; private PermissionsDaoComponent permissionsDaoComponent; private PermissionService permissionService; @@ -100,6 +105,10 @@ public class FixedAclUpdaterTest extends TestCase filesPerLevel); folderSyncCallNodeRef = txnHelper.doInTransaction(cb2); + RetryingTransactionCallback cb3 = createFolderHierchyCallback(home, fileFolderService, + "rootFolderAsyncWithCreateCall", filesPerLevel); + folderAsyncCallWithCreateNodeRef = txnHelper.doInTransaction(cb3); + // change setFixedAclMaxTransactionTime to lower value so setInheritParentPermissions on created folder // hierarchy require async call setFixedAclMaxTransactionTime(permissionsDaoComponent, home, 50); @@ -147,8 +156,10 @@ public class FixedAclUpdaterTest extends TestCase aspect.add(ContentModel.ASPECT_TEMPORARY); nodeDAO.addNodeAspects(nodeDAO.getNodePair(folderAsyncCallNodeRef).getFirst(), aspect); nodeDAO.addNodeAspects(nodeDAO.getNodePair(folderSyncCallNodeRef).getFirst(), aspect); + nodeDAO.addNodeAspects(nodeDAO.getNodePair(folderAsyncCallWithCreateNodeRef).getFirst(), aspect); fileFolderService.delete(folderAsyncCallNodeRef); fileFolderService.delete(folderSyncCallNodeRef); + fileFolderService.delete(folderAsyncCallWithCreateNodeRef); return null; }, false, true); } @@ -189,7 +200,34 @@ public class FixedAclUpdaterTest extends TestCase testWork(folderAsyncCallNodeRef, true); } + @Test + public void testAsyncWithNodeCreation() + { + testWorkWithNodeCreation(folderAsyncCallWithCreateNodeRef, true); + } + private void testWork(NodeRef folderRef, boolean asyncCall) + { + setPermissionsOnTree(folderRef, asyncCall); + triggerFixedACLJob(folderRef); + } + + private void testWorkWithNodeCreation(NodeRef folderRef, boolean asyncCall) + { + setPermissionsOnTree(folderRef, asyncCall); + + // MNT-21847 - Create a new content in folder that has the aspect applied + txnHelper.doInTransaction((RetryingTransactionCallback) () -> { + NodeRef folderWithPendingAcl = getFirstFolderWithAclPending(folderRef); + assertNotNull("No children folders were found with pendingFixACl aspect", folderWithPendingAcl); + createFile(fileFolderService, folderWithPendingAcl, "NewFile", ContentModel.TYPE_CONTENT); + return null; + }, false, true); + + triggerFixedACLJob(folderRef); + } + + private void setPermissionsOnTree(NodeRef folderRef, boolean asyncCall) { // kick it off by setting inherit parent permissions == false txnHelper.doInTransaction((RetryingTransactionCallback) () -> { @@ -203,21 +241,61 @@ public class FixedAclUpdaterTest extends TestCase assertTrue("There are no nodes to process", getNodesCountWithPendingFixedAclAspect() > 0); return null; }, false, true); + } - // run the fixedAclUpdater until there is nothing more to fix (running the updater - // may create more to fix up) + private void triggerFixedACLJob(NodeRef folder) + { + // run the fixedAclUpdater until there is nothing more to fix (running the updater may create more to fix up) or + // the count doesn't change, meaning we have a problem. txnHelper.doInTransaction((RetryingTransactionCallback) () -> { int count = 0; + int previousCount = 0; do { + previousCount = count; count = fixedAclUpdater.execute(); - } while (count > 0); + } while (count > 0 && previousCount != count); return null; }, false, true); // check if nodes with ASPECT_PENDING_FIX_ACL are processed txnHelper.doInTransaction((RetryingTransactionCallback) () -> { assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect()); + //Remove the tree that failed so it does not influence the other test results + removeNodesWithPendingAcl(folder); + return null; + }, false, true); + } + + private NodeRef getFirstFolderWithAclPending(NodeRef parentNodeRef) + { + NodeRef folderWithPendingFixedAcl = null; + List primaryChildFolders = fileFolderService.listFolders(parentNodeRef); + for (int i = 0; i < primaryChildFolders.size(); i++) + { + NodeRef thisChildFolder = primaryChildFolders.get(i).getNodeRef(); + Long thisChildNodeId = nodeDAO.getNodePair(thisChildFolder).getFirst(); + if (nodeDAO.hasNodeAspect(thisChildNodeId, ContentModel.ASPECT_PENDING_FIX_ACL)) + { + folderWithPendingFixedAcl = thisChildFolder; + break; + } + + if (folderWithPendingFixedAcl == null) + { + folderWithPendingFixedAcl = getFirstFolderWithAclPending(thisChildFolder); + } + } + return folderWithPendingFixedAcl; + } + + private void removeNodesWithPendingAcl(NodeRef folder) + { + txnHelper.doInTransaction((RetryingTransactionCallback) () -> { + Set aspect = new HashSet<>(); + aspect.add(ContentModel.ASPECT_TEMPORARY); + nodeDAO.addNodeAspects(nodeDAO.getNodePair(folder).getFirst(), aspect); + fileFolderService.delete(folder); return null; }, false, true); } diff --git a/repository/src/test/java/org/alfresco/repo/rule/ruletrigger/RuleTriggerTest.java b/repository/src/test/java/org/alfresco/repo/rule/ruletrigger/RuleTriggerTest.java index 5412b6adc6..055c30daf8 100644 --- a/repository/src/test/java/org/alfresco/repo/rule/ruletrigger/RuleTriggerTest.java +++ b/repository/src/test/java/org/alfresco/repo/rule/ruletrigger/RuleTriggerTest.java @@ -25,6 +25,7 @@ */ package org.alfresco.repo.rule.ruletrigger; +import java.util.Random; import org.alfresco.model.ContentModel; import org.alfresco.model.ForumModel; import org.alfresco.repo.content.MimetypeMap; @@ -426,7 +427,33 @@ public class RuleTriggerTest extends BaseSpringTest // Check to see if the rule type has been triggered assertTrue(ruleType.rulesTriggered); assertEquals(3, ruleType.triggerCount); - } + } + @Test + public void testOnPropertyUpdateRuleTrigger() + { + NodeRef nodeRef1 = this.nodeService.createNode(this.rootNodeRef, + ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, + ContentModel.TYPE_CONTAINER).getChildRef(); + + ContentWriter contentWriter = this.contentService.getWriter(nodeRef1, ContentModel.PROP_CONTENT, true); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentWriter.setEncoding("UTF-8"); + contentWriter.putContent("some content"); + + Random rand=new Random(); + this.nodeService.setProperty(nodeRef1, ContentModel.PROP_CASCADE_CRC, rand.nextLong()); + // Terminate the transaction + TestTransaction.flagForCommit(); + TestTransaction.end(); + TestTransaction.start(); + + TestRuleType contentUpdate = createTestRuleType(ON_PROPERTY_UPDATE_TRIGGER); + this.nodeService.setProperty(nodeRef1, ContentModel.PROP_CASCADE_CRC, rand.nextLong()); + + assertFalse(contentUpdate.rulesTriggered); + assertEquals("trigger count not matching",0,contentUpdate.triggerCount); + + } private TestRuleType createTestRuleType(String ruleTriggerName) { diff --git a/repository/src/test/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBQueryTest.java b/repository/src/test/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBQueryTest.java index f0165212c0..e9c6ae0117 100644 --- a/repository/src/test/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBQueryTest.java +++ b/repository/src/test/java/org/alfresco/repo/search/impl/querymodel/impl/db/DBQueryTest.java @@ -994,6 +994,30 @@ public class DBQueryTest implements DictionaryListener results.getResultSetMetaData(); results.close(); } + + @Test + public void testGetValueForTransactionalQuery() + { + String query = "=TYPE:\"cm:folder\" "; + queryUsingGetValue(SearchService.LANGUAGE_FTS_ALFRESCO, query); + } + + public void queryUsingGetValue(String ql, String query) + { + SearchParameters sp = new SearchParameters(); + sp.setLanguage(ql); + sp.setQueryConsistency(QueryConsistency.TRANSACTIONAL); + sp.setQuery(query); + sp.addStore(rootNodeRef.getStoreRef()); + ResultSet results = serviceRegistry.getSearchService().query(sp); + + for (int i = 0; i < results.length(); i++) { + ResultSetRow row = results.getRow(i); + assertNotNull(row.getValue(ContentModel.PROP_NODE_UUID)); + } + results.getResultSetMetaData(); + results.close(); + } private static class UnknownDataType implements Serializable { diff --git a/repository/src/test/java/org/alfresco/repo/security/sync/LDAPUserRegistryTest.java b/repository/src/test/java/org/alfresco/repo/security/sync/LDAPUserRegistryTest.java index 96b192246c..1cade12eae 100644 --- a/repository/src/test/java/org/alfresco/repo/security/sync/LDAPUserRegistryTest.java +++ b/repository/src/test/java/org/alfresco/repo/security/sync/LDAPUserRegistryTest.java @@ -34,10 +34,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import javax.naming.CompositeName; -import javax.naming.Name; +import javax.naming.CommunicationException; import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.ServiceUnavailableException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.InitialDirContext; @@ -144,4 +144,52 @@ public class LDAPUserRegistryTest are.getCause().getMessage().contains(LDAPUserRegistry.NAMING_TIMEOUT_EXCEPTION_MESSAGE)); } } + + /** + * Test for MNT-21614: Check & fail if communication breaks due to javax.naming.ServiceUnavailableException + */ + @Test + public void testTimeoutDuringSyncForServiceUnavailableException() throws Exception + { + LDAPUserRegistry userRegistry = createRegistry(); + + when(initialDirContext.getAttributes(eq(LDAPUserRegistry.jndiName(MEMBER_ATTRIBUTE_VALUE)), any())) + .thenThrow(new ServiceUnavailableException(" test.")); + try + { + userRegistry.getGroups(new Date()); + fail("The process should fail with an exception"); + } + catch (AlfrescoRuntimeException are) + { + assertEquals("The error message is not of the right format.", + "synchronization.err.ldap.search", are.getMsgId()); + assertTrue("The error message was not caused by timeout.", + are.getCause().getMessage().contains(" test.")); + } + } + + /** + * Test for MNT-21614: Check & fail if communication breaks due to javax.naming.CommunicationException + */ + @Test + public void testTimeoutDuringSyncForCommunicationException() throws Exception + { + LDAPUserRegistry userRegistry = createRegistry(); + + when(initialDirContext.getAttributes(eq(LDAPUserRegistry.jndiName(MEMBER_ATTRIBUTE_VALUE)), any())) + .thenThrow(new CommunicationException(" test.")); + try + { + userRegistry.getGroups(new Date()); + fail("The process should fail with an exception"); + } + catch (AlfrescoRuntimeException are) + { + assertEquals("The error message is not of the right format.", + "synchronization.err.ldap.search", are.getMsgId()); + assertTrue("The error message was not caused by timeout.", + are.getCause().getMessage().contains(" test.")); + } + } } diff --git a/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentTest.java b/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentTest.java index abab9c9eb7..1b5ac2058f 100644 --- a/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentTest.java +++ b/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentTest.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.dictionary.DictionaryDAO; import org.alfresco.repo.dictionary.M2Model; @@ -68,6 +69,7 @@ import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.springframework.extensions.surf.util.I18NUtil; /** * Tests tracking component @@ -1491,4 +1493,99 @@ public class SOLRTrackingComponentTest extends BaseSpringTest return txs; } } + + @Test + public void testGetNodeMetaDataWithNoType() + { + long startTime = System.currentTimeMillis(); + + SOLRTest st = new SOLRTestWithNoType(txnHelper, fileFolderService, nodeDAO, qnameDAO, nodeService, dictionaryService, rootNodeRef, "testNodeMetaDataNullPropertyValue", true, true); + List createdTransactions = st.buildTransactions(); + + List txns = getTransactions(null, startTime-1000, null, null, 100); + + int[] updates = new int[] {2}; + int[] deletes = new int[] {0}; + List checkedTransactions = checkTransactions(txns, createdTransactions, updates, deletes); + + NodeParameters nodeParameters = new NodeParameters(); + nodeParameters.setTransactionIds(getTransactionIds(checkedTransactions)); + getNodes(nodeParameters, st); + + + NodeMetaDataParameters nodeMetaDataParams = new NodeMetaDataParameters(); + nodeMetaDataParams.setNodeIds(st.getNodeIds()); + try + { + getNodeMetaData(nodeMetaDataParams, null, st); + } + catch (AlfrescoRuntimeException are) + { + if (!are.getMessage().contains("It will be ignored by SOLR")) + { + throw are; + } + } + + } + + private static class SOLRTestWithNoType extends SOLRTest + { + private NodeRef container; + private NodeRef content; + + SOLRTestWithNoType( + RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, + NodeDAO nodeDAO, QNameDAO qnameDAO, NodeService nodeService, DictionaryService dictionaryService, + NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks) + { + super(txnHelper, fileFolderService, nodeDAO, qnameDAO, nodeService, dictionaryService,rootNodeRef, containerName, doNodeChecks, doMetaDataChecks); + } + + public int getExpectedNumNodes() + { + return 2; + } + + protected List buildTransactionsInternal() + { + ArrayList txs = new ArrayList(2); + + txs.add(txnHelper.doInTransaction(new RetryingTransactionCallback() + { + public Long execute() throws Throwable + { + PropertyMap props = new PropertyMap(); + props.put(ContentModel.PROP_NAME, "ContainerWithNoType"); + container = nodeService.createNode( + rootNodeRef, + ContentModel.ASSOC_CHILDREN, + ContentModel.ASSOC_CHILDREN, + ContentModel.TYPE_FOLDER, + props).getChildRef(); + + Long containerId = nodeDAO.getNodePair(container).getFirst(); + + content = nodeDAO.newNode( + containerId, + ContentModel.ASSOC_CHILDREN, + ContentModel.ASSOC_CHILDREN, + new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"), + null, + QName.createQName("{nonExisting}nonExisting"), + I18NUtil.getLocale(), + null, + null).getChildNode().getNodeRef(); + + return nodeDAO.getNodeRefStatus(container).getDbTxnId(); + } + })); + + setExpectedNodeStatus(container, NodeStatus.UPDATED); + setExpectedNodeStatus(content, NodeStatus.UPDATED); + + return txs; + } + } + } \ No newline at end of file diff --git a/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentUnitTest.java b/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentUnitTest.java new file mode 100644 index 0000000000..316f5398f0 --- /dev/null +++ b/repository/src/test/java/org/alfresco/repo/solr/SOLRTrackingComponentUnitTest.java @@ -0,0 +1,115 @@ +/* + * #%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 . + * #L% + */ +package org.alfresco.repo.solr; + +import static java.util.Collections.emptyMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.repo.domain.node.NodeDAO; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** Unit tests for {@link org.alfresco.repo.solr.SOLRTrackingComponent}. */ +public class SOLRTrackingComponentUnitTest +{ + /** A pair of QNames for use in the tests. */ + private static final QName FIRST_PROPERTY = QName.createQName("the://first/property"); + private static final QName SECOND_PROPERTY = QName.createQName("the://second/property"); + /** A node id for use in the tests. */ + private static final long NODE_ID = 123L; + + /** The class under test. */ + @InjectMocks + private SOLRTrackingComponentImpl solrTrackingComponent; + @Mock + private NodeDAO nodeDAO; + @Mock + private DictionaryService dictionaryService; + + @Before + public void setUp() + { + initMocks(this); + } + + /** Check that properties of different types can be returned. */ + @Test + public void testGetProperties_indexedPropertiesPassedThrough() + { + Map propertiesFromDB = Map.of(FIRST_PROPERTY, "value1", SECOND_PROPERTY, 2); + when(nodeDAO.getNodeProperties(NODE_ID)).thenReturn(propertiesFromDB); + PropertyDefinition firstDefinition = mock(PropertyDefinition.class); + when(firstDefinition.isIndexed()).thenReturn(true); + when(dictionaryService.getProperty(FIRST_PROPERTY)).thenReturn(firstDefinition); + PropertyDefinition secondDefinition = mock(PropertyDefinition.class); + when(secondDefinition.isIndexed()).thenReturn(true); + when(dictionaryService.getProperty(SECOND_PROPERTY)).thenReturn(secondDefinition); + + Map properties = solrTrackingComponent.getProperties(NODE_ID); + + assertEquals("Expected both properties to be returned.", propertiesFromDB, properties); + } + + /** Check that a property is not indexed if it is not registered in the dictionary service. */ + @Test + public void testGetProperties_propertyWithoutModelIsNotIndexed() + { + Map propertiesFromDB = Map.of(FIRST_PROPERTY, "value1"); + when(nodeDAO.getNodeProperties(NODE_ID)).thenReturn(propertiesFromDB); + when(dictionaryService.getProperty(FIRST_PROPERTY)).thenReturn(null); + + Map properties = solrTrackingComponent.getProperties(NODE_ID); + + assertEquals("Expected residual property to be skipped.", emptyMap(), properties); + } + + /** Check that a property is not indexed if the model contains */ + @Test + public void testGetProperties_propertySkippedIfIndexFalseSet() + { + Map propertiesFromDB = Map.of(FIRST_PROPERTY, "value1"); + when(nodeDAO.getNodeProperties(NODE_ID)).thenReturn(propertiesFromDB); + PropertyDefinition firstDefinition = mock(PropertyDefinition.class); + when(firstDefinition.isIndexed()).thenReturn(false); + when(dictionaryService.getProperty(FIRST_PROPERTY)).thenReturn(firstDefinition); + + Map properties = solrTrackingComponent.getProperties(NODE_ID); + + assertEquals("Unexpected property when index enabled set to false.", emptyMap(), properties); + } +}