Merge branch 'develop' into stable
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -97,6 +97,12 @@
|
||||
<version>4.5.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.16.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@@ -0,0 +1,99 @@
|
||||
package com.inteligr8.alfresco.acs.api;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.inteligr8.alfresco.acs.model.NodeBodyCreate;
|
||||
|
||||
public class NodeBodyCreateMultipart extends MultipartBody {
|
||||
|
||||
private static final ObjectMapper om = new ObjectMapper();
|
||||
|
||||
public static NodeBodyCreateMultipart from(
|
||||
NodeBodyCreate nodeBody, String filename, InputStream istream,
|
||||
Boolean autoRename, Boolean majorVersion, Boolean versioningEnabled) throws IOException {
|
||||
List<Attachment> atts = new LinkedList<>();
|
||||
atts.addAll(toAttachments(nodeBody));
|
||||
if (autoRename != null)
|
||||
atts.add(toAttachment("autoRename", String.valueOf(autoRename)));
|
||||
if (majorVersion != null)
|
||||
atts.add(toAttachment("majorVersion", String.valueOf(majorVersion)));
|
||||
if (versioningEnabled != null)
|
||||
atts.add(toAttachment("versioningEnabled", String.valueOf(versioningEnabled)));
|
||||
atts.add(toAttachment(filename, istream));
|
||||
return new NodeBodyCreateMultipart(atts, true);
|
||||
}
|
||||
|
||||
public NodeBodyCreateMultipart(List<Attachment> atts) throws IOException {
|
||||
super(atts);
|
||||
}
|
||||
|
||||
public NodeBodyCreateMultipart(List<Attachment> atts, boolean outbound) throws IOException {
|
||||
super(atts, outbound);
|
||||
}
|
||||
|
||||
public NodeBodyCreate getBody() throws IOException {
|
||||
if (!MediaType.APPLICATION_JSON_TYPE.equals(this.getRootAttachment().getContentType()))
|
||||
throw new IllegalStateException();
|
||||
|
||||
InputStream istream = this.getRootAttachment().getDataHandler().getInputStream();
|
||||
try {
|
||||
return om.readValue(istream, NodeBodyCreate.class);
|
||||
} finally {
|
||||
istream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Attachment getFiledataAttachment() {
|
||||
return this.getAttachment("filedata");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<Attachment> toAttachments(NodeBodyCreate nodeBody) throws IOException {
|
||||
List<Attachment> atts = new LinkedList<>();
|
||||
atts.add(toAttachment("name", nodeBody.getName()));
|
||||
atts.add(toAttachment("nodeType", nodeBody.getNodeType()));
|
||||
if (nodeBody.getAspectNames() != null)
|
||||
atts.add(toAttachment("aspectNames", nodeBody.getAspectNames()));
|
||||
if (nodeBody.getProperties() != null)
|
||||
atts.add(toAttachment("properties", (Map<String, Object>)nodeBody.getProperties()));
|
||||
return atts;
|
||||
}
|
||||
|
||||
private static Attachment toAttachment(String name, String value) {
|
||||
return new Attachment(name, new ByteArrayInputStream(value.getBytes()), new ContentDisposition("form-data; name=\"" + name + "\""));
|
||||
}
|
||||
|
||||
private static Attachment toAttachment(String name, Collection<String> c) throws JsonProcessingException {
|
||||
return toJsonAttachment(name, c);
|
||||
}
|
||||
|
||||
private static Attachment toAttachment(String name, Map<String, Object> map) throws JsonProcessingException {
|
||||
return toJsonAttachment(name, map);
|
||||
}
|
||||
|
||||
private static Attachment toJsonAttachment(String name, Object obj) throws JsonProcessingException {
|
||||
String json = om.writeValueAsString(obj);
|
||||
return new Attachment(name, new ByteArrayInputStream(json.getBytes()), new ContentDisposition("form-data; name=\"" + name + "\""));
|
||||
}
|
||||
|
||||
private static Attachment toAttachment(String filename, InputStream istream) {
|
||||
return new Attachment("filedata", istream, new ContentDisposition("form-data; name=\"filedata\"; filename=\"" + filename + "\""));
|
||||
}
|
||||
|
||||
}
|
@@ -1,20 +1,15 @@
|
||||
package com.inteligr8.alfresco.acs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
|
||||
|
||||
import com.inteligr8.alfresco.acs.model.Error;
|
||||
import com.inteligr8.alfresco.acs.model.NodeBodyCreate;
|
||||
import com.inteligr8.alfresco.acs.model.NodeEntry;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -31,7 +26,7 @@ public interface NodesCxfApi {
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@ApiOperation(value = "Create a node", tags={ })
|
||||
@ApiResponses(value = {
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 201, message = "Successful response", response = NodeEntry.class),
|
||||
@ApiResponse(code = 400, message = "Invalid parameter: **nodeId** is not a valid format or **nodeBodyCreate** is invalid "),
|
||||
@ApiResponse(code = 401, message = "Authentication failed"),
|
||||
@@ -45,12 +40,35 @@ public interface NodesCxfApi {
|
||||
@ApiResponse(code = 200, message = "Unexpected error", response = Error.class) })
|
||||
public NodeEntry createNode(
|
||||
@PathParam("nodeId") String nodeId,
|
||||
@Multipart NodeBodyCreate nodeBodyCreate,
|
||||
@QueryParam("autoRename") Boolean autoRename,
|
||||
@QueryParam("majorVersion") Boolean majorVersion,
|
||||
@QueryParam("versioningEnabled") Boolean versioningEnabled,
|
||||
@QueryParam("include") List<String> include,
|
||||
@QueryParam("fields") List<String> fields,
|
||||
@Multipart(value = "filedata", required = false) Attachment attachment);
|
||||
|
||||
MultipartBody body);
|
||||
/*
|
||||
* This better impl doesn't work
|
||||
*
|
||||
@POST
|
||||
@Path("/nodes/{nodeId}/children")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@ApiOperation(value = "Create a node", tags={ })
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 201, message = "Successful response", response = NodeEntry.class),
|
||||
@ApiResponse(code = 400, message = "Invalid parameter: **nodeId** is not a valid format or **nodeBodyCreate** is invalid "),
|
||||
@ApiResponse(code = 401, message = "Authentication failed"),
|
||||
@ApiResponse(code = 403, message = "Current user does not have permission to create children of **nodeId**"),
|
||||
@ApiResponse(code = 404, message = "**nodeId** or **renditionId** does not exist "),
|
||||
@ApiResponse(code = 409, message = "New name clashes with an existing node in the current parent folder"),
|
||||
@ApiResponse(code = 413, message = "Content exceeds individual file size limit configured for the network or system"),
|
||||
@ApiResponse(code = 415, message = "Content Type is not supported"),
|
||||
@ApiResponse(code = 422, message = "Model integrity exception including a file name containing invalid characters"),
|
||||
@ApiResponse(code = 507, message = "Content exceeds overall storage quota limit configured for the network or system"),
|
||||
@ApiResponse(code = 200, message = "Unexpected error", response = Error.class) })
|
||||
public NodeEntry createNode(
|
||||
@PathParam("nodeId") String nodeId,
|
||||
@Multipart("name") String name,
|
||||
@Multipart("nodeType") String nodeType,
|
||||
@Multipart("filedata") InputStream fileStream,
|
||||
@Multipart("filedata") ContentDisposition disposition,
|
||||
@Multipart(value = "autoRename", required = false) Boolean autoRename,
|
||||
@Multipart(value = "majorVersion", required = false) Boolean majorVersion,
|
||||
@Multipart(value = "versioningEnabled", required = false) Boolean versioningEnabled);
|
||||
*/
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||
@@ -47,11 +46,11 @@ public interface NodesJerseyApi {
|
||||
public NodeEntry createNode(
|
||||
@PathParam("nodeId") String nodeId,
|
||||
NodeBodyCreate nodeBodyCreate,
|
||||
@QueryParam("autoRename") Boolean autoRename,
|
||||
@QueryParam("majorVersion") Boolean majorVersion,
|
||||
@QueryParam("versioningEnabled") Boolean versioningEnabled,
|
||||
@QueryParam("include") List<String> include,
|
||||
@QueryParam("fields") List<String> fields,
|
||||
@FormDataParam("autoRename") Boolean autoRename,
|
||||
@FormDataParam("majorVersion") Boolean majorVersion,
|
||||
@FormDataParam("versioningEnabled") Boolean versioningEnabled,
|
||||
@FormDataParam("include") List<String> include,
|
||||
@FormDataParam("fields") List<String> fields,
|
||||
@FormDataParam("filedata") InputStream filedataStream,
|
||||
@FormDataParam("filedata") FormDataContentDisposition filedataDisposition);
|
||||
|
||||
|
@@ -1,10 +1,21 @@
|
||||
package com.inteligr8.alfresco.acs;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.inteligr8.alfresco.acs.api.NodeBodyCreateMultipart;
|
||||
import com.inteligr8.alfresco.acs.model.NodeBodyCreate;
|
||||
import com.inteligr8.alfresco.acs.model.RequestQuery;
|
||||
import com.inteligr8.alfresco.acs.model.RequestQuery.LanguageEnum;
|
||||
import com.inteligr8.alfresco.acs.model.ResultNode;
|
||||
import com.inteligr8.alfresco.acs.model.ResultSetPaging;
|
||||
import com.inteligr8.alfresco.acs.model.SearchRequest;
|
||||
import com.inteligr8.rs.ClientConfiguration;
|
||||
|
||||
@TestPropertySource(locations = {"/local.properties"})
|
||||
@@ -13,7 +24,7 @@ public class ConnectionCxfClientIT extends ConnectionClientIT {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("acs.api.cxf")
|
||||
private AcsPublicRestApi client;
|
||||
private AcsPublicRestApiCxfImpl client;
|
||||
|
||||
@Override
|
||||
public AcsPublicRestApi getClient() {
|
||||
@@ -25,4 +36,25 @@ public class ConnectionCxfClientIT extends ConnectionClientIT {
|
||||
return this.client.getConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadFile() throws IOException {
|
||||
RequestQuery query = new RequestQuery();
|
||||
query.setLanguage(LanguageEnum.AFTS);
|
||||
query.setQuery("=@cm:name:'Shared'");
|
||||
|
||||
SearchRequest searchRequest = new SearchRequest();
|
||||
searchRequest.setQuery(query);
|
||||
|
||||
ResultSetPaging paging = this.client.getSearchApi().search(searchRequest);
|
||||
ResultNode folderNode = paging.getList().getEntries().iterator().next().getEntry();
|
||||
String folderNodeId = folderNode.getId();
|
||||
|
||||
NodeBodyCreate nodeBody = new NodeBodyCreate().nodeType("cm:content").name("TestFolder");
|
||||
|
||||
ByteArrayInputStream istream = new ByteArrayInputStream("This is a test".getBytes());
|
||||
NodeBodyCreateMultipart body = NodeBodyCreateMultipart.from(nodeBody, "test.txt", istream, true, null, null);
|
||||
|
||||
this.client.getNodesExtApi().createNode(folderNodeId, body);
|
||||
}
|
||||
|
||||
}
|
||||
|
19
src/test/resources/log4j2.properties
Normal file
19
src/test/resources/log4j2.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
rootLogger.level=trace
|
||||
rootLogger.appenderRef.stdout.ref=STDOUT
|
||||
|
||||
logger.spring.name=org.springframework
|
||||
logger.spring.level=info
|
||||
|
||||
logger.common-rest-api.name=com.inteligr8.rs
|
||||
logger.common-rest-api.level=trace
|
||||
|
||||
logger.this.name=com.inteligr8.alfresco.acs
|
||||
logger.this.level=trace
|
||||
|
||||
logger.jaxrslog.name=jaxrs.request
|
||||
logger.jaxrslog.level=trace
|
||||
|
||||
appender.stdout.type=Console
|
||||
appender.stdout.name=STDOUT
|
||||
appender.stdout.layout.type=PatternLayout
|
||||
appender.stdout.layout.pattern=%C [%t] %m%n
|
53
src/test/vscode/createNode.http
Normal file
53
src/test/vscode/createNode.http
Normal file
@@ -0,0 +1,53 @@
|
||||
@baseUrl = http://localhost:8080/alfresco
|
||||
@username = admin
|
||||
@password = admin
|
||||
|
||||
### Find Folder
|
||||
# @name find
|
||||
POST {{baseUrl}}/api/-default-/public/search/versions/1/search HTTP/1.1
|
||||
Authorization: Basic {{username}}:{{password}}
|
||||
|
||||
{
|
||||
"query": {
|
||||
"language": "afts",
|
||||
"query": "=@cm:name:'Shared'"
|
||||
}
|
||||
}
|
||||
|
||||
@folderNodeId = {{find.response.body.list.entries[0].entry.id}}
|
||||
|
||||
### Upload File
|
||||
# @name upload
|
||||
POST {{baseUrl}}/api/-default-/public/alfresco/versions/1/nodes/{{folderNodeId}}/children?autoRename=true
|
||||
Authorization: Basic {{username}}:{{password}}
|
||||
Content-type: application/json
|
||||
|
||||
{
|
||||
"name": "TestFolder",
|
||||
"nodeType": "cm:content",
|
||||
"properties": null
|
||||
}
|
||||
|
||||
### Upload File
|
||||
# @name upload-form
|
||||
POST {{baseUrl}}/api/-default-/public/alfresco/versions/1/nodes/{{folderNodeId}}/children
|
||||
Authorization: Basic {{username}}:{{password}}
|
||||
Content-type: multipart/form-data; boundary=----Test
|
||||
|
||||
------Test
|
||||
Content-disposition: form-data; name="name"
|
||||
|
||||
TestFolder
|
||||
------Test
|
||||
Content-disposition: form-data; name="nodeType"
|
||||
|
||||
cm:content
|
||||
------Test
|
||||
Content-disposition: form-data; name="autoRename"
|
||||
|
||||
true
|
||||
------Test
|
||||
Content-disposition: form-data; name="filedata"; filename="test.txt"
|
||||
|
||||
This is a test
|
||||
------Test--
|
Reference in New Issue
Block a user