diff --git a/pom.xml b/pom.xml index c0df8bad0e..4eff6fbd7f 100644 --- a/pom.xml +++ b/pom.xml @@ -97,6 +97,7 @@ rm-enterprise rm-automation + rm-benchmark @@ -296,6 +297,11 @@ maven-failsafe-plugin 2.19 + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + org.codehaus.mojo build-helper-maven-plugin diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 78c62c3a3b..1e6d3439db 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -24,7 +24,6 @@ - releases 1.8 1.8 testng.xml @@ -109,22 +108,18 @@ Recreating database... drop database if exists alfresco; create database alfresco Downloading Alfresco installer... - + Installing Alfresco... + - - org.apache.ant - ant-jsch - 1.8.2 - postgresql postgresql diff --git a/rm-automation/rm-automation-community-rest-api/.gitignore b/rm-automation/rm-automation-community-rest-api/.gitignore index d1a4acb433..bb654bad1e 100644 --- a/rm-automation/rm-automation-community-rest-api/.gitignore +++ b/rm-automation/rm-automation-community-rest-api/.gitignore @@ -6,3 +6,4 @@ /.idea/ *.iml /test-output/ +.factorypath \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/pom.xml b/rm-automation/rm-automation-community-rest-api/pom.xml index 81a3e2c542..0579d444e2 100644 --- a/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/rm-automation/rm-automation-community-rest-api/pom.xml @@ -54,5 +54,11 @@ fluent-json ${fluent.json.version} + + org.projectlombok + lombok + 1.16.10 + provided + diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java index c74034ed5a..b9edeb4002 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java @@ -28,12 +28,19 @@ package org.alfresco.rest.rm.community.model.fileplancomponents; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.ALLOWABLE_OPERATIONS; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.IS_CLOSED; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.RELATIVE_PATH; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for file plan component * @@ -41,6 +48,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @author Rodica Sutu * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class FilePlanComponent { @JsonProperty (required = true) @@ -84,10 +95,11 @@ public class FilePlanComponent @JsonProperty (value = ALLOWABLE_OPERATIONS) private List allowableOperations; - + @JsonProperty (required = false) private FilePlanComponentContent content; - + + @JsonProperty (value = PATH) private FilePlanComponentPath path; @JsonProperty (required = true) @@ -99,324 +111,7 @@ public class FilePlanComponent @JsonProperty (required = true) private FilePlanComponentUserInfo modifiedByUser; + @JsonProperty (value = RELATIVE_PATH) + private String relativePath; - /**Helper constructor for creating the file plan component using - * - * @param name File Plan Component name - * @param nodeType File Plan Component node type - * @param properties File Plan Component properties - */ - public FilePlanComponent(String name, String nodeType, FilePlanComponentProperties properties) - { - this.name = name; - this.nodeType = nodeType; - this.properties = properties; - } - - /** - * Helper constructor to create empty file plan component - */ - public FilePlanComponent() { } - - /** - * Helper constructor for creating the file plan component using - * - * @param name File Plan Component name - */ - public FilePlanComponent(String name) - { - this.name = name; - } - - /** - * Helper constructor for creating the file plan component using - * - * @param name File Plan Component name - * @param properties File Plan Component properties - */ - public FilePlanComponent(String name, FilePlanComponentProperties properties) - { - this.name = name; - this.properties = properties; - } - - /** - * @return the id - */ - public String getId() - { - return this.id; - } - - /** - * @param id the id to set - */ - public void setId(String id) - { - this.id = id; - } - - /** - * @return the parentId - */ - public String getParentId() - { - return this.parentId; - } - - /** - * @param parentId the parentId to set - */ - public void setParentId(String parentId) - { - this.parentId = parentId; - } - - /** - * @return the name - */ - public String getName() - { - return this.name; - } - - /** - * @param name the name to set - */ - public void setName(String name) - { - this.name = name; - } - - /** - * @return the nodeType - */ - public String getNodeType() - { - return this.nodeType; - } - - /** - * @param nodeType the nodeType to set - */ - public void setNodeType(String nodeType) - { - this.nodeType = nodeType; - } - - /** - * @return the isCategory - */ - public Boolean isCategory() - { - return this.isCategory; - } - - /** - * @param isCategory the isCategory to set - */ - public void setCategory(Boolean isCategory) - { - this.isCategory = isCategory; - } - - /** - * @return the isRecordFolder - */ - public Boolean isRecordFolder() - { - return this.isRecordFolder; - } - - /** - * @param isRecordFolder the isRecordFolder to set - */ - public void setRecordFolder(Boolean isRecordFolder) - { - this.isRecordFolder = isRecordFolder; - } - - /** - * @return the isFile - */ - public Boolean isFile() - { - return this.isFile; - } - - /** - * @param isFile the isFile to set - */ - public void setFile(Boolean isFile) - { - this.isFile = isFile; - } - - /** - * @return the hasRetentionSchedule - */ - public Boolean hasRetentionSchedule() - { - return this.hasRetentionSchedule; - } - - /** - * @param hasRetentionSchedule the hasRetentionSchedule to set - */ - public void setHasRetentionSchedule(Boolean hasRetentionSchedule) - { - this.hasRetentionSchedule = hasRetentionSchedule; - } - - /** - * @return the properties - */ - public FilePlanComponentProperties getProperties() - { - return properties; - } - - /** - * @param properties the properties to set - */ - public void setProperties(FilePlanComponentProperties properties) - { - this.properties = properties; - } - - /** - * @return the aspectNames - */ - public List getAspectNames() - { - return this.aspectNames; - } - - /** - * @param aspectNames the aspectNames to set - */ - public void setAspectNames(List aspectNames) - { - this.aspectNames = aspectNames; - } - - /** - * @return the createdByUser - */ - public FilePlanComponentUserInfo getCreatedByUser() - { - return this.createdByUser; - } - - /** - * @param createdByUser the createdByUser to set - */ - public void setCreatedByUser(FilePlanComponentUserInfo createdByUser) - { - this.createdByUser = createdByUser; - } - - /** - * @return the allowableOperations - */ - public List getAllowableOperations() - { - return this.allowableOperations; - } - - /** - * @return the path - */ - public FilePlanComponentPath getPath() - { - return this.path; - } - - /** - * @param path the path to set - */ - public void setPath(FilePlanComponentPath path) - { - this.path = path; - } - - /** - * @param modifiedAt the modifiedAt to set - */ - public void setModifiedAt(String modifiedAt) - { - this.modifiedAt = modifiedAt; - } - - /** - * @param createdAt the createdAt to set - */ - public void setCreatedAt(String createdAt) - { - this.createdAt = createdAt; - } - - /** - * @param modifiedByUser the modifiedByUser to set - */ - public void setModifiedByUser(FilePlanComponentUserInfo modifiedByUser) - { - this.modifiedByUser = modifiedByUser; - } - - /** - * @return the modifiedAt - */ - public String getModifiedAt() - { - return this.modifiedAt; - } - - /** - * @return the createdAt - */ - public String getCreatedAt() - { - return this.createdAt; - } - - /** - * @return the modifiedByUser - */ - public FilePlanComponentUserInfo getModifiedByUser() - { - return this.modifiedByUser; - } - - /** - * @return the isClosed - */ - public Boolean isClosed() - { - return this.isClosed; - } - - /** - * @param closed the isClosed to set - */ - public void setClosed(Boolean closed) - { - this.isClosed = closed; - } - - /** - * @return the isCompleted - */ - public Boolean isCompleted() - { - return this.isCompleted; - } - - /** - * @param completed the isCompleted to set - */ - public void setCompleted(Boolean completed) - { - this.isCompleted = completed; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java index eb2f102266..5a22064c4a 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java @@ -37,77 +37,14 @@ public class FilePlanComponentContent { @JsonProperty (required = true) private String encoding; - + @JsonProperty (required = true) private String mimeType; - + @JsonProperty (required = true) private String mimeTypeName; - + @JsonProperty (required = true) private Integer sizeInBytes; - /** - * @return the encoding - */ - public String getEncoding() - { - return this.encoding; - } - - /** - * @param encoding the encoding to set - */ - public void setEncoding(String encoding) - { - this.encoding = encoding; - } - - /** - * @return the mimeType - */ - public String getMimeType() - { - return this.mimeType; - } - - /** - * @param mimeType the mimeType to set - */ - public void setMimeType(String mimeType) - { - this.mimeType = mimeType; - } - - /** - * @return the mimeTypeName - */ - public String getMimeTypeName() - { - return this.mimeTypeName; - } - - /** - * @param mimeTypeName the mimeTypeName to set - */ - public void setMimeTypeName(String mimeTypeName) - { - this.mimeTypeName = mimeTypeName; - } - - /** - * @return the sizeInBytes - */ - public Integer getSizeInBytes() - { - return this.sizeInBytes; - } - - /** - * @param sizeInBytes the sizeInBytes to set - */ - public void setSizeInBytes(Integer sizeInBytes) - { - this.sizeInBytes = sizeInBytes; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentEntry.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentEntry.java index 7d88b233c8..6aa037599b 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentEntry.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentEntry.java @@ -30,6 +30,10 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import org.alfresco.rest.core.RestModels; /** @@ -38,13 +42,13 @@ import org.alfresco.rest.core.RestModels; * @author Tuna Aksoy * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class FilePlanComponentEntry extends RestModels { @JsonProperty(ENTRY) FilePlanComponent filePlanComponent; - public FilePlanComponent getFilePlanComponent() - { - return filePlanComponent; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java index 11b14c1906..130cb388f5 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java @@ -49,7 +49,7 @@ public class FilePlanComponentFields public static final String PROPERTIES_REVIEW_PERIOD = "rma:reviewPeriod"; public static final String PROPERTIES_LOCATION = "rma:location"; public static final String PROPERTIES_IS_CLOSED = "rma:isClosed"; // not to be confused with IS_CLOSED! - + // for non-electronic records public static final String PROPERTIES_BOX = "rma:box"; public static final String PROPERTIES_FILE = "rma:file"; @@ -57,5 +57,8 @@ public class FilePlanComponentFields public static final String PROPERTIES_PHYSICAL_SIZE = "rma:physicalSize"; public static final String PROPERTIES_SHELF = "rma:shelf"; public static final String PROPERTIES_STORAGE_LOCATION = "rma:storageLocation"; - + + //RelativePath specifies the container structure to create relative to the node nodeId. + public static final String RELATIVE_PATH = "relativePath"; + public static final String PATH = "path"; } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentIdNamePair.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentIdNamePair.java index c6c0e55dc7..25b9f3eadb 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentIdNamePair.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentIdNamePair.java @@ -26,46 +26,24 @@ */ package org.alfresco.rest.rm.community.model.fileplancomponents; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for id/name pair * * @author Kristijan Conkas * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class FilePlanComponentIdNamePair { public String id; public String name; - /** - * @return the id - */ - public String getId() - { - return this.id; - } - - /** - * @param id the id to set - */ - public void setId(String id) - { - this.id = id; - } - - /** - * @return the name - */ - public String getName() - { - return this.name; - } - - /** - * @param name the name to set - */ - public void setName(String name) - { - this.name = name; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentPath.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentPath.java index ca612a556d..5660d0e895 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentPath.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentPath.java @@ -30,12 +30,21 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for FilePlanComponent path parameter *
* @author Kristijan Conkas * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class FilePlanComponentPath { @@ -43,51 +52,4 @@ public class FilePlanComponentPath private Boolean isComplete; private List elements; - /** - * @return the name - */ - public String getName() - { - return this.name; - } - - /** - * @param name the name to set - */ - public void setName(String name) - { - this.name = name; - } - - /** - * @return the isComplete - */ - public Boolean isComplete() - { - return this.isComplete; - } - - /** - * @param isComplete the isComplete to set - */ - public void setComplete(Boolean isComplete) - { - this.isComplete = isComplete; - } - - /** - * @return the elements - */ - public List getElements() - { - return this.elements; - } - - /** - * @param elements the elements to set - */ - public void setElements(List elements) - { - this.elements = elements; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java index 9c17419680..b95bf61720 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java @@ -48,6 +48,11 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for file plan component properties * @@ -56,6 +61,10 @@ import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer; */ //FIXME: Once the fields have been added the JsonIgnoreProperties annotation should be removed @JsonIgnoreProperties (ignoreUnknown = true) +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class FilePlanComponentProperties { @@ -80,7 +89,7 @@ public class FilePlanComponentProperties @JsonProperty(PROPERTIES_LOCATION) private String location; - + @JsonProperty(value = PROPERTIES_IS_CLOSED, required = false) private Boolean isClosed; @@ -100,227 +109,4 @@ public class FilePlanComponentProperties private Integer physicalSize; - public FilePlanComponentProperties(String title, String description) - { - this.title = title; - this.description = description; - } - - public FilePlanComponentProperties(String title) - { - this.title = title; - } - - public FilePlanComponentProperties() - { - } - - - /** - * @return the vitalRecord - */ - public Boolean isVitalRecord() - { - return this.vitalRecord; - } - - /** - * @param vitalRecord the vitalRecord to set - */ - public void setVitalRecord(Boolean vitalRecord) - { - this.vitalRecord = vitalRecord; - } - - /** - * @return the title - */ - public String getTitle() - { - return this.title; - } - - /** - * @param title the title to set - */ - public void setTitle(String title) - { - this.title = title; - } - - /** - * @return the holdReason - */ - public String getHoldReason() - { - return this.holdReason; - } - - /** - * @param holdReason the holdReason to set - */ - public void setHoldReason(String holdReason) - { - this.holdReason = holdReason; - } - - /** - * @param description the description to set - */ - public void setDescription(String description) - { - this.description = description; - } - - /** - * @return the description - */ - public String getDescription() - { - return this.description; - } - - /** - * @return the supplementalMarkingList - */ - public List getSupplementalMarkingList() - { - return this.supplementalMarkingList; - } - - /** - * @param supplementalMarkingList the supplementalMarkingList to set - */ - public void setSupplementalMarkingList(List supplementalMarkingList) - { - this.supplementalMarkingList = supplementalMarkingList; - } - - /** - * @return the reviewPeriod - */ - public ReviewPeriod getReviewPeriod() - { - return reviewPeriod; - } - - /** - * @param reviewPeriod the reviewPeriod to set - */ - public void setReviewPeriod(ReviewPeriod reviewPeriod) - { - this.reviewPeriod = reviewPeriod; - } - - /** - * @return the location - */ - public String getLocation() - { - return location; - } - - /** - * @param location the location to set - */ - public void setLocation(String location) - { - this.location = location; - } - - /** - * @return the box - */ - public String getBox() - { - return this.box; - } - - /** - * @param box the box to set - */ - public void setBox(String box) - { - this.box = box; - } - - /** - * @return the file - */ - public String getFile() - { - return this.file; - } - - /** - * @param file the file to set - */ - public void setFile(String file) - { - this.file = file; - } - - /** - * @return the shelf - */ - public String getShelf() - { - return this.shelf; - } - - /** - * @param shelf the shelf to set - */ - public void setShelf(String shelf) - { - this.shelf = shelf; - } - - /** - * @return the numberOfCopies - */ - public Integer getNumberOfCopies() - { - return this.numberOfCopies; - } - - /** - * @param numberOfCopies the numberOfCopies to set - */ - public void setNumberOfCopies(Integer numberOfCopies) - { - this.numberOfCopies = numberOfCopies; - } - - /** - * @return the physicalSize - */ - public Integer getPhysicalSize() - { - return this.physicalSize; - } - - /** - * @param physicalSize the physicalSize to set - */ - public void setPhysicalSize(Integer physicalSize) - { - this.physicalSize = physicalSize; - } - - /** - * @return the isClosed - */ - public Boolean getIsClosed() - { - return this.isClosed; - } - - /** - * @param isClosed the isClosed to set - */ - public void setIsClosed(Boolean isClosed) - { - this.isClosed = isClosed; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentUserInfo.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentUserInfo.java index 58773d1fd7..f2c7cf4a1b 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentUserInfo.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentUserInfo.java @@ -26,46 +26,24 @@ */ package org.alfresco.rest.rm.community.model.fileplancomponents; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for file plan component created by object * * @author Kristijan Conkas * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class FilePlanComponentUserInfo { private String id; private String displayName; - /** - * @return the id - */ - public String getId() - { - return this.id; - } - - /** - * @param id the id to set - */ - public void setId(String id) - { - this.id = id; - } - - /** - * @return the displayName - */ - public String getDisplayName() - { - return this.displayName; - } - - /** - * @param displayName the displayName to set - */ - public void setDisplayName(String displayName) - { - this.displayName = displayName; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/ReviewPeriod.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/ReviewPeriod.java index 30c2c63938..c8891acb65 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/ReviewPeriod.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/ReviewPeriod.java @@ -26,66 +26,23 @@ */ package org.alfresco.rest.rm.community.model.fileplancomponents; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * POJO for the review period * * @author Rodica Sutu * @since 2.6 */ - +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class ReviewPeriod { private String periodType; private String expression; - - /** - * Helper constructor with - * - * @param periodType - * @param expression - */ - public ReviewPeriod(String periodType, String expression) - { - this.periodType = periodType; - this.expression = expression; - } - - /** - * Helper constructor - */ - public ReviewPeriod() - { - } - - /** - * @return the periodType - */ - public String getPeriodType() - { - return this.periodType; - } - - /** - * @param periodType the periodType to set - */ - public void setPeriodType(String periodType) - { - this.periodType = periodType; - } - - /** - * @return the expression - */ - public String getExpression() - { - return this.expression; - } - - /** - * @param expression the expression to set - */ - public void setExpression(String expression) - { - this.expression = expression; - } } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/site/RMSite.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/site/RMSite.java index e9f80ede48..8added36da 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/site/RMSite.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/site/RMSite.java @@ -30,6 +30,10 @@ import static org.alfresco.rest.rm.community.model.site.RMSiteFields.COMPLIANCE; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import org.alfresco.rest.model.RestSiteModel; /** @@ -38,59 +42,13 @@ import org.alfresco.rest.model.RestSiteModel; * @author Rodica Sutu * @since 2.6 */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class RMSite extends RestSiteModel { @JsonProperty (value = COMPLIANCE,required = true) private RMSiteCompliance compliance; - /** - * Helper constructor to create RM Site object using - * - * @param title - * @param description - * @param compliance - */ - public RMSite(String title, String description, RMSiteCompliance compliance) - { - this.title=title; - this.description=description; - this.compliance=compliance; - } - - /** - * Helper constructor for creating the RM Site - */ - public RMSite() { } - - /** - * Helper constructor to create RM Site object using - * - * @param compliance RM Site Compliance - */ - public RMSite(RMSiteCompliance compliance) - { - super(); - this.compliance = compliance; - } - - /** - * Helper method to set RM site compliance - * - * @param compliance {@link RMSiteCompliance} the compliance to set - */ - public void setCompliance(RMSiteCompliance compliance) - { - this.compliance = compliance; - } - - /** - * Helper method to get RM site compliance - * - * @return compliance the RM Site compliance to get - */ - public RMSiteCompliance getCompliance() - { - return compliance; - } - } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserPermissions.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserPermissions.java new file mode 100644 index 0000000000..14f2ff2be6 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserPermissions.java @@ -0,0 +1,40 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.rm.community.model.user; + +/** + * Constants for RM user capabilities + * + * @author Kristijan Conkas + * @since 2.6 + */ +public class UserPermissions +{ + public static final String PERMISSION_FILING = "Filing"; + public static final String PERMISSION_READ_RECORDS = "ReadRecords"; + public static final String PERMISSION_FILE_RECORDS = "FileRecords"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserRoles.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserRoles.java new file mode 100644 index 0000000000..ae8a6ccb5f --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserRoles.java @@ -0,0 +1,42 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.rm.community.model.user; + +/** + * Constants for RM user roles + * + * @author Kristijan Conkas + * @since 2.6 + */ +public class UserRoles +{ + public static final String ROLE_RM_ADMIN = "Administrator"; + public static final String ROLE_RM_MANAGER = "RecordsManager"; + public static final String ROLE_RM_POWER_USER = "PowerUser"; + public static final String ROLE_RM_SECURITY_OFFICER = "SecurityOfficer"; + public static final String ROLE_RM_USER = "User"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java index 9d8c385a91..39431a9cef 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java @@ -26,6 +26,7 @@ */ package org.alfresco.rest.rm.community.requests; +import static com.jayway.restassured.RestAssured.basic; import static com.jayway.restassured.RestAssured.given; import static org.alfresco.rest.core.RestRequest.requestWithBody; @@ -40,8 +41,12 @@ import static org.springframework.http.HttpMethod.PUT; import static org.testng.Assert.fail; import java.io.File; +import java.util.Iterator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.io.Resources; +import com.jayway.restassured.builder.RequestSpecBuilder; import com.jayway.restassured.http.ContentType; import com.jayway.restassured.response.Response; @@ -168,16 +173,41 @@ public class FilePlanComponentAPI extends RestAPI { fail("Only electronic records are supported"); } + + UserModel currentUser = usingRestWrapper().getTestUser(); + + /* + * For file uploads nodeBodyCreate is ignored hence can't be used. Append all FilePlanComponent fields + * to the request. + */ + RequestSpecBuilder builder = new RequestSpecBuilder(); + builder.setAuth(basic(currentUser.getUsername(), currentUser.getPassword())); + + ObjectMapper mapper = new ObjectMapper(); + JsonNode root = mapper.readTree(toJson(electronicRecordModel)); + + Iterator fieldNames = root.fieldNames(); + while (fieldNames.hasNext()) + { + String f = fieldNames.next(); + try + { + builder.addMultiPart(f, root.get(f).asText(), ContentType.JSON.name()); + } + catch (Exception error) + { + LOG.error("Failed to set " + f + " error: " + error); + } + } + + builder.addMultiPart("filedata", recordContent, ContentType.BINARY.name()); /* * RestWrapper adds some headers which break multipart/form-data uploads and also assumes json POST requests. * Upload the file using RestAssured library. */ - UserModel currentUser = usingRestWrapper().getTestUser(); Response response = given() - .auth().basic(currentUser.getUsername(), currentUser.getPassword()) - .multiPart("nodeBodyCreate", toJson(electronicRecordModel), ContentType.JSON.name()) - .multiPart("filedata", recordContent, ContentType.BINARY.name()) + .spec(builder.build()) .when() .post("fileplan-components/{fileplanComponentId}/children?{parameters}", parentId, getParameters()) .andReturn(); diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java new file mode 100644 index 0000000000..ec5e0e6d9a --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java @@ -0,0 +1,86 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.rm.community.requests; + +import static com.jayway.restassured.RestAssured.given; + +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.response.Response; +import com.jayway.restassured.specification.RequestSpecification; + +import org.alfresco.dataprep.AlfrescoHttpClient; +import org.alfresco.dataprep.AlfrescoHttpClientFactory; +import org.alfresco.rest.core.RestAPI; +import org.alfresco.utility.data.DataUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * RM user management API + * + * @author Kristijan Conkas + * @since 2.6 + */ +// FIXME: As of December 2016 there is no v1-style API for managing RM users and users' +// roles. Until such APIs have become available, methods in this class are just proxies to +// "old-style" API calls. +@Component +@Scope (value = "prototype") +public class RMUserAPI extends RestAPI +{ + @Autowired + private DataUser dataUser; + + @Autowired + private AlfrescoHttpClientFactory alfrescoHttpClientFactory; + + public void assignRoleToUser(String userName, String userRole) throws Exception + { + // get an "old-style" REST API client + AlfrescoHttpClient client = alfrescoHttpClientFactory.getObject(); + + // override v1 baseURI and basePath + RequestSpecification spec = new RequestSpecBuilder() + .setBaseUri(client.getApiUrl()) + .setBasePath("/") + .build(); + + Response response = given() + .spec(spec) + .log().all() + .pathParam("role", userRole) + .pathParam("authority", userName) + .param("alf_ticket", client.getAlfTicket( + dataUser.getAdminUser().getUsername(), dataUser.getAdminUser().getPassword())) + .when() + .post("/rm/roles/{role}/authorities/{authority}") + .prettyPeek() + .andReturn(); + usingRestWrapper().setStatusCode(Integer.toString(response.getStatusCode())); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java index fc32735837..cb478cf65f 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java @@ -28,6 +28,8 @@ package org.alfresco.rest.rm.community.base; import static java.lang.Integer.parseInt; +import static com.jayway.restassured.RestAssured.given; + import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_TITLE; import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; @@ -37,11 +39,19 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE; import static org.alfresco.rest.rm.community.model.site.RMSiteCompliance.STANDARD; import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.jglue.fluentjson.JsonBuilderFactory.buildObject; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; +import com.google.gson.JsonObject; import com.jayway.restassured.RestAssured; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.response.Response; +import com.jayway.restassured.specification.RequestSpecification; +import org.alfresco.dataprep.AlfrescoHttpClient; +import org.alfresco.dataprep.AlfrescoHttpClientFactory; import org.alfresco.rest.RestTest; import org.alfresco.rest.core.RestWrapper; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; @@ -96,6 +106,9 @@ public class BaseRestTest extends RestTest @Autowired public FilePlanComponentAPI filePlanComponentAPI; + @Autowired + private AlfrescoHttpClientFactory alfrescoHttpClientFactory; + // Constants public static final String RM_ID = "rm"; public static final String RM_TITLE = "Records Management"; @@ -113,7 +126,7 @@ public class BaseRestTest extends RestTest { createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS.toString(), "Unfiled Folder " + getRandomAlphanumeric()) } }; } - + /** * @see org.alfresco.rest.RestTest#checkServerHealth() */ @@ -141,7 +154,9 @@ public class BaseRestTest extends RestTest rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); // Create the RM site - RMSite rmSite = new RMSite(RM_TITLE, RM_DESCRIPTION, STANDARD); + RMSite rmSite = RMSite.builder().compliance(STANDARD).build(); + rmSite.setTitle(RM_TITLE); + rmSite.setDescription(RM_DESCRIPTION); rmSiteAPI.createRMSite(rmSite); // Verify the status code @@ -202,7 +217,13 @@ public class BaseRestTest extends RestTest { RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); - FilePlanComponent filePlanComponent = new FilePlanComponent(componentName, componentType.toString(),new FilePlanComponentProperties(componentTitle)); + FilePlanComponent filePlanComponent = FilePlanComponent.builder() + .name(componentName) + .nodeType(componentType.toString()) + .properties(FilePlanComponentProperties.builder() + .title(componentTitle) + .build()) + .build(); FilePlanComponent fpc = filePlanComponentAPI.createFilePlanComponent(filePlanComponent, parentComponentId); restWrapper.assertStatusCodeIs(CREATED); @@ -211,7 +232,7 @@ public class BaseRestTest extends RestTest /** * Helper method to close folder - * @param folderToClose + * @param folderId * @return * @throws Exception */ @@ -260,4 +281,47 @@ public class BaseRestTest extends RestTest filePlanComponentAPI.usingRestWrapper().authenticateUser(user); return filePlanComponentAPI.getFilePlanComponent(componentId); } + + /** + * Helper method to add permission on a component to user + * @param component {@link FilePlanComponent} on which permission should be given + * @param user {@link UserModel} for a user to be granted permission + * @param permission {@link UserPermissions} to be granted + */ + // FIXME: As of December 2016 there is no v1-style API for managing RM permissions. + // Until such APIs have become available, this method is just a proxy to an "old-style" + // API call. + public void addUserPermission(FilePlanComponent component, UserModel user, String permission) + { + // get an "old-style" REST API client + AlfrescoHttpClient client = alfrescoHttpClientFactory.getObject(); + + JsonObject bodyJson = buildObject() + .addArray("permissions") + .addObject() + .add("authority", user.getUsername()) + .add("role", permission) + .end() + .getJson(); + + // override v1 baseURI and basePath + RequestSpecification spec = new RequestSpecBuilder() + .setBaseUri(client.getApiUrl()) + .setBasePath("/") + .build(); + + // execute an "old-style" API call + Response response = given() + .spec(spec) + .auth().basic(dataUser.getAdminUser().getUsername(), dataUser.getAdminUser().getPassword()) + .contentType(ContentType.JSON) + .body(bodyJson.toString()) + .pathParam("nodeId", component.getId()) + .log().all() + .when() + .post("/node/workspace/SpacesStore/{nodeId}/rmpermissions") + .prettyPeek() + .andReturn(); + filePlanComponentAPI.usingRestWrapper().setStatusCode(Integer.toString(response.getStatusCode())); + } } \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java new file mode 100644 index 0000000000..056a465611 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java @@ -0,0 +1,280 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.rm.community.fileplancomponents; + +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE; +import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.NO_CONTENT; +import static org.springframework.http.HttpStatus.OK; + +import org.alfresco.rest.rm.community.base.BaseRestTest; +import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.rm.community.model.user.UserPermissions; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.rm.community.requests.FilePlanComponentAPI; +import org.alfresco.rest.rm.community.requests.RMSiteAPI; +import org.alfresco.rest.rm.community.requests.RMUserAPI; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.data.DataUser; +import org.alfresco.utility.model.SiteModel; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.Test; + +/** + * Create/File electronic records tests + *
+ * These tests only test the creation and filing of electronic records, update at + * present isn't implemented in the API under test. + *

+ * @author Kristijan Conkas + * @since 2.6 + */ +public class DeleteRecordTests extends BaseRestTest +{ + @Autowired + private FilePlanComponentAPI filePlanComponentAPI; + + @Autowired + private RMUserAPI rmUserAPI; + + @Autowired + private DataUser dataUser; + + @Autowired + private RMSiteAPI rmSiteAPI; + + /** image resource file to be used for records body */ + private static final String IMAGE_FILE = "money.JPG"; + + /** + *

+     * Given a record
+     * And that I have the "Delete Record" capability
+     * And write permissions
+     * When I delete the record
+     * Then it is deleted from the file plan
+     * 
+ * + * @param container + * @throws Exception + */ + @Test + ( + dataProvider = "validRootContainers", + description = "Admin user can delete an electronic record" + ) + @AlfrescoTest(jira="RM-4363") + public void adminCanDeleteElectronicRecord(FilePlanComponent container) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // create an electronic record + FilePlanComponent record = FilePlanComponent.builder() + .name("Record " + getRandomAlphanumeric()) + .nodeType(CONTENT_TYPE.toString()) + .build(); + FilePlanComponent newRecord = filePlanComponentAPI.createElectronicRecord(record, IMAGE_FILE, container.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + deleteAndVerify(newRecord); + } + + /** + *
+     * Given a record
+     * And that I have the "Delete Record" capability
+     * And write permissions
+     * When I delete the record
+     * Then it is deleted from the file plan
+     * 
+ * + * @param container + * @throws Exception + */ + @Test + ( + dataProvider = "validRootContainers", + description = "Admin user can delete a non-electronic record" + ) + @AlfrescoTest(jira="RM-4363") + public void adminCanDeleteNonElectronicRecord(FilePlanComponent container) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // create a non-electronic record + FilePlanComponent record = FilePlanComponent.builder() + .name("Record " + getRandomAlphanumeric()) + .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString()) + .build(); + FilePlanComponent newRecord = filePlanComponentAPI.createFilePlanComponent( + record, + container.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + deleteAndVerify(newRecord); + } + + /** + *
+     * Given a record
+     * And that I don't have write permissions
+     * When I try to delete the record
+     * Then nothing happens
+     * And error gets reported
+     * 
+ * + * @param container + * @throws Exception + */ + @Test + ( + description = "User without write permissions can't delete a record" + ) + @AlfrescoTest(jira="RM-4363") + public void userWithoutWritePermissionsCantDeleteRecord() throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // create a non-electronic record in unfiled records + FilePlanComponent record = FilePlanComponent.builder() + .name("Record " + getRandomAlphanumeric()) + .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString()) + .build(); + FilePlanComponent newRecord = filePlanComponentAPI.createFilePlanComponent( + record, + UNFILED_RECORDS_CONTAINER_ALIAS.toString()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // create test user and add it with collab. privileges + UserModel deleteUser = dataUser.createRandomTestUser("delnoperm"); + deleteUser.setUserRole(UserRole.SiteCollaborator); + logger.info("test user: " + deleteUser.getUsername()); + dataUser.addUserToSite(deleteUser, new SiteModel(rmSiteAPI.getSite().getId()), UserRole.SiteCollaborator); + + // add RM role to user + rmUserAPI.assignRoleToUser(deleteUser.getUsername(), UserRoles.ROLE_RM_POWER_USER); + rmUserAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // log in as deleteUser + filePlanComponentAPI.usingRestWrapper().authenticateUser(deleteUser); + + // try to delete newRecord + filePlanComponentAPI.deleteFilePlanComponent(newRecord.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + + /** + *
+     * Given a record
+     * And that I don't have the "Delete Record" capability
+     * When I try to delete the record
+     * Then nothing happens
+     * And error gets reported
+     * 
+ * + * @param container + * @throws Exception + */ + @Test + ( + description = "User without delete records capability can't delete a record" + ) + @AlfrescoTest(jira="RM-4363") + public void userWithoutDeleteRecordsCapabilityCantDeleteRecord() throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // create test user and add it with collab. privileges + UserModel deleteUser = dataUser.createRandomTestUser("delnoperm"); + deleteUser.setUserRole(UserRole.SiteCollaborator); + dataUser.addUserToSite(deleteUser, new SiteModel(rmSiteAPI.getSite().getId()), UserRole.SiteCollaborator); + logger.info("test user: " + deleteUser.getUsername()); + + // add RM role to user, RM Power User doesn't have the Delete Record capabilities + rmUserAPI.assignRoleToUser(deleteUser.getUsername(), UserRoles.ROLE_RM_POWER_USER); + rmUserAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // create random folder + FilePlanComponent randomFolder = createCategoryFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()); + logger.info("random folder:" + randomFolder.getName()); + + // grant deleteUser Filing privileges on randomFolder category, this will be + // inherited to randomFolder + addUserPermission(filePlanComponentAPI.getFilePlanComponent(randomFolder.getParentId()), + deleteUser, UserPermissions.PERMISSION_FILING); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // create a non-electronic record in randomFolder + FilePlanComponent record = FilePlanComponent.builder() + .name("Record " + getRandomAlphanumeric()) + .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString()) + .build(); + FilePlanComponent newRecord = filePlanComponentAPI.createFilePlanComponent( + record, + randomFolder.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // log in as deleteUser + filePlanComponentAPI.usingRestWrapper().authenticateUser(deleteUser); + + // verify the user can see the newRecord + filePlanComponentAPI.getFilePlanComponent(newRecord.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // try to delete newRecord + filePlanComponentAPI.deleteFilePlanComponent(newRecord.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + + /** + * Utility method to delete a record and verify successful deletion + * @param record + * @throws Exception + */ + private void deleteAndVerify(FilePlanComponent record) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // delete it and verify status + filePlanComponentAPI.deleteFilePlanComponent(record.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(NO_CONTENT); + + // try to get deleted file plan component + filePlanComponentAPI.getFilePlanComponent(record.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(NOT_FOUND); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/ElectronicRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/ElectronicRecordTests.java index 2b30770dc8..34312c3c3c 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/ElectronicRecordTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/ElectronicRecordTests.java @@ -41,7 +41,6 @@ import static org.testng.Assert.assertTrue; import org.alfresco.rest.rm.community.base.BaseRestTest; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; -import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties; import org.alfresco.rest.rm.community.requests.FilePlanComponentAPI; import org.alfresco.utility.data.DataUser; import org.springframework.beans.factory.annotation.Autowired; @@ -64,16 +63,16 @@ public class ElectronicRecordTests extends BaseRestTest @Autowired private DataUser dataUser; - + /** image resource file to be used for records body */ private static final String IMAGE_FILE = "money.JPG"; - + /** Valid root containers where electronic records can be created */ @DataProvider(name = "invalidParentContainers") public Object[][] invalidContainers() throws Exception { return new Object[][] { // record category - { getFilePlanComponentAsUser(dataUser.getAdminUser(), + { getFilePlanComponentAsUser(dataUser.getAdminUser(), createCategoryFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()).getParentId()) }, // file plan root { getFilePlanComponentAsUser(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()) }, @@ -83,7 +82,7 @@ public class ElectronicRecordTests extends BaseRestTest { getFilePlanComponentAsUser(dataUser.getAdminUser(), HOLDS_ALIAS.toString()) }, }; } - + /** *
      * Given a parent container that is NOT a record folder or an unfiled record folder
@@ -103,10 +102,13 @@ public class ElectronicRecordTests extends BaseRestTest
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
 
-        FilePlanComponent record = new FilePlanComponent("Record " + getRandomAlphanumeric(), CONTENT_TYPE.toString(), 
-            new FilePlanComponentProperties());
+        // Build object the filePlan
+        FilePlanComponent record = FilePlanComponent.builder()
+                                                .name("Record " + getRandomAlphanumeric())
+                                                .nodeType(CONTENT_TYPE.toString())
+                                                .build();
         filePlanComponentAPI.createElectronicRecord(record, IMAGE_FILE, container.getId());
-        
+
         // verify the create request status code
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY);
     }
@@ -114,7 +116,7 @@ public class ElectronicRecordTests extends BaseRestTest
     /**
      * 
      * Given a parent container that is a record folder
-     * And the record folder is closed 
+     * And the record folder is closed
      * When I try to create an electronic record within the parent container
      * Then nothing happens
      * And an error is reported
@@ -126,22 +128,24 @@ public class ElectronicRecordTests extends BaseRestTest
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
         FilePlanComponent recordFolder = createCategoryFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString());
-        
+
         // the folder should be open
         assertFalse(recordFolder.getProperties().getIsClosed());
-        
+
         // close the folder
         closeFolder(recordFolder.getId());
-        
+
         // try to create it, this should fail
-        FilePlanComponent record = new FilePlanComponent("Record " + getRandomAlphanumeric(), CONTENT_TYPE.toString(), 
-            new FilePlanComponentProperties());
+        FilePlanComponent record = FilePlanComponent.builder()
+                                                .name("Record " + getRandomAlphanumeric())
+                                                .nodeType(CONTENT_TYPE.toString())
+                                                .build();
         filePlanComponentAPI.createElectronicRecord(record, IMAGE_FILE, recordFolder.getId());
-        
+
         // verify the status code
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY);
     }
-    
+
     /**
      * 
      * Given a parent container that is a record folder
@@ -164,13 +168,13 @@ public class ElectronicRecordTests extends BaseRestTest
      */
     @Test
     (
-        dataProvider = "validRootContainers", 
+        dataProvider = "validRootContainers",
         description = "Electronic record can only be created if all mandatory properties are given"
     )
     public void canCreateElectronicRecordOnlyWithMandatoryProperties(FilePlanComponent container) throws Exception
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
-        
+
         logger.info("Root container:\n" + toJson(container));
         if (container.getNodeType().equals(RECORD_FOLDER_TYPE.toString()))
         {
@@ -179,17 +183,17 @@ public class ElectronicRecordTests extends BaseRestTest
         }
 
         // component without name
-        FilePlanComponent record = new FilePlanComponent();
-        record.setNodeType(CONTENT_TYPE.toString());
-        record.setProperties(new FilePlanComponentProperties());
-        
+        FilePlanComponent record = FilePlanComponent.builder()
+                                                    .nodeType(CONTENT_TYPE.toString())
+                                                    .build();
+
         // try to create it
         filePlanComponentAPI.createFilePlanComponent(record, container.getId());
 
         // verify the status code is BAD_REQUEST
-        filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(BAD_REQUEST);      
+        filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(BAD_REQUEST);
     }
-    
+
     /**
      * 
      * Given a parent container that is a record folder
@@ -216,13 +220,47 @@ public class ElectronicRecordTests extends BaseRestTest
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
 
-        FilePlanComponent record = new FilePlanComponent("Record " + getRandomAlphanumeric(), CONTENT_TYPE.toString(), 
-            new FilePlanComponentProperties());
+        FilePlanComponent record = FilePlanComponent.builder()
+                                                    .name("Record " + getRandomAlphanumeric())
+                                                    .nodeType(CONTENT_TYPE.toString())
+                                                    .build();
         String newRecordId = filePlanComponentAPI.createElectronicRecord(record, IMAGE_FILE, container.getId()).getId();
-        
+
         // verify the create request status code
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED);
-        
+
+        // get newly created electonic record and verify its properties
+        FilePlanComponent electronicRecord = filePlanComponentAPI.getFilePlanComponent(newRecordId);
+        // created record will have record identifier inserted in its name but will be prefixed with
+        // the name it was created as
+        assertTrue(electronicRecord.getName().startsWith(record.getName()));
+    }
+
+    /**
+     * This test verified that in the test client implementation if record name isn't specified it
+     * defaults to filed file name.
+     * @param container valid record container
+     * @throws Exception if record creation failed
+     */
+    @Test
+    (
+        dataProvider = "validRootContainers",
+        description = "Electronic records can be created in unfiled record folder or unfiled record root"
+    )
+    public void recordNameDerivedFromFileName(FilePlanComponent container) throws Exception
+    {
+        filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // record object without name set
+        FilePlanComponent record = FilePlanComponent.builder()
+                .nodeType(CONTENT_TYPE.toString())
+                .build();
+
+        String newRecordId = filePlanComponentAPI.createElectronicRecord(record, IMAGE_FILE, container.getId()).getId();
+
+        // verify the create request status code
+        filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED);
+
         // get newly created electonic record and verify its properties
         FilePlanComponent electronicRecord = filePlanComponentAPI.getFilePlanComponent(newRecordId);
         // record will have record identifier inserted in its name but will for sure start with file name
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/FilePlanTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/FilePlanTests.java
index d0b6be85b2..9280b306db 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/FilePlanTests.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/FilePlanTests.java
@@ -199,9 +199,12 @@ public class FilePlanTests extends BaseRestTest
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
 
         // Build object for updating the filePlan
-        FilePlanComponent filePlanComponent = new FilePlanComponent();
-        FilePlanComponentProperties filePlanComponentProperties=new FilePlanComponentProperties(FILE_PLAN_TITLE, FILE_PLAN_DESCRIPTION);
-        filePlanComponent.setProperties(filePlanComponentProperties);
+        FilePlanComponent filePlanComponent = FilePlanComponent.builder()
+            .properties(FilePlanComponentProperties.builder()
+                            .title(FILE_PLAN_TITLE)
+                            .description(FILE_PLAN_DESCRIPTION)
+                            .build())
+            .build();
 
         // Update the record category
         FilePlanComponent renamedFilePlanComponent = filePlanComponentAPI.updateFilePlanComponent(filePlanComponent,FILE_PLAN_ALIAS.toString());
@@ -301,7 +304,12 @@ public class FilePlanTests extends BaseRestTest
         String name = filePlanAlias + getRandomAlphanumeric();
 
         // Build the file plan root properties
-        FilePlanComponent filePlanComponent = new FilePlanComponent(name,rmType.toString(),new FilePlanComponentProperties());
+        FilePlanComponent filePlanComponent = FilePlanComponent.builder()
+                .name(name)
+                .nodeType(rmType.toString())
+                .properties(FilePlanComponentProperties.builder()
+                                .build())
+                .build();
 
         // Authenticate with admin user
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java
index c8cc153545..968edbe9dd 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java
@@ -70,10 +70,10 @@ public class NonElectronicRecordTests extends BaseRestTest
 
     @Autowired
     private DataUser dataUser;
-    
+
     @Autowired
     private RMSiteAPI rmSiteAPI;
-        
+
     /**
      * 
      * Given a parent container that is NOT a record folder or an unfiled record folder
@@ -87,24 +87,25 @@ public class NonElectronicRecordTests extends BaseRestTest
     public void cantCreateForInvalidParentIds() throws Exception
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
-        
+
         // non-electronic record object to be used for create tests
-        FilePlanComponent nonElectronicRecord = new FilePlanComponent(
-            "Record " + getRandomAlphanumeric(),
-            NON_ELECTRONIC_RECORD_TYPE.toString(),
-            new FilePlanComponentProperties());
-        
+        FilePlanComponent nonElectronicRecord = FilePlanComponent.builder()
+                                                .name("Record " + getRandomAlphanumeric())
+                                                .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                                .build();
+
         // create record category, non-electronic records can't be its children
-        FilePlanComponent recordCategory = filePlanComponentAPI.createFilePlanComponent(
-            new FilePlanComponent("Category " + getRandomAlphanumeric(), 
-                RECORD_CATEGORY_TYPE.toString(),
-                new FilePlanComponentProperties()), 
-            FILE_PLAN_ALIAS.toString());
-        
+        FilePlanComponent recordCategoryModel = FilePlanComponent.builder()
+                                                         .name("Category " + getRandomAlphanumeric())
+                                                         .nodeType(RECORD_CATEGORY_TYPE.toString())
+                                                         .build();
+
+        FilePlanComponent recordCategory = filePlanComponentAPI.createFilePlanComponent(recordCategoryModel, FILE_PLAN_ALIAS.toString());
+
         // iterate through all invalid parent containers and try to create/file an electronic record
         asList(FILE_PLAN_ALIAS.toString(), TRANSFERS_ALIAS.toString(), HOLDS_ALIAS.toString(), recordCategory.getId())
             .stream()
-            .forEach(id -> 
+            .forEach(id ->
             {
                 try
                 {
@@ -118,7 +119,7 @@ public class NonElectronicRecordTests extends BaseRestTest
                 filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY);
             });
     }
-    
+
     /**
      * 
      * Given a parent container that is a record folder
@@ -144,14 +145,14 @@ public class NonElectronicRecordTests extends BaseRestTest
     public void canCreateInValidContainers(FilePlanComponent container) throws Exception
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
-        
+
         logger.info("Root container:\n" + toJson(container));
         if (container.getNodeType().equals(RECORD_FOLDER_TYPE.toString()))
         {
             // only record folders can be open or closed
             assertFalse(container.getProperties().getIsClosed());
         }
-        
+
         // use these properties for non-electronic record to be created
         String title = "Title " + getRandomAlphanumeric();
         String description = "Description " + getRandomAlphanumeric();
@@ -159,33 +160,38 @@ public class NonElectronicRecordTests extends BaseRestTest
         String file = "File " + getRandomAlphanumeric();
         String shelf = "Shelf " + getRandomAlphanumeric();
         String location = "Location " + getRandomAlphanumeric();
-        
+
         Random random = new Random();
         Integer copies = random.nextInt(Integer.MAX_VALUE);
         Integer size = random.nextInt(Integer.MAX_VALUE);
-        
-        // set values of all available properties
-        FilePlanComponentProperties properties = new FilePlanComponentProperties(title, description);
-        properties.setBox(box);
-        properties.setFile(file);
-        properties.setShelf(shelf);
-        properties.setLocation(location);
-        properties.setNumberOfCopies(copies);
-        properties.setPhysicalSize(size);
-        
+
+        // set values of all available properties for the non electronic records
+        FilePlanComponent filePlanComponent = FilePlanComponent.builder()
+                                                           .name("Record " + getRandomAlphanumeric())
+                                                           .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                                           .properties(FilePlanComponentProperties.builder()
+                                                                                                  .title(title)
+                                                                                                  .description(description)
+                                                                                                  .box(box)
+                                                                                                  .file(file)
+                                                                                                  .shelf(shelf)
+                                                                                                  .location(location)
+                                                                                                  .numberOfCopies(copies)
+                                                                                                  .physicalSize(size)
+                                                                                                  .build())
+                                                           .build();
+
         // create non-electronic record
         String nonElectronicId = filePlanComponentAPI.createFilePlanComponent(
-            new FilePlanComponent("Record " + getRandomAlphanumeric(), 
-                NON_ELECTRONIC_RECORD_TYPE.toString(),
-                properties), 
+            filePlanComponent,
             container.getId()).getId();
-        
+
         // verify the create request status code
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED);
-        
+
         // get newly created non-electonic record and verify its properties
         FilePlanComponent nonElectronicRecord = filePlanComponentAPI.getFilePlanComponent(nonElectronicId);
-        
+
         assertEquals(title, nonElectronicRecord.getProperties().getTitle());
         assertEquals(description, nonElectronicRecord.getProperties().getDescription());
         assertEquals(box, nonElectronicRecord.getProperties().getBox());
@@ -195,11 +201,11 @@ public class NonElectronicRecordTests extends BaseRestTest
         assertEquals(copies, nonElectronicRecord.getProperties().getNumberOfCopies());
         assertEquals(size, nonElectronicRecord.getProperties().getPhysicalSize());
     }
-    
+
     /**
      * 
      * Given a parent container that is a record folder
-     * And the record folder is closed 
+     * And the record folder is closed
      * When I try to create a non-electronic record within the parent container
      * Then nothing happens
      * And an error is reported
@@ -211,21 +217,22 @@ public class NonElectronicRecordTests extends BaseRestTest
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
         FilePlanComponent recordFolder = createCategoryFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString());
-        
+
         // the folder should be open
         assertFalse(recordFolder.getProperties().getIsClosed());
-        
+
         // close the folder
         closeFolder(recordFolder.getId());
-        
+
         // try to create it, this should fail and throw an exception
 
-        filePlanComponentAPI.createFilePlanComponent(
-            new FilePlanComponent("Record " + getRandomAlphanumeric(), 
-                NON_ELECTRONIC_RECORD_TYPE.toString(),
-                new FilePlanComponentProperties()), 
-            recordFolder.getId()).getId();
-        
+        filePlanComponentAPI.createFilePlanComponent(FilePlanComponent.builder()
+                                                                      .name("Record " + getRandomAlphanumeric())
+                                                                      .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                                                      .build(),
+                                                    recordFolder.getId())
+                                                                    .getId();
+
         // verify the status code
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY);
     }
@@ -251,31 +258,32 @@ public class NonElectronicRecordTests extends BaseRestTest
      */
     @Test
     (
-        dataProvider = "validRootContainers", 
+        dataProvider = "validRootContainers",
         description = "Non-electronic record can only be created if all mandatory properties are given"
     )
     public void allMandatoryPropertiesRequired(FilePlanComponent container) throws Exception
     {
         filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
-        
+
         logger.info("Root container:\n" + toJson(container));
         if (container.getNodeType().equals(RECORD_FOLDER_TYPE.toString()))
         {
             // only record folders can be open or closed
             assertFalse(container.getProperties().getIsClosed());
         }
-        
+
         // component without name and title
-        FilePlanComponent noNameOrTitle = getDummyNonElectronicRecord(); 
-        
+        FilePlanComponent noNameOrTitle = getDummyNonElectronicRecord();
+
         // component with title only
         FilePlanComponent titleOnly = getDummyNonElectronicRecord();
-        FilePlanComponentProperties properties = new FilePlanComponentProperties();
-        properties.setTitle("Title " + getRandomAlphanumeric());
+        FilePlanComponentProperties properties = FilePlanComponentProperties.builder()
+                                                                            .title("Title " + getRandomAlphanumeric())
+                                                                            .build();
         titleOnly.setProperties(properties);
 
-        // try to create invalid components 
-        asList(noNameOrTitle, titleOnly).stream().forEach(c -> 
+        // try to create invalid components
+        asList(noNameOrTitle, titleOnly).stream().forEach(c ->
         {
             try
             {
@@ -284,21 +292,21 @@ public class NonElectronicRecordTests extends BaseRestTest
             catch (Exception error)
             {
             }
-            
+
             // this should fail and throw an exception
             try
-            {                
+            {
                 filePlanComponentAPI.createFilePlanComponent(c, container.getId());
-            } 
+            }
             catch (Exception e)
             {
             }
 
             // verify the status code is BAD_REQUEST
             filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(BAD_REQUEST);
-        });        
+        });
     }
-    
+
     /**
      * 
      * Given that I am a user without RM privileges
@@ -310,7 +318,7 @@ public class NonElectronicRecordTests extends BaseRestTest
      */
     @Test
     (
-        dataProvider = "validRootContainers", 
+        dataProvider = "validRootContainers",
         description = "Non-electronic record can't be created if user doesn't have RM privileges"
     )
     public void cantCreateIfNoRmPrivileges(FilePlanComponent container) throws Exception
@@ -319,16 +327,23 @@ public class NonElectronicRecordTests extends BaseRestTest
         UserModel user = createUserWithRole(username, UserRole.SiteManager);
 
         filePlanComponentAPI.usingRestWrapper().authenticateUser(user);
-        
+
         // try to create a fileplan component
-        FilePlanComponent record = new FilePlanComponent("Record Name", NON_ELECTRONIC_RECORD_TYPE.toString(),
-            new FilePlanComponentProperties("Name", "Title"));
-            
+        FilePlanComponent record=FilePlanComponent.builder()
+                                                  .properties(FilePlanComponentProperties.builder()
+                                                                                         .description("Description")
+                                                                                         .title("Title")
+                                                                                         .build())
+                                                  .name("Record Name")
+                                                  .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                                  .build();
+
+
         // this should fail and throw an exception
         try
-        {                
+        {
             filePlanComponentAPI.createFilePlanComponent(record, container.getId());
-        } 
+        }
         catch (Exception e)
         {
         }
@@ -336,18 +351,19 @@ public class NonElectronicRecordTests extends BaseRestTest
         // user who isn't an RM site member can't access the container path
         filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN);
     }
-    
+
     /**
      * Helper function to return an empty FilePlanComponent for non-electronic record
      * @return
      */
     private FilePlanComponent getDummyNonElectronicRecord()
     {
-        FilePlanComponent component = new FilePlanComponent();
-        component.setNodeType(NON_ELECTRONIC_RECORD_TYPE.toString());
+        FilePlanComponent component=FilePlanComponent.builder()
+                                            .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                            .build();
         return component;
     }
-    
+
     /**
      * Create user with given role and add it to RM site
      * 
@@ -369,13 +385,13 @@ public class NonElectronicRecordTests extends BaseRestTest UserModel user = new UserModel(); user.setUsername(userName); user.setPassword(userName); - + if (!dataUser.isUserInRepo(userName)) { // user doesn't exist, create it user = dataUser.createUser(userName, userName); user.setUserRole(userRole); - + dataUser.addUserToSite(user, new SiteModel(siteId), userRole); } diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordCategoryTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordCategoryTest.java index c812282573..12e8c9ed28 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordCategoryTest.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordCategoryTest.java @@ -94,8 +94,15 @@ public class RecordCategoryTest extends BaseRestTest String categoryTitle = "Category title " + getRandomAlphanumeric(); // Build the record category properties - FilePlanComponent recordCategory = new FilePlanComponent(categoryName,RECORD_CATEGORY_TYPE.toString(), - new FilePlanComponentProperties(categoryTitle)); + FilePlanComponent recordCategory = FilePlanComponent.builder() + .name(categoryName) + .nodeType(RECORD_CATEGORY_TYPE.toString()) + .properties( + FilePlanComponentProperties.builder() + .title(categoryTitle) + .build()) + .build(); + // Create the record category FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS.toString()); @@ -103,9 +110,9 @@ public class RecordCategoryTest extends BaseRestTest restWrapper.assertStatusCodeIs(CREATED); // Verify the returned file plan component - assertTrue(filePlanComponent.isCategory()); - assertFalse(filePlanComponent.isFile()); - assertFalse(filePlanComponent.isRecordFolder()); + assertTrue(filePlanComponent.getIsCategory()); + assertFalse(filePlanComponent.getIsFile()); + assertFalse(filePlanComponent.getIsRecordFolder()); assertEquals(filePlanComponent.getName(), categoryName); assertEquals(filePlanComponent.getNodeType(), RECORD_CATEGORY_TYPE.toString()); @@ -139,8 +146,14 @@ public class RecordCategoryTest extends BaseRestTest String categoryTitle = "Category title " + getRandomAlphanumeric(); // Build the record category properties - FilePlanComponent recordCategory = new FilePlanComponent(categoryName, RECORD_CATEGORY_TYPE.toString(), - new FilePlanComponentProperties(categoryTitle)); + FilePlanComponent recordCategory = FilePlanComponent.builder() + .name(categoryName) + .nodeType(RECORD_CATEGORY_TYPE.toString()) + .properties( + FilePlanComponentProperties.builder() + .title(categoryTitle) + .build()) + .build(); // Create the record category FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS.toString()); @@ -148,7 +161,7 @@ public class RecordCategoryTest extends BaseRestTest String newCategoryName = "Rename " + categoryName; // Build the properties which will be updated - FilePlanComponent recordCategoryUpdated = new FilePlanComponent(newCategoryName); + FilePlanComponent recordCategoryUpdated = FilePlanComponent.builder().name(newCategoryName).build(); // Update the record category FilePlanComponent renamedFilePlanComponent = filePlanComponentAPI.updateFilePlanComponent(recordCategoryUpdated, filePlanComponent.getId()); @@ -186,8 +199,15 @@ public class RecordCategoryTest extends BaseRestTest String categoryTitle = "Category title " + getRandomAlphanumeric(); // Build the record category properties - FilePlanComponent recordCategory = new FilePlanComponent(categoryName, RECORD_CATEGORY_TYPE.toString(), - new FilePlanComponentProperties(categoryTitle)); + FilePlanComponent recordCategory = FilePlanComponent.builder() + .name(categoryName) + .nodeType(RECORD_CATEGORY_TYPE.toString()) + .properties( + FilePlanComponentProperties.builder() + .title(categoryTitle) + .build()) + .build(); + // Create the record category FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS.toString()); @@ -226,9 +246,9 @@ public class RecordCategoryTest extends BaseRestTest // Verify child category assertEquals(childCategory.getParentId(), rootCategory.getId()); - assertTrue(childCategory.isCategory()); - assertFalse(childCategory.isFile()); - assertFalse(childCategory.isRecordFolder()); + assertTrue(childCategory.getIsCategory()); + assertFalse(childCategory.getIsFile()); + assertFalse(childCategory.getIsRecordFolder()); assertEquals(childCategory.getNodeType(), RECORD_CATEGORY_TYPE.toString()); } @@ -295,19 +315,19 @@ public class RecordCategoryTest extends BaseRestTest assertEquals(filePlanComponent.getParentId(), rootCategory.getId()); // Only categories or folders have been created - assertFalse(filePlanComponent.isFile()); + assertFalse(filePlanComponent.getIsFile()); // Boolean properties related to node type // Only RECORD_CATEGORY_TYPE and RECORD_FOLDER_TYPE have been created if (filePlanComponent.getNodeType().equals(RECORD_CATEGORY_TYPE.toString())) { - assertTrue(filePlanComponent.isCategory()); - assertFalse(filePlanComponent.isRecordFolder()); + assertTrue(filePlanComponent.getIsCategory()); + assertFalse(filePlanComponent.getIsRecordFolder()); } else { - assertTrue(filePlanComponent.isRecordFolder()); - assertFalse(filePlanComponent.isCategory()); + assertTrue(filePlanComponent.getIsRecordFolder()); + assertFalse(filePlanComponent.getIsCategory()); } // Does returned object have the same contents as the created one? @@ -348,8 +368,14 @@ public class RecordCategoryTest extends BaseRestTest FilePlanComponent category = createCategory(FILE_PLAN_ALIAS.toString(), COMPONENT_NAME); //Build node properties - FilePlanComponent recordCategory = new FilePlanComponent(COMPONENT_NAME,nodeType, - new FilePlanComponentProperties("Title for " + COMPONENT_NAME)); + FilePlanComponent recordCategory = FilePlanComponent.builder() + .name(COMPONENT_NAME) + .nodeType(nodeType) + .properties( + FilePlanComponentProperties.builder() + .title("Title for " + COMPONENT_NAME) + .build()) + .build(); //create the invalid node type filePlanComponentAPI.createFilePlanComponent(recordCategory, category.getId()); @@ -383,8 +409,14 @@ public class RecordCategoryTest extends BaseRestTest { RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); //Build node properties - FilePlanComponent component = new FilePlanComponent(componentName, componentType.toString(), - new FilePlanComponentProperties("Title for " + componentName)); + FilePlanComponent component = FilePlanComponent.builder() + .name(componentName) + .nodeType(componentType.toString()) + .properties(FilePlanComponentProperties.builder() + .title("Title for " + componentName) + .build()) + .build(); + FilePlanComponent fpc = filePlanComponentAPI.createFilePlanComponent(component, parentComponentId); restWrapper.assertStatusCodeIs(CREATED); return fpc; diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordFolderTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordFolderTests.java index 705e79258b..bab76aec0c 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordFolderTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/RecordFolderTests.java @@ -31,6 +31,7 @@ import static org.alfresco.rest.rm.community.base.TestData.FOLDER_NAME; import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.IS_CLOSED; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE; import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; import static org.springframework.http.HttpStatus.CREATED; @@ -44,6 +45,7 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.fail; import static org.testng.AssertJUnit.assertTrue; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.NoSuchElementException; @@ -93,8 +95,13 @@ public class RecordFolderTests extends BaseRestTest filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); FilePlanComponent filePlanComponent = createCategory(FILE_PLAN_ALIAS.toString(), CATEGORY); - FilePlanComponentProperties filePlanComponentProperties = new FilePlanComponentProperties(FOLDER_TITLE); - FilePlanComponent recordFolder = new FilePlanComponent(FOLDER_NAME,RECORD_FOLDER_TYPE.toString(), filePlanComponentProperties); + FilePlanComponent recordFolder = FilePlanComponent.builder() + .name(FOLDER_NAME) + .nodeType(RECORD_FOLDER_TYPE.toString()) + .properties(FilePlanComponentProperties.builder() + .title(FOLDER_TITLE) + .build()) + .build(); // Create the record folder FilePlanComponent folder = filePlanComponentAPI.createFilePlanComponent(recordFolder, filePlanComponent.getId()); @@ -105,9 +112,9 @@ public class RecordFolderTests extends BaseRestTest // Check folder has been created within the category created assertEquals(filePlanComponent.getId(),folder.getParentId()); // Verify the returned properties for the file plan component - record folder - assertFalse(folder.isCategory()); - assertFalse(folder.isFile()); - assertTrue(folder.isRecordFolder()); + assertFalse(folder.getIsCategory()); + assertFalse(folder.getIsFile()); + assertTrue(folder.getIsRecordFolder()); assertEquals(folder.getName(), FOLDER_NAME); assertEquals(folder.getNodeType(), RECORD_FOLDER_TYPE.toString()); @@ -138,8 +145,14 @@ public class RecordFolderTests extends BaseRestTest String componentID = filePlanComponentAPI.getFilePlanComponent(filePlanComponent).getId(); // Build the record category properties - FilePlanComponent recordFolder = new FilePlanComponent(FOLDER_NAME,RECORD_FOLDER_TYPE.toString(), - new FilePlanComponentProperties(FOLDER_TITLE)); + FilePlanComponent recordFolder = FilePlanComponent.builder() + .name(FOLDER_NAME) + .nodeType(RECORD_FOLDER_TYPE.toString()) + .properties(FilePlanComponentProperties.builder() + .title(FOLDER_TITLE) + .build()) + .build(); + // Create a record folder filePlanComponentAPI.createFilePlanComponent(recordFolder, componentID); @@ -168,10 +181,10 @@ public class RecordFolderTests extends BaseRestTest // Verify the returned properties for the file plan component - record folder assertEquals(RECORD_FOLDER_TYPE.toString(),folderDetails.getNodeType()); - assertTrue(folderDetails.isRecordFolder()); - assertFalse(folderDetails.isCategory()); - assertFalse(folderDetails.isFile()); - assertFalse(folderDetails.isClosed()); + assertTrue(folderDetails.getIsRecordFolder()); + assertFalse(folderDetails.getIsCategory()); + assertFalse(folderDetails.getIsFile()); + assertFalse(folderDetails.getIsClosed()); assertEquals(FOLDER_NAME,folderDetails.getName()); assertEquals(dataUser.getAdminUser().getUsername(),folderDetails.getCreatedByUser().getId()); @@ -210,11 +223,16 @@ public class RecordFolderTests extends BaseRestTest String location = "Location"+getRandomAlphanumeric(); //Create the file plan component properties to update - FilePlanComponentProperties filePlanComponentProperties = new FilePlanComponentProperties(folderTitle, folderDescription); - filePlanComponentProperties.setVitalRecord(true); - filePlanComponentProperties.setReviewPeriod( new ReviewPeriod("month","1")); - filePlanComponentProperties.setLocation(location); - FilePlanComponent recordFolder = new FilePlanComponent(folderName,filePlanComponentProperties); + FilePlanComponent recordFolder = FilePlanComponent.builder() + .name(folderName) + .properties(FilePlanComponentProperties.builder() + .title(folderTitle) + .description(folderDescription) + .vitalRecord(true) + .reviewPeriod(new ReviewPeriod("month","1")) + .location(location) + .build()) + .build(); // Update the record category FilePlanComponent folderUpdated = filePlanComponentAPI.updateFilePlanComponent(recordFolder, folder.getId()); @@ -226,7 +244,7 @@ public class RecordFolderTests extends BaseRestTest assertEquals(folderName, folderUpdated.getName()); assertEquals(folderDescription, folderUpdated.getProperties().getDescription()); assertEquals(folderTitle, folderUpdated.getProperties().getTitle()); - assertTrue(folderUpdated.getProperties().isVitalRecord()); + assertTrue(folderUpdated.getProperties().getVitalRecord()); assertEquals(location, folderUpdated.getProperties().getLocation()); assertNotNull(folderUpdated.getProperties().getReviewPeriod().getPeriodType()); assertNotNull(folderUpdated.getProperties().getReviewPeriod().getExpression()); @@ -324,11 +342,11 @@ public class RecordFolderTests extends BaseRestTest // Is parent Id set correctly assertEquals(filePlanComponent.getParentId(), category.getId()); - assertFalse(filePlanComponent.isFile()); + assertFalse(filePlanComponent.getIsFile()); // Boolean properties related to node type - assertTrue(filePlanComponent.isRecordFolder()); - assertFalse(filePlanComponent.isCategory()); + assertTrue(filePlanComponent.getIsRecordFolder()); + assertFalse(filePlanComponent.getIsCategory()); assertEquals(createdComponent.getName(), filePlanComponent.getName()); assertEquals(createdComponent.getNodeType(), filePlanComponent.getNodeType()); @@ -342,6 +360,97 @@ public class RecordFolderTests extends BaseRestTest ); } + + /** + * Given that I want to create a record folder + * When I use the API with the relativePath + * Then the categories specified in the relativePath that don't exist are created within the record folder + * + * Containers in the relativePath that do not exist are created before the node is created + */ + @Test + ( + description = "Create a folder based on the relativePath. " + + "Containers in the relativePath that do not exist are created before the node is created" + ) + public void createFolderWithRelativePath() throws Exception + { + //RelativePath specify the container structure to create relative to the record folder to be created + String RELATIVE_PATH = LocalDateTime.now().getYear()+"/"+ LocalDateTime.now().getMonth()+"/"+ LocalDateTime.now().getDayOfMonth(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + //The record folder to be created + FilePlanComponent recordFolder = FilePlanComponent.builder() + .name(FOLDER_NAME) + .nodeType(RECORD_FOLDER_TYPE.toString()) + .relativePath(RELATIVE_PATH) + .build(); + + // Create the record folder + FilePlanComponent folder = filePlanComponentAPI.withParams("include="+ PATH).createFilePlanComponent(recordFolder,FILE_PLAN_ALIAS.toString()); + //Check the API response code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // Verify the returned properties for the file plan component - record folder + assertFalse(folder.getIsCategory()); + assertFalse(folder.getIsFile()); + assertTrue(folder.getIsRecordFolder()); + + //Check the path return contains the RELATIVE_PATH + assertTrue(folder.getPath().getName().contains(RELATIVE_PATH)); + //check the parent is a category + assertTrue(filePlanComponentAPI.getFilePlanComponent(folder.getParentId()).getIsCategory()); + + //check the created folder from the server + folder=filePlanComponentAPI.withParams("include=" + PATH).getFilePlanComponent(folder.getId()); + //Check the API response code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + // Verify the returned properties for the file plan component - record folder + assertFalse(folder.getIsCategory()); + assertFalse(folder.getIsFile()); + assertTrue(folder.getIsRecordFolder()); + + //Check the path return contains the RELATIVE_PATH + assertTrue(folder.getPath().getName().contains(RELATIVE_PATH)); + + //New Relative Path only a part of containers need to be created before the record folder + String NEW_RELATIVE_PATH = LocalDateTime.now().getYear() + "/" + LocalDateTime.now().getMonth() + "/" +( LocalDateTime.now().getDayOfMonth()+1); + //The record folder to be created + FilePlanComponent recordFolder2 = FilePlanComponent.builder() + .name(FOLDER_NAME) + .nodeType(RECORD_FOLDER_TYPE.toString()) + .relativePath(NEW_RELATIVE_PATH) + .build(); + + // Create the record folder + FilePlanComponent folder2 = filePlanComponentAPI.withParams("include=" + PATH).createFilePlanComponent(recordFolder2, FILE_PLAN_ALIAS.toString()); + //Check the API response code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // Verify the returned properties for the file plan component - record folder + assertFalse(folder2.getIsCategory()); + assertFalse(folder2.getIsFile()); + assertTrue(folder2.getIsRecordFolder()); + //Check the path return contains the NEW_RELATIVE_PATH + assertTrue(folder2.getPath().getName().contains(NEW_RELATIVE_PATH)); + + //check the parent is a category + assertTrue(filePlanComponentAPI.getFilePlanComponent(folder.getParentId()).getIsCategory()); + + // Check the folder created on the server + folder2 = filePlanComponentAPI.withParams("include=" + PATH).getFilePlanComponent(folder2.getId()); + //Check the API response code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // Verify the returned properties for the file plan component - record folder + assertFalse(folder2.getIsCategory()); + assertFalse(folder2.getIsFile()); + assertTrue(folder2.getIsRecordFolder()); + //Check the path return contains the NEW_RELATIVE_PATH + assertTrue(folder2.getPath().getName().contains(NEW_RELATIVE_PATH)); + } + @AfterClass (alwaysRun = true) public void tearDown() throws Exception { diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java index 74e669d8ce..d008d5fbae 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java @@ -107,8 +107,14 @@ public class UnfiledRecordsFolderTests extends BaseRestTest String folderDescription = folderName + " Description"; // Build unfiled records folder properties - FilePlanComponent unfiledFolder=new FilePlanComponent(folderName,UNFILED_RECORD_FOLDER_TYPE.toString(), - new FilePlanComponentProperties(folderTitle,folderDescription)); + FilePlanComponent unfiledFolder = FilePlanComponent.builder() + .name(folderName) + .nodeType(UNFILED_RECORD_FOLDER_TYPE.toString()) + .properties(FilePlanComponentProperties.builder() + .title(folderTitle) + .description(folderDescription) + .build()) + .build(); FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(unfiledFolder, UNFILED_RECORDS_CONTAINER_ALIAS.toString()); @@ -117,9 +123,9 @@ public class UnfiledRecordsFolderTests extends BaseRestTest filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); // Verify the returned file plan component - assertFalse(filePlanComponent.isCategory()); - assertFalse(filePlanComponent.isFile()); - assertFalse(filePlanComponent.isRecordFolder()); // it is not a _normal_ record folder! + assertFalse(filePlanComponent.getIsCategory()); + assertFalse(filePlanComponent.getIsFile()); + assertFalse(filePlanComponent.getIsRecordFolder()); // it is not a _normal_ record folder! assertEquals(filePlanComponent.getName(), folderName); assertEquals(filePlanComponent.getNodeType(), UNFILED_RECORD_FOLDER_TYPE.toString()); @@ -151,8 +157,14 @@ public class UnfiledRecordsFolderTests extends BaseRestTest logger.info("creating " + componentType.toString()); // Build unfiled records folder properties - FilePlanComponent unfiledFolder = new FilePlanComponent(folderName, componentType.toString(), - new FilePlanComponentProperties(folderTitle, folderDescription)); + FilePlanComponent unfiledFolder = FilePlanComponent.builder() + .name(folderName) + .nodeType(componentType.toString()) + .properties(FilePlanComponentProperties.builder() + .title(folderTitle) + .description(folderDescription) + .build()) + .build(); try { @@ -189,8 +201,14 @@ public class UnfiledRecordsFolderTests extends BaseRestTest assertEquals(parentFolderName, parentFolder.getName()); // Build the unfiled records folder properties - FilePlanComponent unfiledFolder = new FilePlanComponent(childFolderName, UNFILED_RECORD_FOLDER_TYPE.toString(), - new FilePlanComponentProperties(childFolderTitle, childFolderDescription)); + FilePlanComponent unfiledFolder = FilePlanComponent.builder() + .name(childFolderName) + .nodeType(UNFILED_RECORD_FOLDER_TYPE.toString()) + .properties(FilePlanComponentProperties.builder() + .title(childFolderTitle) + .description(childFolderDescription) + .build()) + .build(); // Create it as a child of parentFolder FilePlanComponent childFolder = filePlanComponentAPI.createFilePlanComponent(unfiledFolder, @@ -200,9 +218,9 @@ public class UnfiledRecordsFolderTests extends BaseRestTest restWrapper.assertStatusCodeIs(CREATED); // Verify the returned file plan component - assertFalse(childFolder.isCategory()); - assertFalse(childFolder.isFile()); - assertFalse(childFolder.isRecordFolder()); // it is not a _normal_ record folder! + assertFalse(childFolder.getIsCategory()); + assertFalse(childFolder.getIsFile()); + assertFalse(childFolder.getIsRecordFolder()); // it is not a _normal_ record folder! assertEquals(childFolder.getName(), childFolderName); assertEquals(childFolder.getNodeType(), UNFILED_RECORD_FOLDER_TYPE.toString()); @@ -251,9 +269,14 @@ public class UnfiledRecordsFolderTests extends BaseRestTest assertEquals(folderName, folderToModify.getName()); // Build the properties which will be updated - FilePlanComponent folderToUpdate = new FilePlanComponent(modified + folderToModify.getName(), - new FilePlanComponentProperties(modified + folderToModify.getProperties().getTitle(), - modified + folderToModify.getProperties().getDescription())); + FilePlanComponent folderToUpdate = FilePlanComponent.builder() + .name(modified + folderToModify.getName()) + .properties(FilePlanComponentProperties.builder(). + title(modified + folderToModify.getProperties().getTitle()). + description(modified + folderToModify.getProperties().getDescription()) + .build()) + .build(); + // Update the unfiled records folder filePlanComponentAPI.updateFilePlanComponent(folderToUpdate, folderToModify.getId()); // Verify the status code diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/site/RMSiteTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/site/RMSiteTests.java index 417895d64f..cb562d6525 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/site/RMSiteTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/site/RMSiteTests.java @@ -95,7 +95,10 @@ public class RMSiteTests extends BaseRestTest } // Create the RM site - RMSite rmSite = new RMSite(RM_TITLE, RM_DESCRIPTION, STANDARD); + RMSite rmSite =RMSite.builder().compliance(STANDARD).build(); + rmSite.setTitle(RM_TITLE); + rmSite.setDescription(RM_DESCRIPTION); + RMSite rmSiteResponse = rmSiteAPI.createRMSite(rmSite); // Verify the status code @@ -132,7 +135,10 @@ public class RMSiteTests extends BaseRestTest String newDescription = RM_DESCRIPTION + "createRMSiteWhenSiteExists"; // Create the RM site - RMSite rmSite = new RMSite(newTitle, newDescription, STANDARD); + RMSite rmSite = RMSite.builder().compliance(STANDARD).build(); + rmSite.setTitle(newTitle); + rmSite.setDescription(newDescription); + rmSiteAPI.createRMSite(rmSite); // Verify the status code @@ -236,7 +242,9 @@ public class RMSiteTests extends BaseRestTest rmSiteAPI.usingRestWrapper().authenticateUser(userModel); // Create the RM site - RMSite rmSite = new RMSite(RM_TITLE, RM_DESCRIPTION, DOD5015); + RMSite rmSite = RMSite.builder().compliance(DOD5015).build(); + rmSite.setTitle(RM_TITLE); + rmSite.setDescription(RM_DESCRIPTION); rmSite=rmSiteAPI.createRMSite(rmSite); // Verify the status code @@ -325,7 +333,7 @@ public class RMSiteTests extends BaseRestTest createRMSiteIfNotExists(); // Build the RM site properties - RMSite rmSiteToUpdate = new RMSite(DOD5015); + RMSite rmSiteToUpdate = RMSite.builder().compliance(DOD5015).build(); // Update the RM site rmSiteAPI.updateRMSite(rmSiteToUpdate); diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties index 37b4cd6ede..a42ee061f7 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties @@ -20,4 +20,5 @@ rm.service.node-has-aspect=The record type {1} is already showing for record {0} rm.service.final-version=Final rm.service.final-version-description=The final archived record version rm.service.enable-autoversion-on-record-creation=Auto Version on Record Creation -rm.service.add-children-to-closed-record-folder=You can't add new items to a closed record folder \ No newline at end of file +rm.service.add-children-to-closed-record-folder=You can't add new items to a closed record folder +rm.service.update-record-content=Could not update content property as it's immutable for records. \ No newline at end of file diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml index f4e068dc03..71db247827 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml @@ -45,18 +45,23 @@ - + - + - + + + + + + @@ -84,6 +89,30 @@ + + + + + + + + + + + + + org.alfresco.rm.rest.api.Records + + + + + + + + + + + diff --git a/rm-community/rm-community-repo/pom.xml b/rm-community/rm-community-repo/pom.xml index 51cd214259..3097d04a65 100644 --- a/rm-community/rm-community-repo/pom.xml +++ b/rm-community/rm-community-repo/pom.xml @@ -25,6 +25,7 @@ alfresco-rm-community-repo true ${project.build.directory}/solr/home + 1.4 @@ -532,11 +533,19 @@ /solr4 ${alfresco.solr.home}/context.xml + + org.alfresco + api-explorer + ${api.explorer.version} + /api-explorer + war + true + org.alfresco alfresco-rm-community-rest-api-explorer ${project.version} - /api-explorer + /ig-api-explorer war true diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java index e49df9f140..ba5a48da63 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java @@ -37,20 +37,24 @@ import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies; import org.alfresco.module.org_alfresco_module_rm.model.behaviour.AbstractDisposableItem; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; +import org.alfresco.repo.content.ContentServicePolicies; import org.alfresco.repo.copy.CopyBehaviourCallback; import org.alfresco.repo.copy.CopyDetails; import org.alfresco.repo.copy.CopyServicePolicies; import org.alfresco.repo.copy.DefaultCopyBehaviourCallback; import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.node.integrity.IntegrityException; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.namespace.QName; +import org.springframework.extensions.surf.util.I18NUtil; /** * rma:record behaviour bean @@ -67,7 +71,8 @@ public class RecordAspect extends AbstractDisposableItem RecordsManagementPolicies.OnCreateReference, RecordsManagementPolicies.OnRemoveReference, NodeServicePolicies.OnMoveNodePolicy, - CopyServicePolicies.OnCopyCompletePolicy + CopyServicePolicies.OnCopyCompletePolicy, + ContentServicePolicies.OnContentPropertyUpdatePolicy { /** Well-known location of the scripts folder. */ // TODO make configurable @@ -81,7 +86,10 @@ public class RecordAspect extends AbstractDisposableItem /** record service */ protected RecordService recordService; - + + /** I18N */ + private static final String MSG_CANNOT_UPDATE_RECORD_CONTENT = "rm.service.update-record-content"; + /** * @param extendedSecurityService extended security service */ @@ -336,4 +344,19 @@ public class RecordAspect extends AbstractDisposableItem extendedSecurityService.remove(targetNodeRef); } } + + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.FIRST_EVENT + ) + public void onContentPropertyUpdate(NodeRef nodeRef, QName propertyQName, ContentData beforeValue, ContentData afterValue) + { + // Allow creation of content but not update + if (beforeValue != null) + { + throw new IntegrityException(I18NUtil.getMessage(MSG_CANNOT_UPDATE_RECORD_CONTENT), null); + } + } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/RMNodes.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/RMNodes.java index 983f985e96..e56e5ad748 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/RMNodes.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/RMNodes.java @@ -28,6 +28,8 @@ package org.alfresco.rm.rest.api; import org.alfresco.rest.api.Nodes; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; /** * RM Nodes API @@ -45,4 +47,15 @@ public interface RMNodes extends Nodes public static String PARAM_INCLUDE_HAS_RETENTION_SCHEDULE = "hasRetentionSchedule"; public static String PARAM_INCLUDE_IS_CLOSED = "isClosed"; public static String PARAM_INCLUDE_IS_COMPLETED = "isCompleted"; + + /** + * Gets or creates the relative path starting from the provided parent folder. + * The method decides the type of the created elements considering the + * parent container's type and the type of the node to be created. + * @param parentFolderNodeId the parent folder to start from + * @param relativePath the relative path + * @param nodeTypeQName the type of the node to be created + * @return reference to the last element of the created path + */ + public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName); } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/Records.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/Records.java new file mode 100644 index 0000000000..504b81309b --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/Records.java @@ -0,0 +1,63 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rm.rest.api; + +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rm.rest.api.model.TargetContainer; + +/** + * Records API + * + * @author Ana Bozianu + * @since 2.6 + */ +public interface Records +{ + public static final String PARAM_HIDE_RECORD = "hideRecord"; + + /** + * Creates a record from a file + * + * @param fileId the id of a non record file + * @param parameters the {@link Parameters} object to get the parameters passed into the request + * @return information about the created record + */ + public Node declareFileAsRecord(String fileId, Parameters parameters); + + /** + * Files a record into th fileplan. + * If the record is already filed it links the record to the target folder + * + * @param recordId the id of the record do file/link + * @param target the target parent folder + * @param parameters the {@link Parameters} object to get the parameters passed into the request + * @return information about the new state of the record + */ + public Node fileOrLinkRecord(String recordId, TargetContainer target, Parameters parameters); +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelation.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelation.java similarity index 98% rename from rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelation.java rename to rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelation.java index 5c16af45ab..19a61aaf3f 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelation.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelation.java @@ -25,7 +25,7 @@ * #L% */ -package org.alfresco.rm.rest.api.nodes; +package org.alfresco.rm.rest.api.fileplancomponents; import java.util.ArrayList; import java.util.List; diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResource.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResource.java similarity index 98% rename from rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResource.java rename to rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResource.java index e0d6c8c360..648455f613 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResource.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResource.java @@ -25,7 +25,7 @@ * #L% */ -package org.alfresco.rm.rest.api.nodes; +package org.alfresco.rm.rest.api.fileplancomponents; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.framework.WebApiDescription; diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/package-info.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/package-info.java new file mode 100644 index 0000000000..f4ef3b5150 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/fileplancomponents/package-info.java @@ -0,0 +1,37 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +/** + * Package info that defines the Information Governance Fileplan Components REST API + * + * @author Ana Bozianu + * @since 2.6 + */ +@WebApi(name="ig", scope=Api.SCOPE.PUBLIC, version=1) +package org.alfresco.rm.rest.api.fileplancomponents; +import org.alfresco.rest.framework.Api; +import org.alfresco.rest.framework.WebApi; \ No newline at end of file diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/FilesEntityResource.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/FilesEntityResource.java new file mode 100644 index 0000000000..718d7cc592 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/FilesEntityResource.java @@ -0,0 +1,69 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rm.rest.api.files; + +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.framework.Operation; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.resource.EntityResource; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.webscripts.WithResponse; +import org.alfresco.rm.rest.api.Records; +import org.alfresco.rm.rest.api.model.TargetContainer; +import org.alfresco.util.ParameterCheck; +import org.springframework.beans.factory.InitializingBean; + +/** + * An implementation of an Entity Resource for a file + * + * @author Ana Bozianu + * @since 2.6 + */ +@EntityResource(name="files", title = "Files") +public class FilesEntityResource implements InitializingBean +{ + private Records records; + + public void setRecords(Records records) + { + this.records = records; + } + + @Operation("declare") + @WebApiDescription(title = "Declare as record", description="Declare a file as record.") + public Node declareAsRecord(String fileId, Void body, Parameters parameters, WithResponse withResponse) + { + return records.declareFileAsRecord(fileId, parameters); + } + + @Override + public void afterPropertiesSet() throws Exception + { + ParameterCheck.mandatory("records", this.records); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/package-info.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/package-info.java similarity index 92% rename from rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/package-info.java rename to rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/package-info.java index e8f77618fc..8ba4b1f926 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/package-info.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/files/package-info.java @@ -26,12 +26,12 @@ */ /** - * Package info that defines the Information Governance Nodes REST API + * Package info that defines the Information Governance Files REST API * * @author Ana Bozianu * @since 2.6 */ @WebApi(name="ig", scope=Api.SCOPE.PUBLIC, version=1) -package org.alfresco.rm.rest.api.nodes; +package org.alfresco.rm.rest.api.files; import org.alfresco.rest.framework.Api; import org.alfresco.rest.framework.WebApi; \ No newline at end of file diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java index 2c5b3d28eb..f10aa6e7a1 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java @@ -336,25 +336,30 @@ public class RMNodesImpl extends NodesImpl implements RMNodes public Node createNode(String parentFolderNodeId, Node nodeInfo, Parameters parameters) { // create RM path if needed and call the super method with the last element of the created path - NodeRef parentNodeRef = getOrCreatePath(parentFolderNodeId, nodeInfo); + String relativePath = nodeInfo.getRelativePath(); + + // Get the type of the node to be created + String nodeType = nodeInfo.getNodeType(); + if ((nodeType == null) || nodeType.isEmpty()) + { + throw new InvalidArgumentException("Node type is expected: "+parentFolderNodeId+","+nodeInfo.getName()); + } + QName nodeTypeQName = createQName(nodeType); + + // Get or create the path + NodeRef parentNodeRef = getOrCreatePath(parentFolderNodeId, relativePath, nodeTypeQName); + + // Set relative path to null as we pass the last element from the path nodeInfo.setRelativePath(null); return super.createNode(parentNodeRef.getId(), nodeInfo, parameters); } - /** - * Gets or creates the relative path specified in nodeInfo.relativePath - * starting from the provided parent folder. - * The method decides the type of the created elements considering the - * parent container's type and the type of the node to be created. - * @param parentFolderNodeId the parent folder to start from - * @param nodeInfo information about the node to be created - * @return reference to the last element of the created path - */ - protected NodeRef getOrCreatePath(String parentFolderNodeId, Node nodeInfo) + @Override + public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName) { NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null); - String relativePath = nodeInfo.getRelativePath(); + if (relativePath == null) { return parentNodeRef; @@ -413,14 +418,6 @@ public class RMNodesImpl extends NodesImpl implements RMNodes } else { - // Get the type of the node to be created - String nodeType = nodeInfo.getNodeType(); - if ((nodeType == null) || nodeType.isEmpty()) - { - throw new InvalidArgumentException("Node type is expected: "+parentFolderNodeId+","+nodeInfo.getName()); - } - QName nodeTypeQName = createQName(nodeType); - /* Outside the unfiled record container the path elements are record categories * except the last element which is a record folder if the created node is of type content */ diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RecordsImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RecordsImpl.java new file mode 100644 index 0000000000..357fa47a53 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RecordsImpl.java @@ -0,0 +1,198 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rm.rest.api.impl; + +import java.security.InvalidParameterException; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.repo.node.integrity.IntegrityException; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rm.rest.api.RMNodes; +import org.alfresco.rm.rest.api.Records; +import org.alfresco.rm.rest.api.model.TargetContainer; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.model.FileExistsException; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileNotFoundException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.dao.ConcurrencyFailureException; +import org.springframework.extensions.surf.util.ParameterCheck; + +public class RecordsImpl implements Records, InitializingBean +{ + protected RecordService recordService; + protected FilePlanService filePlanService; + protected NodeService nodeService; + protected FileFolderService fileFolderService; + protected DictionaryService dictionaryService; + protected RMNodes nodes; + + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + public void setNodes(RMNodes nodes) + { + this.nodes = nodes; + } + + @Override + public Node declareFileAsRecord(String fileId, Parameters parameters) + { + // Parameter check + if ((fileId == null) || (fileId.isEmpty())) + { + throw new InvalidArgumentException("Missing fileId"); + } + + // Get file to be declared + NodeRef fileNodeRef = nodes.validateNode(fileId) ; + + // Get fileplan + NodeRef filePlan = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public NodeRef doWork() + { + return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); + } + }); + + // default false (if not provided) + boolean hideRecord = Boolean.valueOf(parameters.getParameter(PARAM_HIDE_RECORD)); + + // Create the record + recordService.createRecord(filePlan, fileNodeRef, !hideRecord); + + // Get information about the new record + return nodes.getFolderOrDocument(fileId, parameters); + } + + @Override + public Node fileOrLinkRecord(String recordId, TargetContainer target, Parameters parameters) + { + ParameterCheck.mandatoryString("recordId", recordId); + + if((target.getTargetParentId() == null || target.getTargetParentId().isEmpty()) && + (target.getRelativePath() == null || target.getRelativePath().isEmpty())) + { + throw new InvalidParameterException("No target folder information was provided"); + } + + // Get record + NodeRef record = nodes.validateNode(recordId); + + // Get record folder to file/link the record to + String parentContainerId = target.getTargetParentId(); + if(parentContainerId == null || parentContainerId.isEmpty()) + { + // If target container not provided get fileplan + parentContainerId = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public String doWork() + { + return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID).getId(); + } + }); + } + NodeRef parentRecordFolder = nodes.getOrCreatePath(parentContainerId, target.getRelativePath(), ContentModel.TYPE_CONTENT); + + // Check if the target is a record folder + if(!dictionaryService.isSubClass(nodeService.getType(parentRecordFolder), RecordsManagementModel.TYPE_RECORD_FOLDER)) + { + throw new InvalidArgumentException("The provided target parent is not a record folder"); + } + + // Get the current parent type to decide if we link or move the record + NodeRef primaryParent = nodeService.getPrimaryParent(record).getParentRef(); + if(dictionaryService.isSubClass(nodeService.getType(primaryParent), RecordsManagementModel.TYPE_RECORD_FOLDER)) + { + recordService.link(record, parentRecordFolder); + } + else + { + try + { + fileFolderService.moveFrom(record, primaryParent, parentRecordFolder, null); + } + catch (FileExistsException e) + { + throw new IntegrityException(e.getMessage(), null); + } + catch (FileNotFoundException e) + { + throw new ConcurrencyFailureException("The record was deleted while filing it", e); + } + } + + // Get the record info + return nodes.getFolderOrDocument(recordId, parameters); + } + + @Override + public void afterPropertiesSet() throws Exception + { + ParameterCheck.mandatory("recordService", recordService); + ParameterCheck.mandatory("filePlanService", filePlanService); + ParameterCheck.mandatory("nodes", nodes); + ParameterCheck.mandatory("nodeService", nodeService); + ParameterCheck.mandatory("fileFolderService", fileFolderService); + ParameterCheck.mandatory("dictionaryService", dictionaryService); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/TargetContainer.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/TargetContainer.java new file mode 100644 index 0000000000..4607aab5d6 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/TargetContainer.java @@ -0,0 +1,74 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rm.rest.api.model; + +/** + * A target container object + * + * @author Ana Bozianu + * @since 2.6 + */ +public class TargetContainer +{ + String targetParentId; + String relativePath; + + public TargetContainer() + { + } + + public String getTargetParentId() + { + return targetParentId; + } + + public void setTargetParentId(String targetParentId) + { + this.targetParentId = targetParentId; + } + + public String getRelativePath() + { + return relativePath; + } + + public void setRelativePath(String relativePath) + { + this.relativePath = relativePath; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder("NodeTarget{"); + sb.append("targetParentId=").append(targetParentId); + sb.append(", relativePath='").append(relativePath).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/RecordsEntityResource.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/RecordsEntityResource.java similarity index 71% rename from rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/RecordsEntityResource.java rename to rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/RecordsEntityResource.java index 215a43f49a..85e216de59 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/RecordsEntityResource.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/RecordsEntityResource.java @@ -25,20 +25,21 @@ * #L% */ -package org.alfresco.rm.rest.api.nodes; - -import java.io.InputStream; +package org.alfresco.rm.rest.api.records; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.framework.BinaryProperties; +import org.alfresco.rest.framework.Operation; import org.alfresco.rest.framework.WebApiDescription; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.resource.EntityResource; import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction; -import org.alfresco.rest.framework.resource.content.BasicContentInfo; import org.alfresco.rest.framework.resource.content.BinaryResource; import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.webscripts.WithResponse; import org.alfresco.rm.rest.api.RMNodes; +import org.alfresco.rm.rest.api.Records; +import org.alfresco.rm.rest.api.model.TargetContainer; import org.alfresco.util.ParameterCheck; import org.springframework.beans.factory.InitializingBean; @@ -49,22 +50,21 @@ import org.springframework.beans.factory.InitializingBean; * @since 2.6 */ @EntityResource(name="records", title = "Records") -public class RecordsEntityResource implements BinaryResourceAction.Update, - BinaryResourceAction.Read, +public class RecordsEntityResource implements BinaryResourceAction.Read, InitializingBean { private RMNodes nodes; + private Records records; public void setNodes(RMNodes nodes) { this.nodes = nodes; } - @Override - public void afterPropertiesSet() throws Exception + public void setRecords(Records records) { - ParameterCheck.mandatory("nodes", this.nodes); + this.records = records; } /** @@ -83,24 +83,22 @@ public class RecordsEntityResource implements BinaryResourceAction.Update, return nodes.getContent(recordId, parameters, true); } - /** - * Upload new version of content - * - * This allow binary content update of an existing record. - * - * Note: alternatively, can upload via POST (multipart/form-data) with existing file name and form "overwrite=true". - * - * @param recordId the id of the record to set the content for - * @param contentInfo Basic information about the content stream - * @param stream an inputstream representing the new content of the node - * @param parameters {@link Parameters} - * @return information about the record that has been updated - */ - @Override - @WebApiDescription(title = "Upload content", description = "Upload content") - @BinaryProperties({"content"}) - public Node updateProperty(String recordId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters) + @Operation("file") + @WebApiDescription(title = "File record", description="File a record into fileplan.") + public Node fileRecord(String recordId, TargetContainer target, Parameters parameters, WithResponse withResponse) { - return nodes.updateContent(recordId, contentInfo, stream, parameters); + try{ + return records.fileOrLinkRecord(recordId, target, parameters); + }catch(Exception ex) + { + throw ex; + } + } + + @Override + public void afterPropertiesSet() throws Exception + { + ParameterCheck.mandatory("nodes", this.nodes); + ParameterCheck.mandatory("records", this.records); } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/package-info.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/package-info.java new file mode 100644 index 0000000000..0eaaf894a5 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/records/package-info.java @@ -0,0 +1,37 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +/** + * Package info that defines the Information Governance Records REST API + * + * @author Ana Bozianu + * @since 2.6 + */ +@WebApi(name="ig", scope=Api.SCOPE.PUBLIC, version=1) +package org.alfresco.rm.rest.api.records; +import org.alfresco.rest.framework.Api; +import org.alfresco.rest.framework.WebApi; \ No newline at end of file diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelationUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelationUnitTest.java similarity index 98% rename from rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelationUnitTest.java rename to rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelationUnitTest.java index 7e9c9d75e2..d4d48ad1c9 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentChildrenRelationUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentChildrenRelationUnitTest.java @@ -25,7 +25,7 @@ * #L% */ -package org.alfresco.rm.rest.api.nodes; +package org.alfresco.rm.rest.api.fileplancomponents; import static org.mockito.Mockito.mock; diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResourceUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResourceUnitTest.java similarity index 98% rename from rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResourceUnitTest.java rename to rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResourceUnitTest.java index 2a36bf6f1a..e2eed2a6f9 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/nodes/FileplanComponentsEntityResourceUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/fileplancomponents/FileplanComponentsEntityResourceUnitTest.java @@ -25,7 +25,7 @@ * #L% */ -package org.alfresco.rm.rest.api.nodes; +package org.alfresco.rm.rest.api.fileplancomponents; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/impl/RMNodesImplRelativePathUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/impl/RMNodesImplRelativePathUnitTest.java index cf25349247..bde808f728 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/impl/RMNodesImplRelativePathUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/rm/rest/api/impl/RMNodesImplRelativePathUnitTest.java @@ -90,8 +90,7 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest * When trying to create a node in the parent node with no relative path */ Node nodeInfo = mock(Node.class); - when(nodeInfo.getRelativePath()).thenReturn(null); - NodeRef returnedPath = rmNodesImpl.getOrCreatePath(parentNode.getId(), nodeInfo); + NodeRef returnedPath = rmNodesImpl.getOrCreatePath(parentNode.getId(), null, ContentModel.TYPE_CONTENT); /* * Then the parent node is returned and no node is created @@ -126,8 +125,7 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest * When trying to create a node in the parent node with the relative path c1/f1 */ Node nodeInfo = mock(Node.class); - when(nodeInfo.getRelativePath()).thenReturn(category + "/" + recordFolder); - NodeRef returnedPath = rmNodesImpl.getOrCreatePath(parentNode.getId(), nodeInfo); + NodeRef returnedPath = rmNodesImpl.getOrCreatePath(parentNode.getId(), category + "/" + recordFolder, ContentModel.TYPE_CONTENT); /* * Then the node f1 is returned and no node is created @@ -166,9 +164,6 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest /* * When trying to create a content node in the relative path c1/c2/c3/f1 */ - Node nodeInfo = mock(Node.class); - when(nodeInfo.getNodeType()).thenReturn("cm:content"); - // c3 String category3 = "c3"; NodeRef categoryNode3 = AlfMock.generateNodeRef(mockedNodeService); @@ -182,8 +177,7 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest when(mockedFileFolderService.create(categoryNode3, recordFolder, RecordsManagementModel.TYPE_RECORD_FOLDER)).thenReturn(recordFolderFileInfo); // call the class under tests - when(nodeInfo.getRelativePath()).thenReturn(category1 + "/" + category2 + "/" + category3 + "/" + recordFolder); - NodeRef returnedPath = rmNodesImpl.getOrCreatePath(fileplanNodeRef.getId(), nodeInfo); + NodeRef returnedPath = rmNodesImpl.getOrCreatePath(fileplanNodeRef.getId(), category1 + "/" + category2 + "/" + category3 + "/" + recordFolder, ContentModel.TYPE_CONTENT); /* * Then the category c1 and the record folder f1 should be created and f1 should be returned @@ -232,9 +226,7 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest when(mockedFileFolderService.create(folderNode2, folder3, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER)).thenReturn(folderFileInfo3); // call the class under tests - Node nodeInfo = mock(Node.class); - when(nodeInfo.getRelativePath()).thenReturn(folder1 + "/" + folder2 + "/" + folder3); - NodeRef returnedParentNode = rmNodesImpl.getOrCreatePath(unfiledRecordContainer.getId(), nodeInfo); + NodeRef returnedParentNode = rmNodesImpl.getOrCreatePath(unfiledRecordContainer.getId(), folder1 + "/" + folder2 + "/" + folder3, ContentModel.TYPE_CONTENT); /* * Then the category c1 and the record folder rf1 should be created @@ -267,9 +259,6 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest /* * When trying to create a folder node in the relative path c1/c2/c3 */ - Node nodeInfo = mock(Node.class); - when(nodeInfo.getNodeType()).thenReturn("rma:recordFolder"); - // c1 String category1 = "c1"; NodeRef categoryNode1 = AlfMock.generateNodeRef(mockedNodeService); @@ -286,8 +275,7 @@ public class RMNodesImplRelativePathUnitTest extends BaseUnitTest when(mockedFilePlanService.createRecordCategory(categoryNode2, category3)).thenReturn(categoryNode3); // call the class under tests - when(nodeInfo.getRelativePath()).thenReturn(category1 + "/" + category2 + "/" + category3); - NodeRef returnedParentNode = rmNodesImpl.getOrCreatePath(fileplanNodeRef.getId(), nodeInfo); + NodeRef returnedParentNode = rmNodesImpl.getOrCreatePath(fileplanNodeRef.getId(), category1 + "/" + category2 + "/" + category3, RecordsManagementModel.TYPE_RECORD_FOLDER); /* * Then the categories c1, c2 and c3 should be created and c3 should be returned diff --git a/rm-community/rm-community-rest-api-explorer/pom.xml b/rm-community/rm-community-rest-api-explorer/pom.xml index 84e073c0db..6db1f474dc 100644 --- a/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/rm-community/rm-community-rest-api-explorer/pom.xml @@ -11,8 +11,7 @@ - 2.0-SNAPSHOT - 2.1.4 + 1.4 1.7 1.7 UTF-8 @@ -30,6 +29,9 @@ org.alfresco api-explorer + + definitions/* + diff --git a/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml b/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml index ade891e07b..e1275d29fb 100644 --- a/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml +++ b/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml @@ -21,6 +21,8 @@ tags: description: Retrieve and manage the RM site - name: records description: Perform record specific operations + - name: files + description: Perform operations on non-record files paths: '/fileplan-components/{fileplanComponentId}': get: @@ -377,7 +379,10 @@ paths: - $ref: '#/parameters/fieldsParam' - in: body name: nodeBodyCreate - description: The node information to create. + description: | + The node information to create. + + This field is ignored for multipart/form-data content uploads. required: true schema: $ref: '#/definitions/RMNodeBodyCreate' @@ -564,7 +569,6 @@ paths: $ref: '#/definitions/Error' '/records/{recordId}/content': get: - x-alfresco-since: "5.2" tags: - records summary: Get record content @@ -583,75 +587,48 @@ paths: description: Content has not been modified since the date provided in the If-Modified-Since header '400': description: | - Invalid parameter: **nodeId** is not a valid format, or is not a file + Invalid parameter: **recordId** is not a valid format, or is not a record '401': - description: Authentication failed + description: Authentication failed '404': description: | - **nodeId** does not exist + **recordId** does not exist default: description: Unexpected error schema: $ref: '#/definitions/Error' - put: - x-alfresco-since: "5.2" - tags: + '/records/{recordId}/file': + post: + tags: - records - summary: Update record content + summary: File a record description: | - Updates the content of the record with identifier **recordId**. + Files the record **recordId** in the target record folder. - The request body for this endpoint can be any text or binary stream. + You can specify the target record folder by providing its id **targetParentId** + or by providing the id of a parent container **targetParentId** and a relative path **relativePath**. - The **majorVersion** and **comment** parameters can be used to control versioning behaviour. If the content is versionable, - a new minor version is created by default. + The **relativePath** specifies the container structure relative to the node **targetParentId**. + If targetParentId is missing the path will be relative to the fileplan. + The relativePath is made of record containers and a record folder as the last element. + Containers that are missing from relativePath will be created before filing. - Optionally a new **name** parameter can also be specified that must be unique within the parent folder. If specified and valid then this - will rename the node. If invalid then an error is returned and the content is not updated. - - **Note:** This API method accepts any content type, but for testing with this tool text based content can be provided. - This is because the OpenAPI Specification does not allow a wildcard to be provided or the ability for - tooling to accept an arbitrary file. - operationId: updateRecordContent - parameters: + If the record is already filed, a link to the target record folder is created. + operationId: fileRecord + parameters: - $ref: '#/parameters/recordIdParam' - - name: majorVersion - in: query - description: | - If **true**, create a major version. - Setting this parameter also enables versioning of this node, if it is not already versioned. - required: false - type: boolean - default: false - - name: comment - in: query - description: | - Add a version comment which will appear in version history. - Setting this parameter also enables versioning of this node, if it is not already versioned. - required: false - type: string - - name: name - in: query - description: | - Optional new name. This should include the file extension. - The name must not contain spaces or the following special characters: * " < > \ / ? : and |. - The character `.` must not be used at the end of the name. - required: false - type: string - pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))" - $ref: '#/parameters/IGNodeEntryIncludeParam' - $ref: '#/parameters/fieldsParam' - in: body - name: contentBodyUpdate - description: The binary content + name: nodeBodyFile + description: The target record folder id required: true schema: - type: string - format: binary + $ref: '#/definitions/RequestBodyFile' + consumes: + - application/json produces: - application/json - consumes: - - application/octet-stream responses: '200': description: Successful response @@ -659,22 +636,64 @@ paths: $ref: '#/definitions/IGNodeEntry' '400': description: | - Invalid parameter: **recordId** is not a valid format, or is not a file + Invalid parameter: **recordIdParam** or **targetParentId** is not a valid format, + **recordIdParam** is not a record, **targetParentId** is not a record container or **nodeBodyFile** is invalid '401': - description: Authentication failed + description: Authentication failed '403': - description: Current user does not have permission to update **recordId** + description: Current user does not have permission to create children of **nodeId** '404': description: | - **recordId** does not exist - '409': - description: Optional new name clashes with an existing node in the current parent folder - '413': - description: Content exceeds individual file size limit (configured for network/system) + **recordIdParam** or **targetParentId** does not exist '422': - description: Model integrity exception including a file name containing invalid characters - '507': - description: Content exceeds overall storage quota limit configured for the network/system + description: | + Model integrity exception: the action breaks system's integrity restrictions + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + '/files/{fileId}/declare': + post: + tags: + - files + summary: Declare as record + description: Declares the file **fileId** in the unfiled record container. + operationId: declareRecord + parameters: + - name: fileId + in: path + description: The identifier of a non-record file. + required: true + type: string + - name: hideRecord + in: query + description: Flag to indicate whether the record should be hiden from the curent parent folder. + type: boolean + default: false + - $ref: '#/parameters/IGNodeEntryIncludeParam' + - $ref: '#/parameters/fieldsParam' + consumes: + - application/json + produces: + - application/json + responses: + '200': + description: Successful response + schema: + $ref: '#/definitions/IGNodeEntry' + '400': + description: | + Invalid parameter: **fileId** is not a valid format + '401': + description: Authentication failed + '403': + description: Current user does not have permission to declare a record + '404': + description: | + **fileId** does not exist + '422': + description: | + Model integrity exception: the action breaks system's integrity restrictions default: description: Unexpected error schema: @@ -958,6 +977,13 @@ definitions: type: object additionalProperties: type: string + RequestBodyFile: + type: object + properties: + targetParentId: + type: string + relativePath: + type: string ## Core definition ChildAssociationInfo: type: object diff --git a/rm-community/rm-community-rest-api-explorer/src/main/webapp/index.html b/rm-community/rm-community-rest-api-explorer/src/main/webapp/index.html index b08cfe78ef..f20f567268 100644 --- a/rm-community/rm-community-rest-api-explorer/src/main/webapp/index.html +++ b/rm-community/rm-community-rest-api-explorer/src/main/webapp/index.html @@ -32,7 +32,7 @@