mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-17 14:21:39 +00:00
Merge remote-tracking branch 'origin/release/6.2.N' into release/6.2.N
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<profiles>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
2
pom.xml
2
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>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -1831,6 +1831,19 @@ public class NodesImpl implements Nodes
|
||||
{
|
||||
versionMajor = Boolean.valueOf(str);
|
||||
}
|
||||
String versioningEnabledStringValue = parameters.getParameter("versioningEnabled");
|
||||
if (null != versioningEnabledStringValue)
|
||||
{
|
||||
boolean versioningEnabled = Boolean.parseBoolean(versioningEnabledStringValue);
|
||||
if (versioningEnabled)
|
||||
{
|
||||
versionMajor = (null != versionMajor) ? versionMajor : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
versionMajor = null;
|
||||
}
|
||||
}
|
||||
String versionComment = parameters.getParameter(PARAM_VERSION_COMMENT);
|
||||
|
||||
// Create the node
|
||||
@@ -2331,6 +2344,11 @@ public class NodesImpl implements Nodes
|
||||
private void handleNodeRename(Map<QName, Serializable> props, NodeRef nodeRef)
|
||||
{
|
||||
Serializable nameProp = props.get(ContentModel.PROP_NAME);
|
||||
handleNodeRename(nameProp, nodeRef);
|
||||
}
|
||||
|
||||
private void handleNodeRename(Serializable nameProp, NodeRef nodeRef)
|
||||
{
|
||||
if ((nameProp != null))
|
||||
{
|
||||
String currentName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
@@ -2705,6 +2723,7 @@ public class NodesImpl implements Nodes
|
||||
String fileName = parameters.getParameter(PARAM_NAME);
|
||||
if (fileName != null)
|
||||
{
|
||||
handleNodeRename(fileName, nodeRef);
|
||||
// optionally rename, before updating the content
|
||||
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, fileName);
|
||||
}
|
||||
@@ -2891,6 +2910,7 @@ public class NodesImpl implements Nodes
|
||||
String versionComment = null;
|
||||
String relativePath = null;
|
||||
String renditionNames = null;
|
||||
boolean versioningEnabled = true;
|
||||
|
||||
Map<String, Object> qnameStrProps = new HashMap<>();
|
||||
Map<QName, Serializable> properties = null;
|
||||
@@ -2947,6 +2967,19 @@ public class NodesImpl implements Nodes
|
||||
case "renditions":
|
||||
renditionNames = getStringOrNull(field.getValue());
|
||||
break;
|
||||
case "versioningenabled":
|
||||
String versioningEnabledStringValue = getStringOrNull(field.getValue());
|
||||
if (null != versioningEnabledStringValue)
|
||||
{
|
||||
// MNT-22036 versioningenabled parameter was added to disable versioning of newly created nodes.
|
||||
// The default API mechanism should not be changed/affected.
|
||||
// Versioning is enabled by default when creating a node using form-data.
|
||||
// To preserve this, versioningEnabled value must be 'true' for any given value typo/valuesNotSupported (except case-insensitive 'false')
|
||||
// .equalsIgnoreCase("false") will return true only when the input value is 'false'
|
||||
// !.equalsIgnoreCase("false") will return false only when the input value is 'false'
|
||||
versioningEnabled = !versioningEnabledStringValue.equalsIgnoreCase("false");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
@@ -3019,12 +3052,14 @@ public class NodesImpl implements Nodes
|
||||
throw new ConstraintViolatedException(fileName + " already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Note: pending REPO-159, we currently auto-enable versioning on new upload (but not when creating empty file)
|
||||
if (versionMajor == null)
|
||||
{
|
||||
versionMajor = true;
|
||||
}
|
||||
// MNT-22036 add versioningEnabled property for newly created nodes.
|
||||
versionMajor = versioningEnabled ? versionMajor : null;
|
||||
|
||||
// Create a new file.
|
||||
NodeRef nodeRef = createNewFile(parentNodeRef, fileName, nodeTypeQName, content, properties, assocTypeQName, parameters, versionMajor, versionComment);
|
||||
|
@@ -5605,6 +5605,279 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
|
||||
assertTrue(((ArrayList) (propUpdateResponse.get("custom:locations"))).size() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void versioningEnabledMultipartNodeCreationTest() throws Exception
|
||||
{
|
||||
setRequestContext(user1);
|
||||
String myNodeId = getMyNodeId();
|
||||
// Test Scenarios:
|
||||
// 1: majorVersion not set - versioningEnabled not set Expect: MAJOR version
|
||||
// 2: majorVersion not set - versioningEnabled false Expect: versioning disabled
|
||||
// 3: majorVersion true - versioningEnabled false Expect: versioning disabled
|
||||
// 4: majorVersion false - versioningEnabled false Expect: versioning disabled
|
||||
// 5: majorVersion not set - versioningEnabled true Expect: MAJOR version
|
||||
// 6: majorVersion true - versioningEnabled true Expect: MAJOR version
|
||||
// 7: majorVersion false - versioningEnabled true Expect: Minor version
|
||||
// 8: majorVersion not set - versioningEnabled False Expect: versioning disabled
|
||||
// 9: majorVersion not set - versioningEnabled invalid Expect: MAJOR version
|
||||
|
||||
// Scenario 1:
|
||||
String fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
File file = getResourceFile("quick-2.pdf");
|
||||
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
|
||||
MultiPartRequest reqBody = multiPartBuilder.build();
|
||||
HttpResponse response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
Document documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
// Default behaviour, expect to be MAJOR Version 1.0
|
||||
Map<String, Object> documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
// Scenario 2:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setVersioningEnabled("false");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
// Scenario 3:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setMajorVersion(true);
|
||||
multiPartBuilder.setVersioningEnabled("false");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
// Scenario 4:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setMajorVersion(false);
|
||||
multiPartBuilder.setVersioningEnabled("false");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
// Scenario 5:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setVersioningEnabled("true");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
// Scenario 6:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setMajorVersion(true);
|
||||
multiPartBuilder.setVersioningEnabled("true");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
// Scenario 7:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setMajorVersion(false);
|
||||
multiPartBuilder.setVersioningEnabled("true");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MINOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("0.1", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
// Scenario 8:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setVersioningEnabled("False");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
// Scenario 9:
|
||||
fileName = "myfile" + UUID.randomUUID() + ".txt";
|
||||
multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
|
||||
multiPartBuilder.setVersioningEnabled("invalid");
|
||||
|
||||
reqBody = multiPartBuilder.build();
|
||||
response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void versioningEnabledJSONNodeCreationTest() throws Exception
|
||||
{
|
||||
setRequestContext(user1);
|
||||
String myNodeId = getMyNodeId();
|
||||
|
||||
// Test Scenarios:
|
||||
// 1: majorVersion not set - versioningEnabled not set Expect: versioning disabled
|
||||
// 2: majorVersion not set - versioningEnabled false Expect: versioning disabled
|
||||
// 3: majorVersion true - versioningEnabled false Expect: versioning disabled
|
||||
// 4: majorVersion false - versioningEnabled false Expect: versioning disabled
|
||||
// 5: majorVersion not set - versioningEnabled true Expect: MAJOR version
|
||||
// 6: majorVersion true - versioningEnabled true Expect: MAJOR version
|
||||
// 7: majorVersion false - versioningEnabled true Expect: Minor version
|
||||
// 8: majorVersion not set - versioningEnabled False Expect: versioning disabled
|
||||
// 9: majorVersion not set - versioningEnabled invalid Expect: versioning disabled
|
||||
// 10 majorVersion not set - versioningenabled true Expect: versioning disabled
|
||||
|
||||
Document d1 = new Document();
|
||||
Map<String, String> requestHeaders = new HashMap<>();
|
||||
|
||||
//Scenario 1:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
d1.setNodeType(TYPE_CM_CONTENT);
|
||||
|
||||
HttpResponse response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
Document documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
Map<String, Object> documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 2:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","false");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 3:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","false");
|
||||
requestHeaders.put("majorVersion","true");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 4:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","false");
|
||||
requestHeaders.put("majorVersion","false");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 5:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","true");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
//Scenario 6:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","true");
|
||||
requestHeaders.put("majorVersion","true");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MAJOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("1.0", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
//Scenario 7:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","true");
|
||||
requestHeaders.put("majorVersion","false");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertEquals("MINOR", documentProperties.get("cm:versionType"));
|
||||
assertEquals("0.1", documentProperties.get("cm:versionLabel"));
|
||||
|
||||
//Scenario 8:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","False");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 9:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningEnabled","invalid");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
|
||||
//Scenario 10:
|
||||
d1.setName("testDoc" + UUID.randomUUID());
|
||||
requestHeaders = new HashMap<>();
|
||||
requestHeaders.put("versioningenabled","true");
|
||||
|
||||
response = post(getNodeChildrenUrl(myNodeId), toJsonAsStringNonNull(d1),requestHeaders, null, null, 201);
|
||||
documentResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
|
||||
documentProperties = documentResponse.getProperties();
|
||||
assertNull(documentProperties);
|
||||
}
|
||||
|
||||
@Test public void testAuditableProperties() throws Exception
|
||||
{
|
||||
setRequestContext(user1);
|
||||
@@ -5708,6 +5981,55 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
|
||||
assertTrue(currentPath.equals(expectedPath));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimaryPathVersion() throws Exception
|
||||
{
|
||||
setRequestContext(user1);
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(user1);
|
||||
String myNodeId = getMyNodeId();
|
||||
|
||||
// /Company Home/User Homes/user<timestamp>/folder_A
|
||||
String folderName = "folder_A";
|
||||
Folder folder = createFolder(myNodeId, folderName);
|
||||
NodeRef folderNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, folder.getId());
|
||||
|
||||
// /Company Home/User Homes/user<timestamp>/folder_A/testDoc<GUID>
|
||||
String docName = "testDoc" + GUID.generate();
|
||||
Document doc = new Document();
|
||||
doc.setName(docName);
|
||||
doc.setNodeType(TYPE_CM_CONTENT);
|
||||
HttpResponse response = post(getNodeChildrenUrl(folderNodeRef.getId()), toJsonAsStringNonNull(doc), 201);
|
||||
Document docResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
NodeRef docNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, docResp.getId());
|
||||
|
||||
// Checks that current path and name match
|
||||
String expectedPath1 = "/Company Home/User Homes/" + user1 + "/" + folderName + "/" + docName;
|
||||
Path docPath1 = nodeService.getPath(docNodeRef);
|
||||
Path.ChildAssocElement docPathLast1 = (Path.ChildAssocElement) docPath1.last();
|
||||
String docLocalName1 = docPathLast1.getRef().getQName().getLocalName();
|
||||
String currentPath1 = docPath1.toDisplayPath(nodeService, permissionService) + "/" + docLocalName1;
|
||||
assertTrue(docName.equals(docLocalName1));
|
||||
assertTrue(expectedPath1.equals(currentPath1));
|
||||
|
||||
// Upload document new content supplying a different name
|
||||
String docName2 = "testDoc2" + GUID.generate();
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("name", docName2);
|
||||
Document docResp2 = updateTextFileWithRandomContent(docNodeRef.getId(), 1024L, params);
|
||||
NodeRef docNodeRef2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, docResp2.getId());
|
||||
|
||||
// Checks new path and name after new version upload
|
||||
String expectedPath2 = "/Company Home/User Homes/" + user1 + "/" + folderName + "/" + docName2;
|
||||
Path docPath2 = nodeService.getPath(docNodeRef2);
|
||||
Path.ChildAssocElement docPathLast2 = (Path.ChildAssocElement) docPath2.last();
|
||||
String docLocalName2 = docPathLast2.getRef().getQName().getLocalName();
|
||||
String currentPath2 = docPath2.toDisplayPath(nodeService, permissionService) + "/" + docLocalName2;
|
||||
assertFalse(docLocalName1.equals(docLocalName2));
|
||||
assertTrue(docName2.equals(docLocalName2));
|
||||
assertFalse(expectedPath1.equals(currentPath2));
|
||||
assertTrue(expectedPath2.equals(currentPath2));
|
||||
}
|
||||
|
||||
private String getDataDictionaryNodeId() throws Exception
|
||||
{
|
||||
Map params = new HashMap<>();
|
||||
|
@@ -43,7 +43,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* <i><b>multipart/form-data</b></i> builder.
|
||||
@@ -57,6 +56,7 @@ public class MultiPartBuilder
|
||||
private String updateNodeRef;
|
||||
private String description;
|
||||
private String contentTypeQNameStr;
|
||||
private String versioningEnabled;
|
||||
private List<String> aspects = Collections.emptyList();
|
||||
private Boolean majorVersion;
|
||||
private Boolean overwrite;
|
||||
@@ -76,6 +76,7 @@ public class MultiPartBuilder
|
||||
this.updateNodeRef = that.updateNodeRef;
|
||||
this.description = that.description;
|
||||
this.contentTypeQNameStr = that.contentTypeQNameStr;
|
||||
this.versioningEnabled = that.versioningEnabled;
|
||||
this.aspects = new ArrayList<>(that.aspects);
|
||||
this.majorVersion = that.majorVersion;
|
||||
this.overwrite = that.overwrite;
|
||||
@@ -125,6 +126,12 @@ public class MultiPartBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiPartBuilder setVersioningEnabled(String versioningEnabled)
|
||||
{
|
||||
this.versioningEnabled = versioningEnabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiPartBuilder setAspects(List<String> aspects)
|
||||
{
|
||||
this.aspects = aspects;
|
||||
@@ -278,6 +285,7 @@ public class MultiPartBuilder
|
||||
addPartIfNotNull(parts, "updatenoderef", updateNodeRef);
|
||||
addPartIfNotNull(parts, "description", description);
|
||||
addPartIfNotNull(parts, "contenttype", contentTypeQNameStr);
|
||||
addPartIfNotNull(parts, "versioningenabled", versioningEnabled);
|
||||
addPartIfNotNull(parts, "aspects", getCommaSeparated(aspects));
|
||||
addPartIfNotNull(parts, "majorversion", majorVersion);
|
||||
addPartIfNotNull(parts, "overwrite", overwrite);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>7.301-SNAPSHOT</version>
|
||||
<version>7.308-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -177,13 +177,13 @@ public class CMISResultSetRow implements ResultSetRow
|
||||
context.setScore(getScore());
|
||||
for (Column column : query.getColumns())
|
||||
{
|
||||
// When an SCORE selector is included, score must be adapted to range 0..1 due to CMIS specification
|
||||
if (column.getFunction()!= null && column.getFunction().getName().equals(Score.NAME))
|
||||
{
|
||||
return getNormalisedScore();
|
||||
}
|
||||
else if (column.getAlias().equals(columnName))
|
||||
if (column.getAlias().equals(columnName))
|
||||
{
|
||||
//When an SCORE selector is included, score must be adapted to range 0..1 due to CMIS specification
|
||||
if (column.getFunction()!= null && column.getFunction().getName().equals(Score.NAME))
|
||||
{
|
||||
return getNormalisedScore();
|
||||
}
|
||||
return column.getFunction().getValue(column.getFunctionArguments(), context);
|
||||
}
|
||||
// Special case for one selector - ignore any table aliases
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.cache;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -150,10 +150,24 @@ public final class DefaultSimpleCache<K extends Serializable, V extends Object>
|
||||
* @return <code>true</code> if the put resulted in a change in value, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean putAndCheckUpdate(K key, V value)
|
||||
{
|
||||
return putAndCheckUpdate(key, value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>put</code> method that may be used to check for updates in a thread-safe manner.
|
||||
*
|
||||
* @param includeNewCheck if true then we include the new value in the check
|
||||
* @return <code>true</code> if the put resulted in a change in value,
|
||||
* or if includeNewCheck is true and the put resulted in a new value,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean putAndCheckUpdate(K key, V value, boolean includeNewCheck)
|
||||
{
|
||||
AbstractMap.SimpleImmutableEntry<K, V> kvp = new AbstractMap.SimpleImmutableEntry<K, V>(key, value);
|
||||
AbstractMap.SimpleImmutableEntry<K, V> priorKVP = cache.asMap().put(key, kvp);
|
||||
return priorKVP != null && (! priorKVP.equals(kvp));
|
||||
|
||||
return (includeNewCheck && priorKVP == null) || (priorKVP != null && (!priorKVP.equals(kvp)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -35,6 +35,7 @@ public enum DeploymentMethod
|
||||
INSTALLER,
|
||||
DOCKER_COMPOSE,
|
||||
HELM_CHART,
|
||||
ANSIBLE,
|
||||
/**
|
||||
* The distribution zip was used to lay down the ACS artifacts
|
||||
*/
|
||||
|
@@ -23,7 +23,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.domain.permissions;
|
||||
package org.alfresco.repo.domain.permissions;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
@@ -392,8 +392,20 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
else
|
||||
{
|
||||
// When node is copied when the aspect is applied, the sharedACLtoReplace will not match the children's ACLS
|
||||
// to replace, we need to use the current one.
|
||||
Long currentAcl = nodeDAO.getNodeAclId(nodeId);
|
||||
|
||||
if (nodeDAO.hasNodeAspect(nodeId, ContentModel.ASPECT_PENDING_FIX_ACL))
|
||||
{
|
||||
// If node has a pending acl, retrieve the sharedAclToReplace from node property. When the job calls
|
||||
// this, it already does it but on move and copy operations, it uses the new parents old ACL.
|
||||
sharedAclToReplace = (Long) nodeDAO.getNodeProperty(nodeId, ContentModel.PROP_SHARED_ACL_TO_REPLACE);
|
||||
|
||||
}
|
||||
|
||||
// Lazily retrieve/create the shared ACL
|
||||
if (mergeFrom == null)
|
||||
{
|
||||
@@ -405,33 +417,26 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
|
||||
nodeDAO.setNodeAclId(nodeId, mergeFrom);
|
||||
}
|
||||
|
||||
List<NodeIdAndAclId> children = nodeDAO.getPrimaryChildrenAcls(nodeId);
|
||||
|
||||
if(children.size() > 0)
|
||||
{
|
||||
nodeDAO.setPrimaryChildrenSharedAclId(nodeId, sharedAclToReplace, mergeFrom);
|
||||
}
|
||||
List<NodeIdAndAclId> children = nodeDAO.getPrimaryChildrenAcls(nodeId);
|
||||
|
||||
if (!propagateOnChildren)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (NodeIdAndAclId child : children)
|
||||
{
|
||||
Long acl = child.getAclId();
|
||||
|
||||
{
|
||||
//Use the current ACL instead of the stored value, it could've been changed meanwhile
|
||||
Long acl = nodeDAO.getNodeAclId(child.getId());
|
||||
|
||||
if (acl == null)
|
||||
{
|
||||
propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if(acl.equals(mergeFrom))
|
||||
// {
|
||||
// setFixedAcls(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false);
|
||||
// }
|
||||
// Still has old shared ACL or already replaced
|
||||
if(acl.equals(sharedAclToReplace) || acl.equals(mergeFrom))
|
||||
if(acl.equals(sharedAclToReplace) || acl.equals(mergeFrom) || acl.equals(currentAcl))
|
||||
{
|
||||
propagateOnChildren = setFixAclPending(child.getId(), inheritFrom, mergeFrom, sharedAclToReplace, changes, false, asyncCall, propagateOnChildren);
|
||||
}
|
||||
@@ -456,7 +461,22 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// By doing an eager update of the direct children we canot see if another thread has changed the ACL
|
||||
// between the time we get the child nodes and we update them. By updating the direct children last it is
|
||||
// possible to verify if any child has changed meanwhile.
|
||||
if(children.size() > 0)
|
||||
{
|
||||
nodeDAO.setPrimaryChildrenSharedAclId(nodeId, sharedAclToReplace, mergeFrom);
|
||||
}
|
||||
|
||||
// When this is not executed triggered by the job, but a move or copy operation occures on a pending
|
||||
// node, we don't want to apply the OLD ACL that was pending
|
||||
if(nodeDAO.hasNodeAspect(nodeId, ContentModel.ASPECT_PENDING_FIX_ACL))
|
||||
{
|
||||
removePendingAclAspect(nodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,25 +529,45 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
// set ASPECT_PENDING_FIX_ACL aspect on node to be later on processed with FixedAclUpdater amd switch flag
|
||||
// FIXED_ACL_ASYNC_REQUIRED_KEY
|
||||
addFixedAclPendingAspect(nodeId, sharedAclToReplace, inheritFrom);
|
||||
addFixedAclPendingAspect(nodeId, sharedAclToReplace, inheritFrom, mergeFrom);
|
||||
AlfrescoTransactionSupport.bindResource(FixedAclUpdater.FIXED_ACL_ASYNC_REQUIRED_KEY, true);
|
||||
// stop propagating on children nodes
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addFixedAclPendingAspect(Long nodeId, Long sharedAclToReplace, Long inheritFrom)
|
||||
{
|
||||
Set<QName> aspect = new HashSet<>();
|
||||
aspect.add(ContentModel.ASPECT_PENDING_FIX_ACL);
|
||||
nodeDAO.addNodeAspects(nodeId, aspect);
|
||||
Map<QName, Serializable> pendingAclProperties = new HashMap<>();
|
||||
pendingAclProperties.put(ContentModel.PROP_SHARED_ACL_TO_REPLACE, sharedAclToReplace);
|
||||
pendingAclProperties.put(ContentModel.PROP_INHERIT_FROM_ACL, inheritFrom);
|
||||
nodeDAO.addNodeProperties(nodeId, pendingAclProperties);
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Set Fixed Acl Pending : " + nodeId + " " + nodeDAO.getNodePair(nodeId).getSecond());
|
||||
private void addFixedAclPendingAspect(Long nodeId, Long sharedAclToReplace, Long inheritFrom, Long mergeFrom)
|
||||
{
|
||||
//If the node already has the pending ACL aspect, just update the new inheritFrom value
|
||||
if (nodeDAO.hasNodeAspect(nodeId, ContentModel.ASPECT_PENDING_FIX_ACL))
|
||||
{
|
||||
Map<QName, Serializable> pendingAclProperties = new HashMap<>();
|
||||
pendingAclProperties.put(ContentModel.PROP_INHERIT_FROM_ACL, inheritFrom);
|
||||
nodeDAO.addNodeProperties(nodeId, pendingAclProperties);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<QName> aspect = new HashSet<>();
|
||||
aspect.add(ContentModel.ASPECT_PENDING_FIX_ACL);
|
||||
nodeDAO.addNodeAspects(nodeId, aspect);
|
||||
Map<QName, Serializable> pendingAclProperties = new HashMap<>();
|
||||
pendingAclProperties.put(ContentModel.PROP_SHARED_ACL_TO_REPLACE, sharedAclToReplace);
|
||||
pendingAclProperties.put(ContentModel.PROP_INHERIT_FROM_ACL, inheritFrom);
|
||||
nodeDAO.addNodeProperties(nodeId, pendingAclProperties);
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Set Fixed Acl Pending : " + nodeId + " " + nodeDAO.getNodePair(nodeId).getSecond());
|
||||
}
|
||||
}
|
||||
|
||||
public void removePendingAclAspect(Long nodeId)
|
||||
{
|
||||
Set<QName> aspects = new HashSet<>(1);
|
||||
aspects.add(ContentModel.ASPECT_PENDING_FIX_ACL);
|
||||
Set<QName> pendingFixAclProperties = new HashSet<>();
|
||||
pendingFixAclProperties.add(ContentModel.PROP_SHARED_ACL_TO_REPLACE);
|
||||
pendingFixAclProperties.add(ContentModel.PROP_INHERIT_FROM_ACL);
|
||||
nodeDAO.removeNodeAspects(nodeId, aspects);
|
||||
nodeDAO.removeNodeProperties(nodeId, pendingFixAclProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -105,5 +105,7 @@ public interface AccessControlListDAO
|
||||
|
||||
public void updateInheritance(Long childNodeId, Long oldParentAclId, Long newParentAclId);
|
||||
|
||||
public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List<AclChange> changes, boolean set);
|
||||
public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List<AclChange> changes, boolean set);
|
||||
|
||||
public void removePendingAclAspect(Long nodeId);
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
@@ -91,8 +92,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
|
||||
private int maxItemBatchSize = 100;
|
||||
private int numThreads = 4;
|
||||
|
||||
private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
|
||||
private PolicyComponent policyComponent;
|
||||
private ClassPolicyDelegate<OnInheritPermissionsDisabled> onInheritPermissionsDisabledDelegate;
|
||||
private PolicyComponent policyComponent;
|
||||
private PolicyIgnoreUtil policyIgnoreUtil;
|
||||
|
||||
public void setNumThreads(int numThreads)
|
||||
@@ -135,8 +136,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
|
||||
{
|
||||
this.lockTimeToLive = lockTimeToLive;
|
||||
this.lockRefreshTime = lockTimeToLive / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
@@ -149,7 +150,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
|
||||
|
||||
public void init()
|
||||
{
|
||||
onInheritPermissionsDisabledDelegate = policyComponent.registerClassPolicy(PermissionServicePolicies.OnInheritPermissionsDisabled.class);
|
||||
onInheritPermissionsDisabledDelegate = policyComponent
|
||||
.registerClassPolicy(PermissionServicePolicies.OnInheritPermissionsDisabled.class);
|
||||
}
|
||||
|
||||
private class GetNodesWithAspects
|
||||
@@ -262,26 +264,34 @@ 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))
|
||||
{
|
||||
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);
|
||||
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);
|
||||
accessControlListDAO.setInheritanceForChildren(nodeRef, inheritFrom, sharedAclToReplace, true);
|
||||
|
||||
// Remove aspect
|
||||
accessControlListDAO.removePendingAclAspect(nodeId);
|
||||
|
||||
nodeDAO.removeNodeAspects(nodeId, aspects);
|
||||
nodeDAO.removeNodeProperties(nodeId, PENDING_FIX_ACL_ASPECT_PROPS);
|
||||
|
||||
if (!policyIgnoreUtil.ignorePolicy(nodeRef))
|
||||
{
|
||||
boolean transformedToAsyncOperation = toBoolean((Boolean) AlfrescoTransactionSupport.getResource(FixedAclUpdater.FIXED_ACL_ASYNC_REQUIRED_KEY));
|
||||
boolean transformedToAsyncOperation = toBoolean(
|
||||
(Boolean) AlfrescoTransactionSupport.getResource(FixedAclUpdater.FIXED_ACL_ASYNC_REQUIRED_KEY));
|
||||
|
||||
OnInheritPermissionsDisabled onInheritPermissionsDisabledPolicy = onInheritPermissionsDisabledDelegate.get(ContentModel.TYPE_BASE);
|
||||
OnInheritPermissionsDisabled onInheritPermissionsDisabledPolicy = onInheritPermissionsDisabledDelegate
|
||||
.get(ContentModel.TYPE_BASE);
|
||||
onInheritPermissionsDisabledPolicy.onInheritPermissionsDisabled(nodeRef, transformedToAsyncOperation);
|
||||
}
|
||||
|
||||
@@ -395,12 +405,8 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
|
||||
|
||||
AclWorkProvider provider = new AclWorkProvider();
|
||||
AclWorker worker = new AclWorker();
|
||||
BatchProcessor<NodeRef> bp = new BatchProcessor<>(
|
||||
"FixedAclUpdater",
|
||||
transactionService.getRetryingTransactionHelper(),
|
||||
provider,
|
||||
numThreads, maxItemBatchSize,
|
||||
applicationContext,
|
||||
BatchProcessor<NodeRef> bp = new BatchProcessor<>("FixedAclUpdater",
|
||||
transactionService.getRetryingTransactionHelper(), provider, numThreads, maxItemBatchSize, applicationContext,
|
||||
log, 100);
|
||||
int count = bp.process(worker, true);
|
||||
return count;
|
||||
@@ -413,7 +419,7 @@ public class FixedAclUpdater extends TransactionListenerAdapter implements Appli
|
||||
finally
|
||||
{
|
||||
jobLockRefreshCallback.isActive.set(false);
|
||||
if(lockToken != null)
|
||||
if (lockToken != null)
|
||||
{
|
||||
jobLockService.releaseLock(lockToken, lockQName);
|
||||
}
|
||||
|
@@ -764,7 +764,7 @@ deployment.service.targetLockRefreshTime=60000
|
||||
# How long to wait in mS from the last communication before deciding that deployment has failed, possibly
|
||||
# the destination is no longer available?
|
||||
deployment.service.targetLockTimeout=3600000
|
||||
# Deployment method used to deploy this Alfresco instance (DEFAULT, INSTALLER, DOCKER_COMPOSE, HELM_CHART, ZIP, QUICK_START)
|
||||
# Deployment method used to deploy this Alfresco instance (DEFAULT, INSTALLER, DOCKER_COMPOSE, HELM_CHART, ANSIBLE, ZIP, QUICK_START)
|
||||
deployment.method=DEFAULT
|
||||
|
||||
#Invitation Service
|
||||
|
@@ -136,6 +136,7 @@
|
||||
<property name="tenantAware" value="false" />
|
||||
<property name="cacheStats" ref="cacheStatistics"/>
|
||||
<property name="cacheStatsEnabled" value="${cache.immutableEntitySharedCache.tx.statsEnabled}"/>
|
||||
<property name="allowEqualsChecks" value="true" />
|
||||
</bean>
|
||||
|
||||
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.cache;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -131,6 +131,45 @@ public class DefaultSimpleCacheTest extends SimpleCacheTestBase<DefaultSimpleCac
|
||||
assertEquals(false, cache.putAndCheckUpdate(104, "104"));
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putAndCheckUpdateIncludeNewCheck()
|
||||
{
|
||||
// Put an initial value
|
||||
cache.put(101, "101");
|
||||
// Update it
|
||||
assertEquals(true, cache.putAndCheckUpdate(101, "99101", true));
|
||||
// Check the value really was updated
|
||||
assertEquals("99101", cache.get(101));
|
||||
|
||||
// Precondition: no value for key 102
|
||||
assertFalse(cache.contains(102));
|
||||
// Put a value - and test the return
|
||||
assertEquals(true, cache.putAndCheckUpdate(102, "102", true));
|
||||
assertEquals("102", cache.get(102));
|
||||
|
||||
cache.put(103, null);
|
||||
assertEquals(true, cache.putAndCheckUpdate(103, "103", true));
|
||||
// Repeat the put, this should not be an update
|
||||
assertEquals(false, cache.putAndCheckUpdate(103, "103", true));
|
||||
|
||||
assertFalse(cache.contains(104));
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, null, true));
|
||||
// Repeat putting null - still not an update, as we had that value a moment ago.
|
||||
assertEquals(false, cache.putAndCheckUpdate(104, null, true));
|
||||
// Now an update
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, "104", true));
|
||||
// Another update
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, "99104", true));
|
||||
// Another update, back to null
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, null, true));
|
||||
// Not an update - still null
|
||||
assertEquals(false, cache.putAndCheckUpdate(104, null, true));
|
||||
|
||||
cache.remove(104);
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, "104", true));
|
||||
assertEquals(true, cache.putAndCheckUpdate(104, null, true));
|
||||
}
|
||||
|
||||
// TODO: Timer-based tests are not ideal. An alternative approach is to factor out the CacheBuilder.newBuilder()
|
||||
// call to a protected method, override that in this test class to return a mock and use the mock to check
|
||||
@@ -198,6 +237,6 @@ public class DefaultSimpleCacheTest extends SimpleCacheTestBase<DefaultSimpleCac
|
||||
{
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user