diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index 58e7d593bf..ec093897e2 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -1848,6 +1848,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 @@ -2914,6 +2927,7 @@ public class NodesImpl implements Nodes String versionComment = null; String relativePath = null; String renditionNames = null; + boolean versioningEnabled = true; Map qnameStrProps = new HashMap<>(); Map properties = null; @@ -2970,6 +2984,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: { @@ -3042,12 +3069,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); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java index a6c34a1a96..73fa568c32 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -5612,6 +5612,283 @@ 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 documentProperties = documentResponse.getProperties(); + assertEquals(2, documentProperties.size()); + 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(2, documentProperties.size()); + 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(2, documentProperties.size()); + 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(2, documentProperties.size()); + 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 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 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); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/util/MultiPartBuilder.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/util/MultiPartBuilder.java index 527d5fa3d9..433caeff30 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/tests/util/MultiPartBuilder.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/util/MultiPartBuilder.java @@ -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; /** * multipart/form-data builder. @@ -57,6 +56,7 @@ public class MultiPartBuilder private String updateNodeRef; private String description; private String contentTypeQNameStr; + private String versioningEnabled; private List 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 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);