mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			53 Commits
		
	
	
		
			9.35
			...
			dev-dhrn-t
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					c9bce5170d | ||
| 
						 | 
					9bd54efc10 | ||
| 
						 | 
					3c81ec949e | ||
| 
						 | 
					53704a2c58 | ||
| 
						 | 
					b4455f7d60 | ||
| 
						 | 
					0617fbb0bf | ||
| 
						 | 
					f748334f1e | ||
| 
						 | 
					08748e8af5 | ||
| 
						 | 
					ce62fb1da3 | ||
| 
						 | 
					34f360211f | ||
| 
						 | 
					b559e78827 | ||
| 
						 | 
					1add8a0f08 | ||
| 
						 | 
					5eb8767f4c | ||
| 
						 | 
					7fb3386413 | ||
| 
						 | 
					22945a30ea | ||
| 
						 | 
					fc531f64ed | ||
| 
						 | 
					98090ac48c | ||
| 
						 | 
					33b64f483d | ||
| 
						 | 
					5e2d939f4e | ||
| 
						 | 
					26dbcd3e79 | ||
| 
						 | 
					8ec9fa5f5e | ||
| 
						 | 
					578becd586 | ||
| 
						 | 
					1f6774f2ef | ||
| 
						 | 
					9ff5f3b843 | ||
| 
						 | 
					9e3bb59067 | ||
| 
						 | 
					db47063830 | ||
| 
						 | 
					562479bde4 | ||
| 
						 | 
					e738e0a0fb | ||
| 
						 | 
					eb703c19aa | ||
| 
						 | 
					b772205539 | ||
| 
						 | 
					b9c6b59129 | ||
| 
						 | 
					cf7ce72209 | ||
| 
						 | 
					7a58014c32 | ||
| 
						 | 
					e964aab211 | ||
| 
						 | 
					2d3cac3c27 | ||
| 
						 | 
					3a495f7b3f | ||
| 
						 | 
					949e257f19 | ||
| 
						 | 
					dfb34140ac | ||
| 
						 | 
					c1f78b1a17 | ||
| 
						 | 
					8b70483aa0 | ||
| 
						 | 
					3ebeac2eb4 | ||
| 
						 | 
					d91a552925 | ||
| 
						 | 
					8c91145b39 | ||
| 
						 | 
					86fcf67016 | ||
| 
						 | 
					48c85ec24f | ||
| 
						 | 
					f446031069 | ||
| 
						 | 
					a9dabb0e99 | ||
| 
						 | 
					bdc95019ae | ||
| 
						 | 
					ace87c9c3b | ||
| 
						 | 
					af8b556bf8 | ||
| 
						 | 
					5990fadb3b | ||
| 
						 | 
					08b62afb10 | ||
| 
						 | 
					d4bae73b86 | 
@@ -25,10 +25,6 @@
 | 
			
		||||
                    <url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
 | 
			
		||||
                </pluginRepository>
 | 
			
		||||
            </pluginRepositories>
 | 
			
		||||
            <properties>
 | 
			
		||||
                <!-- WhiteSource token -->
 | 
			
		||||
                <org.whitesource.orgToken>${env.WHITESOURCE_API_KEY}</org.whitesource.orgToken>
 | 
			
		||||
            </properties>
 | 
			
		||||
        </profile>
 | 
			
		||||
    </profiles>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -177,6 +177,11 @@ jobs:
 | 
			
		||||
        - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
 | 
			
		||||
      script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
 | 
			
		||||
 | 
			
		||||
    - name: "Repository - Messaging tests"
 | 
			
		||||
      before_script:
 | 
			
		||||
        - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
 | 
			
		||||
      script: travis_wait 20 mvn -B test -pl repository -Dtest=CamelRoutesTest,CamelComponentsTest
 | 
			
		||||
 | 
			
		||||
    - name: "Remote-api - AppContext01TestSuite"
 | 
			
		||||
      before_script:
 | 
			
		||||
        - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.1 postgres -c 'max_connections=300'
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
      <version>8.424-SNAPSHOT</version>
 | 
			
		||||
      <version>11.5-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
@@ -167,7 +167,7 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.fasterxml.woodstox</groupId>
 | 
			
		||||
            <artifactId>woodstox-core</artifactId>
 | 
			
		||||
            <version>6.2.4</version>
 | 
			
		||||
            <version>6.2.5</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- the cxf libs were updated, see dependencyManagement section -->
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,6 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <profiles>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								pom.xml
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
    <version>8.424-SNAPSHOT</version>
 | 
			
		||||
    <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    <packaging>pom</packaging>
 | 
			
		||||
    <name>Alfresco Community Repo Parent</name>
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <acs.version.major>7</acs.version.major>
 | 
			
		||||
        <acs.version.minor>0</acs.version.minor>
 | 
			
		||||
        <acs.version.minor>1</acs.version.minor>
 | 
			
		||||
        <acs.version.revision>0</acs.version.revision>
 | 
			
		||||
        <acs.version.label />
 | 
			
		||||
 | 
			
		||||
@@ -55,14 +55,14 @@
 | 
			
		||||
 | 
			
		||||
        <dependency.spring.version>5.3.3</dependency.spring.version>
 | 
			
		||||
        <dependency.antlr.version>3.5.2</dependency.antlr.version>
 | 
			
		||||
        <dependency.jackson.version>2.12.1</dependency.jackson.version>
 | 
			
		||||
        <dependency.jackson.version>2.12.2</dependency.jackson.version>
 | 
			
		||||
        <dependency.jackson-databind.version>${dependency.jackson.version}</dependency.jackson-databind.version>
 | 
			
		||||
        <dependency.cxf.version>3.4.2</dependency.cxf.version>
 | 
			
		||||
        <dependency.cxf.version>3.4.3</dependency.cxf.version>
 | 
			
		||||
        <dependency.opencmis.version>1.0.0</dependency.opencmis.version>
 | 
			
		||||
        <dependency.webscripts.version>8.18</dependency.webscripts.version>
 | 
			
		||||
        <dependency.bouncycastle.version>1.68</dependency.bouncycastle.version>
 | 
			
		||||
        <dependency.mockito-core.version>3.8.0</dependency.mockito-core.version>
 | 
			
		||||
        <dependency.org-json.version>20201115</dependency.org-json.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.8.0</dependency.commons-io.version>
 | 
			
		||||
        <dependency.gson.version>2.8.5</dependency.gson.version>
 | 
			
		||||
@@ -73,14 +73,14 @@
 | 
			
		||||
        <dependency.slf4j.version>1.7.30</dependency.slf4j.version>
 | 
			
		||||
        <dependency.gytheio.version>0.12</dependency.gytheio.version>
 | 
			
		||||
        <dependency.groovy.version>2.5.9</dependency.groovy.version>
 | 
			
		||||
        <dependency.tika.version>1.25</dependency.tika.version>
 | 
			
		||||
        <dependency.tika.version>1.26</dependency.tika.version>
 | 
			
		||||
        <dependency.spring-security.version>5.4.1</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>11.0.0-alfresco-001</dependency.keycloak.version>
 | 
			
		||||
        <dependency.jboss.logging.version>3.4.1.Final</dependency.jboss.logging.version>
 | 
			
		||||
        <dependency.camel.version>3.7.0</dependency.camel.version>
 | 
			
		||||
        <dependency.camel.version>3.7.1</dependency.camel.version>
 | 
			
		||||
        <dependency.activemq.version>5.16.1</dependency.activemq.version>
 | 
			
		||||
        <dependency.apache.taglibs.version>1.2.5</dependency.apache.taglibs.version>
 | 
			
		||||
        <dependency.awaitility.version>4.0.3</dependency.awaitility.version>
 | 
			
		||||
@@ -102,10 +102,10 @@
 | 
			
		||||
        <dependency.postgresql.version>42.2.19</dependency.postgresql.version>
 | 
			
		||||
        <dependency.mysql.version>8.0.23</dependency.mysql.version>
 | 
			
		||||
        <dependency.mariadb.version>2.7.2</dependency.mariadb.version>
 | 
			
		||||
        <dependency.tas-utility.version>3.0.43</dependency.tas-utility.version>
 | 
			
		||||
        <dependency.tas-utility.version>3.0.44</dependency.tas-utility.version>
 | 
			
		||||
        <dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
 | 
			
		||||
        <dependency.tas-restapi.version>1.56</dependency.tas-restapi.version>
 | 
			
		||||
        <dependency.tas-cmis.version>1.27</dependency.tas-cmis.version>
 | 
			
		||||
        <dependency.tas-restapi.version>1.57</dependency.tas-restapi.version>
 | 
			
		||||
        <dependency.tas-cmis.version>1.29</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>
 | 
			
		||||
@@ -679,7 +679,7 @@
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>joda-time</groupId>
 | 
			
		||||
                <artifactId>joda-time</artifactId>
 | 
			
		||||
                <version>2.10.9</version>
 | 
			
		||||
                <version>2.10.10</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <!-- provided dependencies -->
 | 
			
		||||
@@ -694,7 +694,7 @@
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>junit</groupId>
 | 
			
		||||
                <artifactId>junit</artifactId>
 | 
			
		||||
                <version>4.13</version>
 | 
			
		||||
                <version>4.13.1</version>
 | 
			
		||||
                <scope>test</scope>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,11 +25,16 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api.model;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
import org.alfresco.rest.api.groups.GroupsEntityResource;
 | 
			
		||||
import org.alfresco.rest.api.people.PeopleEntityResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.EmbeddedEntityResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.UniqueId;
 | 
			
		||||
import org.alfresco.service.cmr.security.AccessStatus;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.service.cmr.security.AccessStatus;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of Node Permissions
 | 
			
		||||
@@ -128,6 +133,18 @@ public class NodePermissions
 | 
			
		||||
            return authorityId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @EmbeddedEntityResource(propertyName = "person", entityResource = PeopleEntityResource.class)
 | 
			
		||||
        public String getPerson()
 | 
			
		||||
        {
 | 
			
		||||
            return authorityId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @EmbeddedEntityResource(propertyName = "group", entityResource = GroupsEntityResource.class)
 | 
			
		||||
        public String getGroup()
 | 
			
		||||
        {
 | 
			
		||||
            return authorityId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getAccessStatus()
 | 
			
		||||
        {
 | 
			
		||||
            return accessStatus;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,31 +4,71 @@
 | 
			
		||||
 | 
			
		||||
<#macro dateFormat date>${date?string("dd MMM yyyy HH:mm:ss 'GMT'Z '('zzz')'")}</#macro>
 | 
			
		||||
<#macro propValue p>
 | 
			
		||||
<#if p.value??>
 | 
			
		||||
   <#if p.value?is_date>
 | 
			
		||||
      <@dateFormat p.value />
 | 
			
		||||
   <#elseif p.value?is_boolean>
 | 
			
		||||
      ${p.value?string}
 | 
			
		||||
   <#elseif p.value?is_number>
 | 
			
		||||
      ${p.value?c}
 | 
			
		||||
   <#elseif p.value?is_string>
 | 
			
		||||
      ${p.value?html}
 | 
			
		||||
   <#elseif p.value?is_hash>
 | 
			
		||||
      <#assign result = "{"/>
 | 
			
		||||
      <#assign first = true />
 | 
			
		||||
      <#list p.value?keys as key>
 | 
			
		||||
         <#if first = false>
 | 
			
		||||
            <#assign result = result + ", "/>
 | 
			
		||||
   <#attempt>
 | 
			
		||||
      <#if p.value??>
 | 
			
		||||
        <#if p.value?is_date>
 | 
			
		||||
         <@dateFormat p.value />
 | 
			
		||||
        <#elseif p.value?is_boolean>
 | 
			
		||||
         ${p.value?string}
 | 
			
		||||
        <#elseif p.value?is_number>
 | 
			
		||||
         ${p.value?c}
 | 
			
		||||
        <#elseif p.value?is_string>
 | 
			
		||||
         ${p.value?html}
 | 
			
		||||
        <#elseif p.value?is_hash || p.value?is_enumerable>
 | 
			
		||||
            <@convertToJSON p.value />
 | 
			
		||||
        </#if>
 | 
			
		||||
   	  <#else>
 | 
			
		||||
   	     ${null}
 | 
			
		||||
      </#if>
 | 
			
		||||
   <#recover>
 | 
			
		||||
      <span style="color:red">${.error}</span>
 | 
			
		||||
   </#attempt>
 | 
			
		||||
</#macro>
 | 
			
		||||
<#macro convertToJSON v>
 | 
			
		||||
   <#attempt>
 | 
			
		||||
      <#if v??>
 | 
			
		||||
         <#if v?is_date>
 | 
			
		||||
            <@dateFormat v />
 | 
			
		||||
         <#elseif v?is_boolean>
 | 
			
		||||
            ${v?string}
 | 
			
		||||
         <#elseif v?is_number>
 | 
			
		||||
            ${v?c}
 | 
			
		||||
         <#elseif v?is_string>
 | 
			
		||||
            "${v?string}"
 | 
			
		||||
         <#elseif v?is_hash>
 | 
			
		||||
            <@compress single_line=true>
 | 
			
		||||
               {
 | 
			
		||||
               <#assign first = true />
 | 
			
		||||
               <#list v?keys as key>
 | 
			
		||||
               <#if first = false>,</#if>
 | 
			
		||||
               "${key}":
 | 
			
		||||
               <#if v[key]??>
 | 
			
		||||
                  <@convertToJSON v[key] />
 | 
			
		||||
               <#else>
 | 
			
		||||
                  ${null}
 | 
			
		||||
               </#if>
 | 
			
		||||
               <#assign first = false/>
 | 
			
		||||
               </#list>
 | 
			
		||||
               }
 | 
			
		||||
            </@compress>
 | 
			
		||||
         <#elseif v?is_enumerable>
 | 
			
		||||
            <#assign first = true />
 | 
			
		||||
               <@compress single_line=true>
 | 
			
		||||
                  [
 | 
			
		||||
                  <#list v as item>
 | 
			
		||||
                     <#if first = false>,</#if>
 | 
			
		||||
                     <@convertToJSON item />
 | 
			
		||||
                     <#assign first = false/>
 | 
			
		||||
                  </#list>
 | 
			
		||||
                  ]
 | 
			
		||||
               </@compress>
 | 
			
		||||
         </#if>
 | 
			
		||||
         <#assign result = result + "${key}=${p.value[key]?html}" />
 | 
			
		||||
         <#assign first = false/>
 | 
			
		||||
      </#list>
 | 
			
		||||
      <#assign result = result + "}"/>
 | 
			
		||||
      ${result}
 | 
			
		||||
   </#if>
 | 
			
		||||
<#else>
 | 
			
		||||
   ${null}
 | 
			
		||||
</#if>
 | 
			
		||||
      <#else>
 | 
			
		||||
         ${null}
 | 
			
		||||
      </#if>
 | 
			
		||||
   <#recover>
 | 
			
		||||
      <span style="color:red">${.error}</span>
 | 
			
		||||
   </#attempt>
 | 
			
		||||
</#macro>
 | 
			
		||||
<#macro contentUrl nodeRef prop>
 | 
			
		||||
${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>8.424-SNAPSHOT</version>
 | 
			
		||||
        <version>11.5-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
@@ -82,7 +82,7 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.commons</groupId>
 | 
			
		||||
            <artifactId>commons-lang3</artifactId>
 | 
			
		||||
            <version>3.11</version>
 | 
			
		||||
            <version>3.12.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>commons-codec</groupId>
 | 
			
		||||
@@ -191,7 +191,7 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.maven</groupId>
 | 
			
		||||
            <artifactId>maven-artifact</artifactId>
 | 
			
		||||
            <version>3.6.3</version>
 | 
			
		||||
            <version>3.8.1</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>de.schlichtherle.truezip</groupId>
 | 
			
		||||
@@ -383,7 +383,7 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.fasterxml.woodstox</groupId>
 | 
			
		||||
            <artifactId>woodstox-core</artifactId>
 | 
			
		||||
            <version>6.2.4</version>
 | 
			
		||||
            <version>6.2.5</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- GData -->
 | 
			
		||||
@@ -810,7 +810,7 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>commons-net</groupId>
 | 
			
		||||
            <artifactId>commons-net</artifactId>
 | 
			
		||||
            <version>3.7.2</version>
 | 
			
		||||
            <version>3.8.0</version>
 | 
			
		||||
            <scope>test</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@ public class IdsEntity
 | 
			
		||||
    private Long idThree;
 | 
			
		||||
    private Long idFour;
 | 
			
		||||
    private List<Long> ids;
 | 
			
		||||
    private boolean ordered;
 | 
			
		||||
    public Long getIdOne()
 | 
			
		||||
    {
 | 
			
		||||
        return idOne;
 | 
			
		||||
@@ -80,4 +81,12 @@ public class IdsEntity
 | 
			
		||||
    {
 | 
			
		||||
        this.ids = ids;
 | 
			
		||||
    }
 | 
			
		||||
    public boolean isOrdered()
 | 
			
		||||
    {
 | 
			
		||||
        return ordered;
 | 
			
		||||
    }
 | 
			
		||||
    public void setOrdered(boolean ordered)
 | 
			
		||||
    {
 | 
			
		||||
        this.ordered = ordered;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1483,7 +1483,17 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
 | 
			
		||||
 | 
			
		||||
            // Update ACLs for moved tree
 | 
			
		||||
            Long newParentAclId = newParentNode.getAclId();
 | 
			
		||||
            accessControlListDAO.updateInheritance(newChildNodeId, oldParentAclId, newParentAclId);
 | 
			
		||||
 | 
			
		||||
            // Verify if parent has aspect applied and ACL's are pending
 | 
			
		||||
            if (hasNodeAspect(oldParentNodeId, ContentModel.ASPECT_PENDING_FIX_ACL))
 | 
			
		||||
            {
 | 
			
		||||
                Long oldParentSharedAclId = (Long) this.getNodeProperty(oldParentNodeId, ContentModel.PROP_SHARED_ACL_TO_REPLACE);
 | 
			
		||||
                accessControlListDAO.updateInheritance(newChildNodeId, oldParentSharedAclId, newParentAclId);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                accessControlListDAO.updateInheritance(newChildNodeId, oldParentAclId, newParentAclId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Done
 | 
			
		||||
@@ -2746,6 +2756,22 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
 | 
			
		||||
        selectNodesWithAspects(qnameIds, minNodeId, maxNodeId, resultsCallback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void getNodesWithAspects(
 | 
			
		||||
            Set<QName> aspectQNames,
 | 
			
		||||
            Long minNodeId, Long maxNodeId, boolean ordered,
 | 
			
		||||
            NodeRefQueryCallback resultsCallback)
 | 
			
		||||
    {
 | 
			
		||||
        Set<Long> qnameIdsSet = qnameDAO.convertQNamesToIds(aspectQNames, false);
 | 
			
		||||
        if (qnameIdsSet.size() == 0)
 | 
			
		||||
        {
 | 
			
		||||
            // No point running a query
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        List<Long> qnameIds = new ArrayList<Long>(qnameIdsSet);
 | 
			
		||||
        selectNodesWithAspects(qnameIds, minNodeId, maxNodeId, ordered, resultsCallback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return              Returns a writable copy of the cached aspects set
 | 
			
		||||
     */
 | 
			
		||||
@@ -4917,6 +4943,10 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
 | 
			
		||||
            List<Long> qnameIds,
 | 
			
		||||
            Long minNodeId, Long maxNodeId,
 | 
			
		||||
            NodeRefQueryCallback resultsCallback);
 | 
			
		||||
    protected abstract void selectNodesWithAspects(
 | 
			
		||||
            List<Long> qnameIds,
 | 
			
		||||
            Long minNodeId, Long maxNodeId, boolean ordered,
 | 
			
		||||
            NodeRefQueryCallback resultsCallback);
 | 
			
		||||
    protected abstract Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex);
 | 
			
		||||
    protected abstract int updateNodeAssoc(Long id, int assocIndex);
 | 
			
		||||
    protected abstract int deleteNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId);
 | 
			
		||||
 
 | 
			
		||||
@@ -405,6 +405,20 @@ public interface NodeDAO extends NodeBulkLoader
 | 
			
		||||
            Long minNodeId, Long maxNodeId,
 | 
			
		||||
            NodeRefQueryCallback resultsCallback);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get nodes with aspects between the given ranges, ordering the results optionally
 | 
			
		||||
     * 
 | 
			
		||||
     * @param aspectQNames              the aspects that must be on the nodes
 | 
			
		||||
     * @param minNodeId                 the minimum node ID (inclusive)
 | 
			
		||||
     * @param maxNodeId                 the maximum node ID (exclusive)
 | 
			
		||||
     * @param ordered                   if the results are to be ordered by nodeID
 | 
			
		||||
     * @param resultsCallback           callback to process results
 | 
			
		||||
     */
 | 
			
		||||
    public void getNodesWithAspects(
 | 
			
		||||
            Set<QName> aspectQNames,
 | 
			
		||||
            Long minNodeId, Long maxNodeId, boolean ordered,
 | 
			
		||||
            NodeRefQueryCallback resultsCallback);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Node Assocs
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -764,6 +764,31 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
 | 
			
		||||
        template.select(SELECT_NODES_WITH_ASPECT_IDS, parameters, resultHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void selectNodesWithAspects(
 | 
			
		||||
            List<Long> qnameIds,
 | 
			
		||||
            Long minNodeId, Long maxNodeId, boolean ordered,
 | 
			
		||||
            final NodeRefQueryCallback resultsCallback)
 | 
			
		||||
    {
 | 
			
		||||
        @SuppressWarnings("rawtypes")
 | 
			
		||||
        ResultHandler resultHandler = new ResultHandler()
 | 
			
		||||
        {
 | 
			
		||||
            public void handleResult(ResultContext context)
 | 
			
		||||
            {
 | 
			
		||||
                NodeEntity entity = (NodeEntity) context.getResultObject();
 | 
			
		||||
                Pair<Long, NodeRef> nodePair = new Pair<Long, NodeRef>(entity.getId(), entity.getNodeRef());
 | 
			
		||||
                resultsCallback.handle(nodePair);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        IdsEntity parameters = new IdsEntity();
 | 
			
		||||
        parameters.setIdOne(minNodeId);
 | 
			
		||||
        parameters.setIdTwo(maxNodeId);
 | 
			
		||||
        parameters.setIds(qnameIds);
 | 
			
		||||
        parameters.setOrdered(ordered);
 | 
			
		||||
        template.select(SELECT_NODES_WITH_ASPECT_IDS, parameters, resultHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Long insertNodeAssoc(Long sourceNodeId, Long targetNodeId, Long assocTypeQNameId, int assocIndex)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -337,6 +337,13 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
        setFixedAcls(getNodeIdNotNull(parent), inheritFrom, null, sharedAclToReplace, changes, false, asyncCall, true);
 | 
			
		||||
        return changes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<AclChange> setInheritanceForChildren(NodeRef parent, Long inheritFrom, Long sharedAclToReplace, boolean asyncCall, boolean forceSharedACL)
 | 
			
		||||
    {
 | 
			
		||||
        List<AclChange> changes = new ArrayList<AclChange>();
 | 
			
		||||
        setFixedAcls(getNodeIdNotNull(parent), inheritFrom, null, sharedAclToReplace, changes, false, asyncCall, true, forceSharedACL);
 | 
			
		||||
        return changes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void updateChangedAcls(NodeRef startingPoint, List<AclChange> changes)
 | 
			
		||||
    {
 | 
			
		||||
@@ -362,6 +369,29 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
        setFixedAcls(nodeId, inheritFrom, mergeFrom, sharedAclToReplace, changes, set, false, true);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Support to set a shared ACL on a node and all of its children
 | 
			
		||||
     * 
 | 
			
		||||
     * @param nodeId
 | 
			
		||||
     *            the parent node
 | 
			
		||||
     * @param inheritFrom
 | 
			
		||||
     *            the parent node's ACL
 | 
			
		||||
     * @param mergeFrom
 | 
			
		||||
     *            the shared ACL, if already known. If <code>null</code>, will be retrieved / created lazily
 | 
			
		||||
     * @param changes
 | 
			
		||||
     *            the list in which to record changes
 | 
			
		||||
     * @param set
 | 
			
		||||
     *            set the shared ACL on the parent ?
 | 
			
		||||
     * @param asyncCall
 | 
			
		||||
     *            function may require asynchronous call depending the execution time; if time exceeds configured <code>fixedAclMaxTransactionTime</code> value,
 | 
			
		||||
     *            recursion is stopped using propagateOnChildren parameter(set on false) and those nodes for which the method execution was not finished 
 | 
			
		||||
     *            in the classical way, will have ASPECT_PENDING_FIX_ACL, which will be used in {@link FixedAclUpdater} for later processing
 | 
			
		||||
     */
 | 
			
		||||
    public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List<AclChange> changes, boolean set, boolean asyncCall, boolean propagateOnChildren)
 | 
			
		||||
    {
 | 
			
		||||
        setFixedAcls(nodeId, inheritFrom, mergeFrom, sharedAclToReplace, changes, set, false, true, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Support to set a shared ACL on a node and all of its children
 | 
			
		||||
     * 
 | 
			
		||||
@@ -379,8 +409,10 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
     *            function may require asynchronous call depending the execution time; if time exceeds configured <code>fixedAclMaxTransactionTime</code> value,
 | 
			
		||||
     *            recursion is stopped using propagateOnChildren parameter(set on false) and those nodes for which the method execution was not finished 
 | 
			
		||||
     *            in the classical way, will have ASPECT_PENDING_FIX_ACL, which will be used in {@link FixedAclUpdater} for later processing
 | 
			
		||||
     * @param forceSharedACL
 | 
			
		||||
     *            When a child node has an unexpected ACL, force it to assume the new shared ACL instead of throwing a concurrency exception.
 | 
			
		||||
     */
 | 
			
		||||
    public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List<AclChange> changes, boolean set, boolean asyncCall, boolean propagateOnChildren) 
 | 
			
		||||
    public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List<AclChange> changes, boolean set, boolean asyncCall, boolean propagateOnChildren, boolean forceSharedACL)
 | 
			
		||||
    {
 | 
			
		||||
        if (log.isDebugEnabled())
 | 
			
		||||
        {
 | 
			
		||||
@@ -431,14 +463,14 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
               
 | 
			
		||||
                if (acl == null)
 | 
			
		||||
                {
 | 
			
		||||
                    propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren);
 | 
			
		||||
                    propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren, forceSharedACL);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // Still has old shared ACL or already replaced
 | 
			
		||||
                    if(acl.equals(sharedAclToReplace) || acl.equals(mergeFrom) || acl.equals(currentAcl))
 | 
			
		||||
                    {
 | 
			
		||||
                        propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren);
 | 
			
		||||
                        propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren, forceSharedACL);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
@@ -457,7 +489,20 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (dbAcl.getAclType() == ACLType.SHARED)
 | 
			
		||||
                        {
 | 
			
		||||
                            throw new ConcurrencyFailureException("setFixedAcls: unexpected shared acl: "+dbAcl);
 | 
			
		||||
                            if (forceSharedACL)
 | 
			
		||||
                            {
 | 
			
		||||
                                log.warn("Forcing shared ACL on node: " + child.getId() + " ( "
 | 
			
		||||
                                        + nodeDAO.getNodePair(child.getId()).getSecond() + ") - " + dbAcl);
 | 
			
		||||
                                sharedAclToReplace = acl;
 | 
			
		||||
                                propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace,
 | 
			
		||||
                                        changes, false, asyncCall, propagateOnChildren, forceSharedACL);
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                throw new ConcurrencyFailureException(
 | 
			
		||||
                                        "setFixedAcls: unexpected shared acl: " + dbAcl + " on node " + child.getId() + " ( "
 | 
			
		||||
                                                + nodeDAO.getNodePair(child.getId()).getSecond() + ")");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -506,7 +551,7 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
     * 
 | 
			
		||||
     */
 | 
			
		||||
    private boolean setFixAclPending(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace,
 | 
			
		||||
            List<AclChange> changes, boolean set, boolean asyncCall, boolean propagateOnChildren)
 | 
			
		||||
            List<AclChange> changes, boolean set, boolean asyncCall, boolean propagateOnChildren, boolean forceSharedACL)
 | 
			
		||||
    {
 | 
			
		||||
        // check transaction time
 | 
			
		||||
        long transactionStartTime = AlfrescoTransactionSupport.getTransactionStartTime();
 | 
			
		||||
@@ -514,7 +559,7 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
 | 
			
		||||
        if (transactionTime < fixedAclMaxTransactionTime)
 | 
			
		||||
        {
 | 
			
		||||
            // make regular method call if time is under max transaction configured time
 | 
			
		||||
            setFixedAcls(nodeId, inheritFrom, mergeFrom, sharedAclToReplace, changes, set, asyncCall, propagateOnChildren);
 | 
			
		||||
            setFixedAcls(nodeId, inheritFrom, mergeFrom, sharedAclToReplace, changes, set, asyncCall, propagateOnChildren, forceSharedACL);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,11 @@ public interface AccessControlListDAO
 | 
			
		||||
     */
 | 
			
		||||
    public List<AclChange> setInheritanceForChildren(NodeRef parent, Long inheritFrom, Long sharedAclToReplace, boolean asyncCall);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the inheritance on a given node and it's children. If an unexpected ACL occurs in a child, it can be overriden by setting forceSharedACL
 | 
			
		||||
     */
 | 
			
		||||
    public List<AclChange> setInheritanceForChildren(NodeRef parent, Long inheritFrom, Long sharedAclToReplace, boolean asyncCall, boolean forceSharedACL);
 | 
			
		||||
 | 
			
		||||
    public Long getIndirectAcl(NodeRef nodeRef);
 | 
			
		||||
 | 
			
		||||
    public Long getInheritedAcl(NodeRef nodeRef);
 | 
			
		||||
 
 | 
			
		||||
@@ -35,9 +35,12 @@ import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Sets;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.model.ContentModel;
 | 
			
		||||
import org.alfresco.repo.batch.BatchProcessWorkProvider;
 | 
			
		||||
import org.alfresco.repo.batch.BatchProcessor;
 | 
			
		||||
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
 | 
			
		||||
import org.alfresco.repo.domain.node.NodeDAO;
 | 
			
		||||
import org.alfresco.repo.domain.node.NodeDAO.NodeRefQueryCallback;
 | 
			
		||||
import org.alfresco.repo.lock.JobLockService;
 | 
			
		||||
@@ -50,6 +53,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
 | 
			
		||||
import org.alfresco.repo.security.permissions.PermissionServicePolicies;
 | 
			
		||||
import org.alfresco.repo.security.permissions.PermissionServicePolicies.OnInheritPermissionsDisabled;
 | 
			
		||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
 | 
			
		||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
 | 
			
		||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
 | 
			
		||||
import org.alfresco.repo.transaction.TransactionListenerAdapter;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
@@ -64,6 +68,8 @@ import org.apache.commons.logging.LogFactory;
 | 
			
		||||
import org.springframework.beans.BeansException;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.context.ApplicationContextAware;
 | 
			
		||||
import org.springframework.context.ApplicationEventPublisher;
 | 
			
		||||
import org.springframework.dao.ConcurrencyFailureException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds nodes with ASPECT_PENDING_FIX_ACL aspect and sets fixed ACLs for them
 | 
			
		||||
@@ -79,18 +85,22 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
 | 
			
		||||
    public static final String FIXED_ACL_ASYNC_REQUIRED_KEY = "FIXED_ACL_ASYNC_REQUIRED";
 | 
			
		||||
    public static final String FIXED_ACL_ASYNC_CALL_KEY = "FIXED_ACL_ASYNC_CALL";
 | 
			
		||||
    protected static final QName LOCK_Q_NAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "FixedAclUpdater");
 | 
			
		||||
 | 
			
		||||
    /** A set of listeners to receive callback events whenever permissions are updated by this class. */
 | 
			
		||||
    private static Set<FixedAclUpdaterListener> listeners = Sets.newConcurrentHashSet();
 | 
			
		||||
 | 
			
		||||
    private ApplicationContext applicationContext;
 | 
			
		||||
    private JobLockService jobLockService;
 | 
			
		||||
    private TransactionService transactionService;
 | 
			
		||||
    private AccessControlListDAO accessControlListDAO;
 | 
			
		||||
    private NodeDAO nodeDAO;
 | 
			
		||||
    private QName lockQName = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "FixedAclUpdater");
 | 
			
		||||
    private long lockTimeToLive = 10000;
 | 
			
		||||
    private long lockRefreshTime = lockTimeToLive / 2;
 | 
			
		||||
 | 
			
		||||
    private int maxItemBatchSize = 100;
 | 
			
		||||
    private int numThreads = 4;
 | 
			
		||||
    private boolean forceSharedACL = false;
 | 
			
		||||
 | 
			
		||||
    private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
 | 
			
		||||
    private PolicyComponent policyComponent;
 | 
			
		||||
@@ -132,6 +142,11 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
        this.maxItemBatchSize = maxItemBatchSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setForceSharedACL(boolean forceSharedACL)
 | 
			
		||||
    {
 | 
			
		||||
        this.forceSharedACL = forceSharedACL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setLockTimeToLive(long lockTimeToLive)
 | 
			
		||||
    {
 | 
			
		||||
        this.lockTimeToLive = lockTimeToLive;
 | 
			
		||||
@@ -148,6 +163,12 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
        this.policyIgnoreUtil = policyIgnoreUtil;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Register a {@link FixedAclUpdaterListener} to be notified when a node is updated by an instance of this class. */
 | 
			
		||||
    public static void registerListener(FixedAclUpdaterListener listener)
 | 
			
		||||
    {
 | 
			
		||||
        listeners.add(listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void init()
 | 
			
		||||
    {
 | 
			
		||||
        onInheritPermissionsDisabledDelegate = policyComponent
 | 
			
		||||
@@ -182,7 +203,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
                        public List<NodeRef> execute() throws Throwable
 | 
			
		||||
                        {
 | 
			
		||||
                            getNodesCallback.init();
 | 
			
		||||
                            nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, getNodesCallback);
 | 
			
		||||
                            nodeDAO.getNodesWithAspects(aspects, getNodesCallback.getMinNodeId(), null, true, getNodesCallback);
 | 
			
		||||
                            getNodesCallback.done();
 | 
			
		||||
 | 
			
		||||
                            return getNodesCallback.getNodes();
 | 
			
		||||
@@ -231,7 +252,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class AclWorker implements BatchProcessor.BatchProcessWorker<NodeRef>
 | 
			
		||||
    protected class AclWorker implements BatchProcessor.BatchProcessWorker<NodeRef>
 | 
			
		||||
    {
 | 
			
		||||
        private Set<QName> aspects = new HashSet<>(1);
 | 
			
		||||
 | 
			
		||||
@@ -253,7 +274,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void process(final NodeRef nodeRef) throws Throwable
 | 
			
		||||
        public void process(final NodeRef nodeRef) 
 | 
			
		||||
        {
 | 
			
		||||
            RunAsWork<Void> findAndUpdateAclRunAsWork = new RunAsWork<Void>()
 | 
			
		||||
            {
 | 
			
		||||
@@ -265,36 +286,48 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
                        log.debug(String.format("Processing node %s", nodeRef));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    final Long nodeId = nodeDAO.getNodePair(nodeRef).getFirst();
 | 
			
		||||
 | 
			
		||||
                    // MNT-22009 - If node was deleted and in archive store, remove the aspect and properties and do not
 | 
			
		||||
                    // process
 | 
			
		||||
                    if (nodeRef.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE))
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        final Long nodeId = nodeDAO.getNodePair(nodeRef).getFirst();
 | 
			
		||||
 | 
			
		||||
                        // MNT-22009 - If node was deleted and in archive store, remove the aspect and properties and do
 | 
			
		||||
                        // not
 | 
			
		||||
                        // process
 | 
			
		||||
                        if (nodeRef.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE))
 | 
			
		||||
                        {
 | 
			
		||||
                            accessControlListDAO.removePendingAclAspect(nodeId);
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // retrieve acl properties from node
 | 
			
		||||
                        Long inheritFrom = (Long) nodeDAO.getNodeProperty(nodeId, ContentModel.PROP_INHERIT_FROM_ACL);
 | 
			
		||||
                        Long sharedAclToReplace = (Long) nodeDAO.getNodeProperty(nodeId, ContentModel.PROP_SHARED_ACL_TO_REPLACE);
 | 
			
		||||
 | 
			
		||||
                        // set inheritance using retrieved prop
 | 
			
		||||
                        accessControlListDAO.setInheritanceForChildren(nodeRef, inheritFrom, sharedAclToReplace, true,
 | 
			
		||||
                                forceSharedACL);
 | 
			
		||||
 | 
			
		||||
                        // Remove aspect
 | 
			
		||||
                        accessControlListDAO.removePendingAclAspect(nodeId);
 | 
			
		||||
                        return null;
 | 
			
		||||
 | 
			
		||||
                        if (!policyIgnoreUtil.ignorePolicy(nodeRef))
 | 
			
		||||
                        {
 | 
			
		||||
                            boolean transformedToAsyncOperation = toBoolean((Boolean) AlfrescoTransactionSupport
 | 
			
		||||
                                    .getResource(FixedAclUpdater.FIXED_ACL_ASYNC_REQUIRED_KEY));
 | 
			
		||||
 | 
			
		||||
                            OnInheritPermissionsDisabled onInheritPermissionsDisabledPolicy = onInheritPermissionsDisabledDelegate
 | 
			
		||||
                                    .get(ContentModel.TYPE_BASE);
 | 
			
		||||
                            onInheritPermissionsDisabledPolicy.onInheritPermissionsDisabled(nodeRef, transformedToAsyncOperation);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // retrieve acl properties from node
 | 
			
		||||
                    Long inheritFrom = (Long) nodeDAO.getNodeProperty(nodeId, ContentModel.PROP_INHERIT_FROM_ACL);
 | 
			
		||||
                    Long sharedAclToReplace = (Long) nodeDAO.getNodeProperty(nodeId, ContentModel.PROP_SHARED_ACL_TO_REPLACE);
 | 
			
		||||
 | 
			
		||||
                    // set inheritance using retrieved prop
 | 
			
		||||
                    accessControlListDAO.setInheritanceForChildren(nodeRef, inheritFrom, sharedAclToReplace, true);
 | 
			
		||||
 | 
			
		||||
                    // Remove aspect
 | 
			
		||||
                    accessControlListDAO.removePendingAclAspect(nodeId);
 | 
			
		||||
 | 
			
		||||
                    if (!policyIgnoreUtil.ignorePolicy(nodeRef))
 | 
			
		||||
                    catch (Exception e)
 | 
			
		||||
                    {
 | 
			
		||||
                        boolean transformedToAsyncOperation = toBoolean(
 | 
			
		||||
                                (Boolean) AlfrescoTransactionSupport.getResource(FixedAclUpdater.FIXED_ACL_ASYNC_REQUIRED_KEY));
 | 
			
		||||
 | 
			
		||||
                        OnInheritPermissionsDisabled onInheritPermissionsDisabledPolicy = onInheritPermissionsDisabledDelegate
 | 
			
		||||
                                .get(ContentModel.TYPE_BASE);
 | 
			
		||||
                        onInheritPermissionsDisabledPolicy.onInheritPermissionsDisabled(nodeRef, transformedToAsyncOperation);
 | 
			
		||||
                        log.error("Job could not process pending ACL node " + nodeRef + ": " + e);
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    listeners.forEach(listener -> listener.permissionsUpdatedAsynchronously(nodeRef));
 | 
			
		||||
 | 
			
		||||
                    if (log.isDebugEnabled())
 | 
			
		||||
                    {
 | 
			
		||||
                        log.debug(String.format("Node processed %s", nodeRef));
 | 
			
		||||
@@ -308,8 +341,15 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
            AuthenticationUtil.runAs(findAndUpdateAclRunAsWork, AuthenticationUtil.getSystemUserName());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    private class GetNodesWithAspectCallback implements NodeRefQueryCallback
 | 
			
		||||
    /** Create a new AclWorker. */
 | 
			
		||||
    protected AclWorker createAclWorker()
 | 
			
		||||
    {
 | 
			
		||||
        return new AclWorker();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GetNodesWithAspectCallback implements NodeRefQueryCallback
 | 
			
		||||
    {
 | 
			
		||||
        private List<NodeRef> nodes = new ArrayList<>();
 | 
			
		||||
        private long minNodeId;
 | 
			
		||||
@@ -400,11 +440,11 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            lockToken = jobLockService.getLock(lockQName, lockTimeToLive, 0, 1);
 | 
			
		||||
            jobLockService.refreshLock(lockToken, lockQName, lockRefreshTime, jobLockRefreshCallback);
 | 
			
		||||
            lockToken = jobLockService.getLock(LOCK_Q_NAME, lockTimeToLive, 0, 1);
 | 
			
		||||
            jobLockService.refreshLock(lockToken, LOCK_Q_NAME, lockRefreshTime, jobLockRefreshCallback);
 | 
			
		||||
 | 
			
		||||
            AclWorkProvider provider = new AclWorkProvider();
 | 
			
		||||
            AclWorker worker = new AclWorker();
 | 
			
		||||
            AclWorker worker = createAclWorker();
 | 
			
		||||
            BatchProcessor<NodeRef> bp = new BatchProcessor<>("FixedAclUpdater",
 | 
			
		||||
                    transactionService.getRetryingTransactionHelper(), provider, numThreads, maxItemBatchSize, applicationContext,
 | 
			
		||||
                    log, 100);
 | 
			
		||||
@@ -421,7 +461,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
 | 
			
		||||
            jobLockRefreshCallback.isActive.set(false);
 | 
			
		||||
            if (lockToken != null)
 | 
			
		||||
            {
 | 
			
		||||
                jobLockService.releaseLock(lockToken, lockQName);
 | 
			
		||||
                jobLockService.releaseLock(lockToken, LOCK_Q_NAME);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.repo.domain.permissions;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
 | 
			
		||||
/** Listener to receive callback events when permissions are asynchronously updated with the {@link FixedAclUpdater}. */
 | 
			
		||||
public interface FixedAclUpdaterListener
 | 
			
		||||
{
 | 
			
		||||
    /** Callback method for when permissions have been updated by the FixedAclUpdater. */
 | 
			
		||||
    void permissionsUpdatedAsynchronously(NodeRef nodeRef);
 | 
			
		||||
}
 | 
			
		||||
@@ -779,6 +779,7 @@
 | 
			
		||||
            <if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
 | 
			
		||||
            and na.qname_id in
 | 
			
		||||
                <foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
 | 
			
		||||
        <if test="ordered == true">order by node.id ASC</if>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <!-- Common results for result_NodeAssoc -->
 | 
			
		||||
 
 | 
			
		||||
@@ -117,6 +117,7 @@
 | 
			
		||||
        <property name="nodeDAO" ref="nodeDAO"/>
 | 
			
		||||
        <property name="maxItemBatchSize" value="${system.fixedACLsUpdater.maxItemBatchSize}"/>
 | 
			
		||||
        <property name="numThreads" value="${system.fixedACLsUpdater.numThreads}"/>
 | 
			
		||||
        <property name="forceSharedACL" value="${system.fixedACLsUpdater.forceSharedACL}"/>
 | 
			
		||||
        <property name="lockTimeToLive" value="${system.fixedACLsUpdater.lockTTL}"/>
 | 
			
		||||
        <property name="policyComponent" ref="policyComponent"/>
 | 
			
		||||
        <property name="policyIgnoreUtil" ref="policyIgnoreUtil"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
repository.name=Main Repository
 | 
			
		||||
 | 
			
		||||
# Schema number
 | 
			
		||||
version.schema=14002
 | 
			
		||||
version.schema=15000
 | 
			
		||||
 | 
			
		||||
# Directory configuration
 | 
			
		||||
 | 
			
		||||
@@ -220,6 +220,8 @@ system.content.deletionFailureAction=IGNORE
 | 
			
		||||
# The CRON expression to trigger the deletion of resources associated with orphaned content.
 | 
			
		||||
system.content.orphanCleanup.cronExpression=0 0 4 * * ?
 | 
			
		||||
 | 
			
		||||
# The CRON expression to trigger the cleanup of deleted nodes and dangling transactions that are old enough
 | 
			
		||||
system.nodeServiceCleanup.cronExpression=0 0 21 * * ?
 | 
			
		||||
 | 
			
		||||
# When transforming archive files (.zip etc) into text representations (such as
 | 
			
		||||
#  for full text indexing), should the files within the archive be processed too?
 | 
			
		||||
@@ -1082,6 +1084,8 @@ system.fixedACLsUpdater.lockTTL=10000
 | 
			
		||||
system.fixedACLsUpdater.maxItemBatchSize=100
 | 
			
		||||
# fixedACLsUpdater - the number of threads to use
 | 
			
		||||
system.fixedACLsUpdater.numThreads=4
 | 
			
		||||
# fixedACLsUpdater - Force shared ACL to propagate through children even if there is an unexpected ACL
 | 
			
		||||
system.fixedACLsUpdater.forceSharedACL=false
 | 
			
		||||
# fixedACLsUpdater cron expression - fire at midnight every day
 | 
			
		||||
system.fixedACLsUpdater.cronExpression=0 0 0 * * ? 
 | 
			
		||||
 | 
			
		||||
@@ -1204,7 +1208,7 @@ repo.event2.filter.nodeAspects=sys:*
 | 
			
		||||
repo.event2.filter.childAssocTypes=rn:rendition
 | 
			
		||||
# Comma separated list of users which should be excluded
 | 
			
		||||
# Note: username's case-sensitivity depends on the {user.name.caseSensitive} setting
 | 
			
		||||
repo.event2.filter.users=System, null
 | 
			
		||||
repo.event2.filter.users=
 | 
			
		||||
# Topic name
 | 
			
		||||
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
 | 
			
		||||
 | 
			
		||||
@@ -1225,4 +1229,4 @@ system.new-node-transaction-indexes.ignored=true
 | 
			
		||||
 | 
			
		||||
# Allows the configuration of maximum limits of the temp files to be deleted or the maximum time allowed to run for the job
 | 
			
		||||
system.tempFileCleaner.maxFilesToDelete=
 | 
			
		||||
system.tempFileCleaner.maxTimeToRun=
 | 
			
		||||
system.tempFileCleaner.maxTimeToRun=
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
    <bean id="nodeServiceCleanupTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
 | 
			
		||||
        <property name="cronExpression" value="0 0 21 * * ?"/>
 | 
			
		||||
        <property name="cronExpression" value="${system.nodeServiceCleanup.cronExpression}"/>
 | 
			
		||||
        <property name="startDelay" value="${system.cronJob.startDelayMilliseconds}"/>
 | 
			
		||||
        <property name="jobDetail">
 | 
			
		||||
            <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
 | 
			
		||||
 
 | 
			
		||||
@@ -170,6 +170,7 @@ import org.junit.runners.Suite;
 | 
			
		||||
    org.alfresco.repo.content.caching.quota.UnlimitedQuotaStrategyTest.class,
 | 
			
		||||
    org.alfresco.repo.content.caching.CachingContentStoreTest.class,
 | 
			
		||||
    org.alfresco.repo.content.caching.ContentCacheImplTest.class,
 | 
			
		||||
    org.alfresco.repo.domain.permissions.FixedAclUpdaterUnitTest.class,
 | 
			
		||||
    org.alfresco.repo.domain.propval.PropertyTypeConverterTest.class,
 | 
			
		||||
    org.alfresco.repo.search.MLAnaysisModeExpansionTest.class,
 | 
			
		||||
    org.alfresco.repo.search.DocumentNavigatorTest.class,
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,99 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * 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.messaging.camel;
 | 
			
		||||
 | 
			
		||||
import org.apache.camel.CamelContext;
 | 
			
		||||
import org.apache.camel.Produce;
 | 
			
		||||
import org.apache.camel.ProducerTemplate;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.runner.RunWith;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.test.context.ContextConfiguration;
 | 
			
		||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests Camel components defined in the application's Spring context
 | 
			
		||||
 */
 | 
			
		||||
@RunWith(SpringJUnit4ClassRunner.class)
 | 
			
		||||
@ContextConfiguration(locations = "/test-messaging-context.xml")
 | 
			
		||||
public class CamelComponentsTest {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected CamelContext camelContext;
 | 
			
		||||
 | 
			
		||||
    @Produce("activemq:queue:alfresco.test")
 | 
			
		||||
    protected ProducerTemplate activemqTemplate;
 | 
			
		||||
 | 
			
		||||
    @Produce("amqp:queue:alfresco.test")
 | 
			
		||||
    protected ProducerTemplate amqpTemplate;
 | 
			
		||||
 | 
			
		||||
    @Produce("jms:queue:alfresco.test")
 | 
			
		||||
    protected ProducerTemplate jmsTemplate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testActivemqComponent()
 | 
			
		||||
    {
 | 
			
		||||
        final String msg = "ping <activemq>";
 | 
			
		||||
 | 
			
		||||
        activemqTemplate.sendBody(msg);
 | 
			
		||||
 | 
			
		||||
        final Object reply = camelContext
 | 
			
		||||
                .createConsumerTemplate()
 | 
			
		||||
                .receiveBody("activemq:queue:alfresco.test", 2000);
 | 
			
		||||
 | 
			
		||||
        assertEquals(msg, reply);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testAmqpComponent()
 | 
			
		||||
    {
 | 
			
		||||
        final String msg = "ping <amqp>";
 | 
			
		||||
 | 
			
		||||
        amqpTemplate.sendBody(msg);
 | 
			
		||||
 | 
			
		||||
        final Object reply = camelContext
 | 
			
		||||
                .createConsumerTemplate()
 | 
			
		||||
                .receiveBody("amqp:queue:alfresco.test", 2000);
 | 
			
		||||
 | 
			
		||||
        assertEquals(msg, reply);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testJmsComponent()
 | 
			
		||||
    {
 | 
			
		||||
        final String msg = "ping <jms>";
 | 
			
		||||
 | 
			
		||||
        jmsTemplate.sendBody(msg);
 | 
			
		||||
 | 
			
		||||
        final Object reply = camelContext
 | 
			
		||||
                .createConsumerTemplate()
 | 
			
		||||
                .receiveBody("jms:queue:alfresco.test", 2000);
 | 
			
		||||
 | 
			
		||||
        assertEquals(msg, reply);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -61,76 +61,76 @@ public class CamelRoutesTest
 | 
			
		||||
    
 | 
			
		||||
    @Produce("direct-vm:alfresco.test.1")
 | 
			
		||||
    protected ProducerTemplate template1;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Produce("direct-vm:alfresco.test.2")
 | 
			
		||||
    protected ProducerTemplate template2;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Produce("direct-vm:alfresco.default")
 | 
			
		||||
    protected ProducerTemplate template3;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Produce("direct-vm:alfresco.test.transacted")
 | 
			
		||||
    protected ProducerTemplate template4;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected MockExceptionProcessor messagingExceptionProcessor;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected MockConsumer mockConsumer;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected MockExceptionThrowingConsumer mockExceptionThrowingConsumer;
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testMessageRouteXmlDefined() throws Exception {
 | 
			
		||||
        String expectedBody = "<matched.>";
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        resultEndpoint1.expectedBodiesReceived(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        template1.sendBody(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        resultEndpoint1.assertIsSatisfied();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testMessageRoutePackageDefined() throws Exception {
 | 
			
		||||
        String expectedBody = "<matched.>";
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        resultEndpoint2.expectedBodiesReceived(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        template2.sendBody(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        resultEndpoint2.assertIsSatisfied();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testMessageRouteXmlOverride() throws Exception {
 | 
			
		||||
        String expectedBody = "<matched.>";
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        dlqEndpoint.expectedBodiesReceived(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        template3.sendBody(expectedBody);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
        dlqEndpoint.assertIsSatisfied();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testTransactedRoute() throws Exception {
 | 
			
		||||
        String expectedBody = "<matched.>";
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        template4.sendBody(expectedBody);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Wait for Camel and ActiveMQ to process
 | 
			
		||||
        Thread.sleep(2000);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Test that our exception processor received the error
 | 
			
		||||
        assertNotNull(messagingExceptionProcessor.getLastError());
 | 
			
		||||
        assertTrue(messagingExceptionProcessor.getLastError().getClass().equals(
 | 
			
		||||
                IllegalArgumentException.class));
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Check that an error was thrown the first time
 | 
			
		||||
        assertTrue(mockExceptionThrowingConsumer.isErrorThrown());
 | 
			
		||||
        assertNull(mockExceptionThrowingConsumer.getLastMessage());
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Check that the message was re-delivered to a second consumer
 | 
			
		||||
        assertEquals(expectedBody, mockConsumer.getLastMessage());
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -90,8 +90,8 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    private CheckOutCheckInService checkOutCheckInService;
 | 
			
		||||
    private ContentService contentService;
 | 
			
		||||
    private AuthorityService authorityService;
 | 
			
		||||
    private static final long MAX_TRANSACTION_TIME_DEFAULT = 50;
 | 
			
		||||
    private static final int[] filesPerLevelMoreFolders = { 5, 3, 1, 50 };
 | 
			
		||||
    private static final long MAX_TRANSACTION_TIME_DEFAULT = 10;
 | 
			
		||||
    private static final int[] filesPerLevelMoreFolders = { 5, 1, 1, 1, 1, 1, 1 };
 | 
			
		||||
    private static final int[] filesPerLevelMoreFiles = { 5, 100 };
 | 
			
		||||
    private long maxTransactionTime;
 | 
			
		||||
    private static HashMap<Integer, Class<?>> errors;
 | 
			
		||||
@@ -306,7 +306,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testSyncCopyNoTimeOut() throws FileExistsException, FileNotFoundException
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef originalRef = createFolderHierarchyInRootForFolderTests("originFolder");
 | 
			
		||||
        NodeRef targetRef = createFolderHierarchyInRootForFolderTests("targetFolder");
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("targetFolder");
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorOrigin = new ACLComparator(originalRef);
 | 
			
		||||
@@ -316,6 +316,19 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
            maxTransactionTime = 86400000;
 | 
			
		||||
            setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Set Shared permissions on origin
 | 
			
		||||
            permissionService.setInheritParentPermissions(originalRef, true, false);
 | 
			
		||||
            permissionService.setPermission(originalRef, TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR, true);
 | 
			
		||||
@@ -343,7 +356,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(originalRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -354,14 +367,26 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testAsyncWithNodeCopy()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
 | 
			
		||||
        NodeRef targetRef = createFile(fileFolderService, homeFolderNodeRef, "testAsyncWithNodeCopyTargetFolder",
 | 
			
		||||
                ContentModel.TYPE_FOLDER);
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyTargetFolder");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, false, false);
 | 
			
		||||
@@ -410,7 +435,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -421,13 +446,26 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testAsyncWithNodeCopyToPendingFolder()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
 | 
			
		||||
        NodeRef targetRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyTargetFolder");
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyTargetFolder");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, false, false);
 | 
			
		||||
@@ -487,7 +525,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -499,13 +537,26 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testAsyncWithNodeCopyParentToChildPendingFolder()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
 | 
			
		||||
        NodeRef targetRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyTargetFolder");
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyTargetFolder");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, false, false);
 | 
			
		||||
@@ -585,7 +636,151 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Move child of node that has the aspect to a child folder of a folder that also has the aspect applied before job
 | 
			
		||||
     * runs
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testAsyncWithNodeMoveChildToChildPendingFolder()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveChildToChildPendingFolderOrigin");
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveChildToChildPendingFolderTarget");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Set permissions on a child to get a new shared ACL with pending acl nodes
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRef, TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Get target Folder with a pending ACL
 | 
			
		||||
            NodeRef targetFolderWithPendingAcl = getFirstNodeWithAclPending(ContentModel.TYPE_FOLDER, targetRef);
 | 
			
		||||
            assertNotNull("No children folders were found with pendingFixACl aspect", targetFolderWithPendingAcl);
 | 
			
		||||
            NodeRef targetFolderWithPendingAclChild = nodeDAO
 | 
			
		||||
                    .getNodePair(getChild(nodeDAO.getNodePair(targetFolderWithPendingAcl).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetFolderWithPendingAcl);
 | 
			
		||||
            aclComparatorTarget.setOriginalPermission(TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on origin folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(folderRef, true, false);
 | 
			
		||||
                permissionService.setPermission(folderRef, TEST_GROUP_NAME_FULL, DEFAULT_PERMISSION, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Find a pending ACL folder
 | 
			
		||||
            NodeRef originFolderWithPendingAcl = getFirstNodeWithAclPending(ContentModel.TYPE_FOLDER, folderRef);
 | 
			
		||||
            assertNotNull("No children folders were found with pendingFixACl aspect", originFolderWithPendingAcl);
 | 
			
		||||
            NodeRef originFolderWithPendingAclChild = nodeDAO
 | 
			
		||||
                    .getNodePair(getChild(nodeDAO.getNodePair(originFolderWithPendingAcl).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorMovedNode = new ACLComparator(originFolderWithPendingAclChild);
 | 
			
		||||
            aclComparatorMovedNode.setOriginalPermission(TEST_GROUP_NAME_FULL, DEFAULT_PERMISSION);
 | 
			
		||||
 | 
			
		||||
            // Move one pending folder into the other
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                fileFolderService.move(originFolderWithPendingAclChild, targetFolderWithPendingAclChild, "movedFolder");
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger job
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
            assertTrue("Moved node did not inherit permissions from target",
 | 
			
		||||
                    aclComparatorMovedNode.hasPermission(TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR));
 | 
			
		||||
            assertTrue("Child of Pending Moved node did not inherit permissions from target",
 | 
			
		||||
                    aclComparatorMovedNode.firstChildHasPermission(TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR));
 | 
			
		||||
            assertFalse("Moved node kept original permissions", aclComparatorMovedNode.parentHasOriginalPermission());
 | 
			
		||||
            assertFalse("Child of Moved node kept original permissions",
 | 
			
		||||
                    aclComparatorMovedNode.firstChildHasOriginalPermission());
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Create a conflicting ACL on a node and then try to run the job normally, without forcing the ACL to get the
 | 
			
		||||
     * expected error and then run it again with the forcedShareACL property as true so it can override the problematic
 | 
			
		||||
     * ACL
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testAsyncWithErrorsForceSharedACL()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithErrorsForceSharedACL");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on origin folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(folderRef, true, false);
 | 
			
		||||
                permissionService.setPermission(folderRef, TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Find a pending ACL folder
 | 
			
		||||
            NodeRef originFolderWithPendingAcl = getFirstNodeWithAclPending(ContentModel.TYPE_FOLDER, folderRef);
 | 
			
		||||
            assertNotNull("No children folders were found with pendingFixACl aspect", originFolderWithPendingAcl);
 | 
			
		||||
            NodeRef originFolderWithPendingAclChild = nodeDAO
 | 
			
		||||
                    .getNodePair(getChild(nodeDAO.getNodePair(originFolderWithPendingAcl).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Create a new ACL elsewhere and put the shared ACL (from a child) on the pending node child to simulate
 | 
			
		||||
            // conflict
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                NodeRef tempNode = createFile(fileFolderService, folderRef, "testAsyncWithErrorsForceSharedACLTemp",
 | 
			
		||||
                        ContentModel.TYPE_FOLDER);
 | 
			
		||||
                permissionService.setInheritParentPermissions(tempNode, false, false);
 | 
			
		||||
                permissionService.setPermission(tempNode, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                NodeRef tempNodeChild = createFile(fileFolderService, tempNode, "testAsyncWithErrorsForceSharedACLTempChild",
 | 
			
		||||
                        ContentModel.TYPE_FOLDER);
 | 
			
		||||
                setACL(permissionsDaoComponent, originFolderWithPendingAclChild,
 | 
			
		||||
                        nodeDAO.getNodeAclId(nodeDAO.getNodePair(tempNodeChild).getFirst()));
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            ACLComparator aclComparator = new ACLComparator(originFolderWithPendingAclChild);
 | 
			
		||||
 | 
			
		||||
            // Trigger job without forcing the shared ACL, only 1 error is expected
 | 
			
		||||
            triggerFixedACLJob(false);
 | 
			
		||||
            assertEquals("Unexpected number of errors", 1, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            // Trigger job forcing the shared ACL
 | 
			
		||||
            triggerFixedACLJob(true);
 | 
			
		||||
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
            assertTrue("Child of node with conflict does not have correct permissions",
 | 
			
		||||
                    aclComparator.firstChildHasPermission(TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR));
 | 
			
		||||
            assertTrue("Node with conflict does not have correct permissions",
 | 
			
		||||
                    aclComparator.hasPermission(TEST_GROUP_NAME_FULL, PermissionService.COORDINATOR));
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -596,14 +791,26 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testAsyncWithNodeMove()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
 | 
			
		||||
        NodeRef targetRef = createFile(fileFolderService, homeFolderNodeRef, "testAsyncWithNodeMoveTargetFolder",
 | 
			
		||||
                ContentModel.TYPE_FOLDER);
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveTargetFolder");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, false, false);
 | 
			
		||||
@@ -649,7 +856,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -660,13 +867,27 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    public void testAsyncWithNodeMoveToPendingFolder()
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
 | 
			
		||||
        NodeRef targetRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveTargetFolder");
 | 
			
		||||
 | 
			
		||||
        // Get ACLS for later comparison
 | 
			
		||||
        ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
        NodeRef targetRefBase = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveTargetFolder");
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRefBase, true, false);
 | 
			
		||||
                permissionService.setPermission(targetRefBase, TEST_GROUP_NAME_FULL, PermissionService.CONSUMER, true);
 | 
			
		||||
                return null;
 | 
			
		||||
            }, false, true);
 | 
			
		||||
 | 
			
		||||
            // Trigger the job so the target folder structure has a different base ACL
 | 
			
		||||
            triggerFixedACLJob();
 | 
			
		||||
            assertEquals("Not all nodes were processed", 0, getNodesCountWithPendingFixedAclAspect());
 | 
			
		||||
 | 
			
		||||
            NodeRef targetRef = nodeDAO.getNodePair(getChild(nodeDAO.getNodePair(targetRefBase).getFirst())).getSecond();
 | 
			
		||||
 | 
			
		||||
            // Get ACLS for later comparison
 | 
			
		||||
            ACLComparator aclComparatorTarget = new ACLComparator(targetRef);
 | 
			
		||||
 | 
			
		||||
            // Set permissions on target folder
 | 
			
		||||
            txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
                permissionService.setInheritParentPermissions(targetRef, false, false);
 | 
			
		||||
@@ -723,7 +944,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            deleteNodes(folderRef);
 | 
			
		||||
            deleteNodes(targetRef);
 | 
			
		||||
            deleteNodes(targetRefBase);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1250,6 +1471,19 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void setACL(PermissionsDaoComponent permissionsDaoComponent, NodeRef nodeRef, long aclId)
 | 
			
		||||
    {
 | 
			
		||||
        if (permissionsDaoComponent instanceof ADMPermissionsDaoComponentImpl)
 | 
			
		||||
        {
 | 
			
		||||
            AccessControlListDAO acldao = ((ADMPermissionsDaoComponentImpl) permissionsDaoComponent).getACLDAO(nodeRef);
 | 
			
		||||
            if (acldao instanceof ADMAccessControlListDAO)
 | 
			
		||||
            {
 | 
			
		||||
                ADMAccessControlListDAO admAcLDao = (ADMAccessControlListDAO) acldao;
 | 
			
		||||
                admAcLDao.setAccessControlList(nodeRef, aclId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NodeRef createFolderHierarchyInRoot(String folderName, int[] filesPerLevel)
 | 
			
		||||
    {
 | 
			
		||||
        return txnHelper.doInTransaction((RetryingTransactionCallback<NodeRef>) () -> {
 | 
			
		||||
@@ -1318,6 +1552,11 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void triggerFixedACLJob()
 | 
			
		||||
    {
 | 
			
		||||
        triggerFixedACLJob(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void triggerFixedACLJob(boolean forceSharedACL)
 | 
			
		||||
    {
 | 
			
		||||
        // 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 for 3 cycles, meaning we have a problem.
 | 
			
		||||
@@ -1325,6 +1564,7 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
            int count = 0;
 | 
			
		||||
            int previousCount = 0;
 | 
			
		||||
            int rounds = 0;
 | 
			
		||||
            fixedAclUpdater.setForceSharedACL(forceSharedACL);
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                previousCount = count;
 | 
			
		||||
@@ -1356,8 +1596,13 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
                        isDescendent = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (isDescendent && nodeDAO.getNodeType(nodeDAO.getNodePair(nodeRef).getFirst()).equals(nodeType))
 | 
			
		||||
                {
 | 
			
		||||
                    // If folder, the tests will need a child and a grandchild to verify permissions
 | 
			
		||||
                    if (nodeType.equals(ContentModel.TYPE_FOLDER) && !hasGrandChilden(nodeRef)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    return nodeRef;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1377,6 +1622,10 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
                NodeRef nodeRef = nodesWithAclPendingAspect.get(i);
 | 
			
		||||
                if (nodeDAO.getNodeType(nodeDAO.getNodePair(nodeRef).getFirst()).equals(nodeType))
 | 
			
		||||
                {
 | 
			
		||||
                    // If folder, the tests will need a child and a grandchild to verify permissions
 | 
			
		||||
                    if (nodeType.equals(ContentModel.TYPE_FOLDER) && !hasGrandChilden(nodeRef)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    return nodeRef;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1385,6 +1634,18 @@ public class FixedAclUpdaterTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean hasGrandChilden(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        Long nodeId = nodeDAO.getNodePair(nodeRef).getFirst();
 | 
			
		||||
        Long childId = getChild(nodeId);
 | 
			
		||||
        Long grandChild = null;
 | 
			
		||||
        if (childId != null)
 | 
			
		||||
        {
 | 
			
		||||
            grandChild = getChild(childId);
 | 
			
		||||
        }
 | 
			
		||||
        return (grandChild != null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void deleteNodes(NodeRef folder)
 | 
			
		||||
    {
 | 
			
		||||
        txnHelper.doInTransaction((RetryingTransactionCallback<Void>) () -> {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,108 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.repo.domain.permissions;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.model.ContentModel.TYPE_BASE;
 | 
			
		||||
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_ARCHIVE_SPACESSTORE;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.Mockito.never;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
import static org.mockito.Mockito.when;
 | 
			
		||||
import static org.mockito.MockitoAnnotations.openMocks;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.domain.node.NodeDAO;
 | 
			
		||||
import org.alfresco.repo.domain.permissions.FixedAclUpdater.AclWorker;
 | 
			
		||||
import org.alfresco.repo.policy.ClassPolicyDelegate;
 | 
			
		||||
import org.alfresco.repo.security.permissions.PermissionServicePolicies.OnInheritPermissionsDisabled;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.util.Pair;
 | 
			
		||||
import org.alfresco.util.PolicyIgnoreUtil;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.mockito.InjectMocks;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
 | 
			
		||||
/** Mock-based unit tests for {@link FixedAclUpdater}. */
 | 
			
		||||
public class FixedAclUpdaterUnitTest
 | 
			
		||||
{
 | 
			
		||||
    private static final NodeRef NODE_REF = new NodeRef("test://node/ref");
 | 
			
		||||
    private static final long NODE_ID = 123L;
 | 
			
		||||
    private static final NodeRef ARCHIVED_NODE = new NodeRef(STORE_REF_ARCHIVE_SPACESSTORE, "archived");
 | 
			
		||||
 | 
			
		||||
    @InjectMocks
 | 
			
		||||
    private FixedAclUpdater fixedAclUpdater = new FixedAclUpdater();
 | 
			
		||||
    /** The inner class under test. */
 | 
			
		||||
    private AclWorker aclWorker = fixedAclUpdater.createAclWorker();
 | 
			
		||||
    @Mock
 | 
			
		||||
    private NodeDAO nodeDAO;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private AccessControlListDAO accessControlListDAO;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private PolicyIgnoreUtil policyIgnoreUtil;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private OnInheritPermissionsDisabled onInheritPermissionsDisabled;
 | 
			
		||||
    /** A pair of mock listeners. */
 | 
			
		||||
    @Mock
 | 
			
		||||
    private FixedAclUpdaterListener listenerA, listenerB;
 | 
			
		||||
 | 
			
		||||
    @Before
 | 
			
		||||
    public void setUp()
 | 
			
		||||
    {
 | 
			
		||||
        openMocks(this);
 | 
			
		||||
 | 
			
		||||
        fixedAclUpdater.registerListener(listenerA);
 | 
			
		||||
        fixedAclUpdater.registerListener(listenerB);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Check that when the AclWorker successfully processes a node then the listeners are notified. */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testListenersNotifiedAboutUpdate() throws Throwable
 | 
			
		||||
    {
 | 
			
		||||
        when(nodeDAO.getNodePair(NODE_REF)).thenReturn(new Pair<>(NODE_ID, NODE_REF));
 | 
			
		||||
        when(onInheritPermissionsDisabledDelegate.get(TYPE_BASE)).thenReturn(onInheritPermissionsDisabled);
 | 
			
		||||
 | 
			
		||||
        aclWorker.process(NODE_REF);
 | 
			
		||||
 | 
			
		||||
        verify(listenerA).permissionsUpdatedAsynchronously(NODE_REF);
 | 
			
		||||
        verify(listenerB).permissionsUpdatedAsynchronously(NODE_REF);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Check that archived nodes get the "Pending ACL" aspect removed without further updates, and the listeners are not notified. */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testListenersNotNotifiedAboutArchivedNode() throws Throwable
 | 
			
		||||
    {
 | 
			
		||||
        when(nodeDAO.getNodePair(ARCHIVED_NODE)).thenReturn(new Pair<>(NODE_ID, ARCHIVED_NODE));
 | 
			
		||||
        when(onInheritPermissionsDisabledDelegate.get(TYPE_BASE)).thenReturn(onInheritPermissionsDisabled);
 | 
			
		||||
 | 
			
		||||
        aclWorker.process(ARCHIVED_NODE);
 | 
			
		||||
 | 
			
		||||
        verify(accessControlListDAO).removePendingAclAspect(NODE_ID);
 | 
			
		||||
        verify(listenerA, never()).permissionsUpdatedAsynchronously(any(NodeRef.class));
 | 
			
		||||
        verify(listenerB, never()).permissionsUpdatedAsynchronously(any(NodeRef.class));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -231,7 +231,7 @@ public class ModuleVersionNumberTest extends TestCase
 | 
			
		||||
        return (ModuleVersionNumber) objectInputStream.readObject();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Tests that we can strip the suffixes such as "-M2", "-A12" or "-RC2" from versions "7.0.0-M2", "6.2.2-A12", "7.0.1-RC2"
 | 
			
		||||
    // Tests that we can strip the suffixes such as "-M2", "-A12" or "-RC2" from versions "7.0.0-M2", "6.2.2-A12", "7.1.0-RC2"
 | 
			
		||||
    // The main version may contain 3 or 4 digit parts.
 | 
			
		||||
    public void testGetVersionWithoutSuffix()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,13 @@
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <import resource="classpath:/alfresco/subsystems/Messaging/default/messaging-context.xml" />
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <bean id="messagingExceptionProcessor" 
 | 
			
		||||
        class="org.alfresco.messaging.camel.MockExceptionProcessor" />
 | 
			
		||||
        
 | 
			
		||||
    <bean id="mockConsumer" 
 | 
			
		||||
        class="org.alfresco.messaging.camel.MockConsumer" />
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <bean id="mockExceptionThrowingConsumer" 
 | 
			
		||||
        class="org.alfresco.messaging.camel.MockExceptionThrowingConsumer" />
 | 
			
		||||
    
 | 
			
		||||
@@ -25,4 +25,19 @@
 | 
			
		||||
        <property name="routeContextId" value="customRoutes" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="transactionAwareEventProducer" class="org.mockito.Mockito" factory-method="mock">
 | 
			
		||||
        <constructor-arg value="org.alfresco.repo.rawevents.TransactionAwareEventProducer" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="policyComponent" class="org.mockito.Mockito" factory-method="mock">
 | 
			
		||||
        <constructor-arg value="org.alfresco.repo.policy.PolicyComponentImpl"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="renditionEventProcessor" class="org.mockito.Mockito" factory-method="mock">
 | 
			
		||||
        <constructor-arg value="org.alfresco.repo.rendition2.RenditionEventProcessor"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="transformRequestProcessor" class="org.mockito.Mockito" factory-method="mock">
 | 
			
		||||
        <constructor-arg value="org.alfresco.repo.rendition2.TransformRequestProcessor" />
 | 
			
		||||
    </bean>
 | 
			
		||||
</beans>
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
messaging.broker.url=vm://localhost?broker.persistent=false
 | 
			
		||||
messaging.broker.url=nio://localhost:61616
 | 
			
		||||
messaging.broker.ssl=false
 | 
			
		||||
messaging.broker.connections.max=8
 | 
			
		||||
messaging.transacted=true
 | 
			
		||||
messaging.broker.username=
 | 
			
		||||
messaging.broker.password=
 | 
			
		||||
messaging.broker.password=
 | 
			
		||||
 | 
			
		||||
acs.repo.rendition.events.endpoint=jms:acs-repo-rendition-events-test?jmsMessageType=Text
 | 
			
		||||
acs.repo.transform.request.endpoint=jms:acs-repo-transform-request-test?jmsMessageType=Text
 | 
			
		||||
		Reference in New Issue
	
	Block a user