From c13cbfaed08262525e6d7c06be0d7cb5d62945c6 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Fri, 25 Nov 2016 17:36:29 +0200 Subject: [PATCH] RM-4359 - added records endpoint with get/update content requests --- .../rm-public-rest-context.xml | 4 + .../rest/api/nodes/RecordsEntityResource.java | 105 ++++++++++++ .../main/webapp/definitions/ig-core-api.yaml | 153 +++++++++++++++++- 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/RecordsEntityResource.java 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 07f5823e4f..f4e068dc03 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 @@ -49,6 +49,10 @@ + + + + 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/nodes/RecordsEntityResource.java new file mode 100644 index 0000000000..3887a0c15e --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/nodes/RecordsEntityResource.java @@ -0,0 +1,105 @@ +/* + * #%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.nodes; + +import java.io.InputStream; + +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.framework.BinaryProperties; +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.rm.rest.api.RMNodes; +import org.springframework.beans.factory.InitializingBean; + +/** + * An implementation of an Entity Resource for a record + * + * @author Ana Bozianu + * @since 2.6 + */ +@EntityResource(name="records", title = "Records") +public class RecordsEntityResource implements BinaryResourceAction.Update, + BinaryResourceAction.Read, + InitializingBean +{ + + private RMNodes nodes; + + public void setNodes(RMNodes nodes) + { + this.nodes = nodes; + } + + @Override + public void afterPropertiesSet() throws Exception + { + + } + + /** + * Download content + * + * @param entityId + * @param parameters {@link Parameters} + * @return + * @throws EntityNotFoundException + */ + @Override + @WebApiDescription(title = "Download content", description = "Download content") + @BinaryProperties({"content"}) + public BinaryResource readProperty(String entityId, Parameters parameters) throws EntityNotFoundException + { + return nodes.getContent(entityId, 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 entityId + * @param contentInfo Basic information about the content stream + * @param stream An inputstream + * @param parameters + * @return + */ + @Override + @WebApiDescription(title = "Upload content", description = "Upload content") + @BinaryProperties({"content"}) + public Node updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters) + { + return nodes.updateContent(entityId, contentInfo, stream, parameters); + } +} 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 447f030e15..a99942b387 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 @@ -19,6 +19,8 @@ tags: description: Retrieve and manage fileplan components - name: ig-sites description: Retrieve and manage the RM site + - name: records + description: Perform record specific operations paths: '/fileplan-components/{fileplanComponentId}': get: @@ -547,6 +549,123 @@ paths: description: Unexpected error schema: $ref: '#/definitions/Error' + '/records/{recordId}/content': + get: + x-alfresco-since: "5.2" + tags: + - records + summary: Get record content + description: | + + Gets the content of the record with identifier **recordId**. + operationId: getRecordContent + parameters: + - $ref: '#/parameters/recordIdParam' + - $ref: '#/parameters/attachmentParam' + - $ref: '#/parameters/ifModifiedSinceHeader' + responses: + '200': + description: Successful response + '304': + 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 + '401': + description: Authentication failed + '404': + description: | + **nodeId** does not exist + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + put: + x-alfresco-since: "5.2" + tags: + - records + summary: Update record content + description: | + Updates the content of the record with identifier **recordId**. + + The request body for this endpoint can be any text or binary stream. + + 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. + + 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: + - $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 + required: true + schema: + type: string + format: binary + produces: + - application/json + consumes: + - application/octet-stream + responses: + '200': + description: Successful response + schema: + $ref: '#/definitions/IGNodeEntry' + '400': + description: | + Invalid parameter: **recordId** is not a valid format, or is not a file + '401': + description: Authentication failed + '403': + description: Current user does not have permission to update **recordId** + '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) + '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 + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' parameters: fileplanComponentIdWithAliasParam: name: fileplanComponentId @@ -609,13 +728,18 @@ parameters: items: type: string collectionFormat: csv - ## Core definition fileplanComponentIdParam: name: fileplanComponentId in: path description: The identifier of a fileplan compoment. required: true type: string + recordIdParam: + name: recordId + in: path + description: The identifier of a record. + required: true + type: string ## Core definition fieldsParam: name: fields @@ -670,6 +794,33 @@ parameters: items: type: string collectionFormat: csv + # Core definition + attachmentParam: + name: attachment + in: query + description: | + **true** enables a web browser to download the file as an attachment. + **false** means a web browser may preview the file in a new tab or window, but not + download the file. + + You can only set this parameter to **false** if the content type of the file is in the supported list; + for example, certain image files and PDF files. + + If the content type is not supported for preview, then a value of **false** is ignored, and + the attachment will be returned in the response. + required: false + default: true + type: boolean + # Core definition + ifModifiedSinceHeader: + name: If-Modified-Since + in: header + description: | + Only returns the content if it has been modified since the date provided. + Use the date format defined by HTTP. For example, `Wed, 09 Mar 2016 16:56:34 GMT`. + required: false + type: string + format: date-time definitions: IGNodeEntry: type: object