diff --git a/rm-automation/rm-automation-community-rest-api/pom.xml b/rm-automation/rm-automation-community-rest-api/pom.xml index 583d5b15e7..4662386d6c 100644 --- a/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/rm-automation/rm-automation-community-rest-api/pom.xml @@ -85,5 +85,10 @@ commons-collections4 4.1 + + com.github.docker-java + docker-java + 3.0.14 + diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RMRestProperties.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RMRestProperties.java index 1d6e11f909..99991254a6 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RMRestProperties.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RMRestProperties.java @@ -56,4 +56,7 @@ public class RMRestProperties extends RestProperties @Value ("${rest.rmPath}") private String restRmPath; + + @Value ("${docker.host}") + private String dockerHost; } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/service/ActionsService.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/service/ActionsService.java new file mode 100644 index 0000000000..03a54d5c24 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/service/ActionsService.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2019 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.core.service; + +import com.google.common.collect.ImmutableMap; + +import org.alfresco.rest.core.RMRestWrapper; +import org.alfresco.rest.core.RestAPIFactory; +import org.alfresco.rest.rm.community.model.rules.ActionsOnRule; +import org.alfresco.utility.model.RepoTestModel; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +/** + * Produces processed results from Core Actions API calls + * + * @author Claudia Agache + * @since 3.1 + */ +@Service +public class ActionsService +{ + @Autowired + private RestAPIFactory restAPIFactory; + + /** + * Declares and files a document as record to a record folder using v1 actions api + * + * @param userModel user who executes the action + * @param targetNode the node on which the action is executed + * @param destinationPath the path to the record folder + * @throws Exception + */ + public void declareAndFile(UserModel userModel, RepoTestModel targetNode, String destinationPath) throws Exception + { + RMRestWrapper rmRestWrapper = restAPIFactory.getRmRestWrapper(); + rmRestWrapper.getRestWrapper() + .authenticateUser(userModel).withCoreAPI().usingActions() + .executeAction(ActionsOnRule.DECLARE_AS_RECORD.getActionValue(), targetNode, + ImmutableMap.of("path", destinationPath)); + rmRestWrapper.assertStatusCodeIs(HttpStatus.ACCEPTED); + } + + /** + * Declares a document as record using v1 actions api + * + * @param userModel user who executes the action + * @param targetNode the node on which the action is executed + * @throws Exception + */ + public void declareAsRecord(UserModel userModel, RepoTestModel targetNode) throws Exception + { + RMRestWrapper rmRestWrapper = restAPIFactory.getRmRestWrapper(); + rmRestWrapper.getRestWrapper() + .authenticateUser(userModel).withCoreAPI().usingActions() + .executeAction(ActionsOnRule.DECLARE_AS_RECORD.getActionValue(), targetNode); + rmRestWrapper.assertStatusCodeIs(HttpStatus.ACCEPTED); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMModelRequest.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMModelRequest.java index c9eefdfa0d..b2510f80f7 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMModelRequest.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMModelRequest.java @@ -48,7 +48,7 @@ public abstract class RMModelRequest extends ModelRequest private RMRestWrapper rmRestWrapper; /** - * @param restWrapper + * @param rmRestWrapper */ public RMModelRequest(RMRestWrapper rmRestWrapper) { diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java index 23f6655166..febd2b5427 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java @@ -113,7 +113,7 @@ public class GSCoreAPI extends RMModelRequest /** * Provides DSL on all REST calls under records/... API path * - * @return {@link FilePlanComponentAPI} + * @return {@link RecordsAPI} */ public RecordsAPI usingRecords() { diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/DockerHelper.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/DockerHelper.java new file mode 100644 index 0000000000..c5f3be62a2 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/DockerHelper.java @@ -0,0 +1,136 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2019 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.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Frame; +import com.github.dockerjava.core.DockerClientBuilder; +import com.github.dockerjava.core.command.LogContainerResultCallback; + +import org.apache.commons.lang.SystemUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * Helper class for interaction with docker containers + * + * @author Claudia Agache + * @since 3.1 + */ +@Service +public class DockerHelper +{ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private static final String REPO_IMAGE_NAME = "repository"; + private DockerClient dockerClient; + + public DockerHelper(@Value ("${docker.host}") String dockerHost) + { + if (SystemUtils.IS_OS_WINDOWS) + { + this.dockerClient = DockerClientBuilder.getInstance(dockerHost).build(); + } + else + { + this.dockerClient = DockerClientBuilder.getInstance().build(); + } + } + + /** + * Method for returning logs of docker container + * + * @param containerId - ID of the container + * @return list of strings, where every string is log line + */ + private List getDockerLogs(String containerId) + { + final List logs = new ArrayList<>(); + // get the logs since current time - 10 seconds + int timeStamp = (int) (System.currentTimeMillis() / 1000) - 10; + + LogContainerCmd logContainerCmd = dockerClient.logContainerCmd(containerId); + logContainerCmd.withStdOut(true) + .withStdErr(true) + .withSince(timeStamp) // UNIX timestamp to filter logs. Output log-entries since that timestamp. + .withTimestamps(true); //print timestamps for every log line + + try + { + logContainerCmd.exec(new LogContainerResultCallback() + { + @Override + public void onNext(Frame item) + { + logs.add(item.toString()); + } + }).awaitCompletion(); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); // set interrupt flag + logger.error("Failed to retrieve logs of container " + containerId, e); + } + + return logs; + } + + /** + * Get the alfresco container logs + * + * @return list of strings, where every string is log line + */ + public List getAlfrescoLogs() + { + Optional alfrescoContainer = findContainerByImageName(REPO_IMAGE_NAME); + return (alfrescoContainer.isPresent()) ? getDockerLogs(alfrescoContainer.get().getId()) : Collections.emptyList(); + } + + /** + * Method for finding a docker container after the image name + * + * @param imageName - the name of the image used by container + * @return the container + */ + private Optional findContainerByImageName(String imageName) + { + List containers = dockerClient.listContainersCmd().withShowAll(true).exec(); + + return containers.stream() + .filter(container -> container.getImage().contains(imageName)) + .findFirst(); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/resources/config.properties b/rm-automation/rm-automation-community-rest-api/src/main/resources/config.properties index f66389d1f5..5d54d6c02d 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/resources/config.properties +++ b/rm-automation/rm-automation-community-rest-api/src/main/resources/config.properties @@ -1,3 +1,6 @@ alfresco.server=localhost alfresco.port=8080 -rest.rmPath=alfresco/api/-default-/public/gs/versions/1 \ No newline at end of file +rest.rmPath=alfresco/api/-default-/public/gs/versions/1 + +# Docker properties values +docker.host=tcp://127.0.0.1:2375 \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/files/DeclareDocumentAsRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/files/DeclareDocumentAsRecordTests.java index 077703bca5..5e08e5fd7f 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/files/DeclareDocumentAsRecordTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/files/DeclareDocumentAsRecordTests.java @@ -100,10 +100,16 @@ public class DeclareDocumentAsRecordTests extends BaseRMRestTest * And it is now a record * And it remains a secondary child of the starting location where I can still view it *
+     *
+     * RM-6779
+     * Given I declare a record using the v1 API
+     * When I do not provide a location parameter
+     * Then the record is declared in the unfiled folder
+     *
      * @throws Exception for malformed JSON API response
      */
     @Test(description = "User with correct permissions can declare document as a record")
-    @AlfrescoTest(jira = "RM-4429")
+    @AlfrescoTest(jira = "RM-4429, RM-6779")
     public void userWithPrivilegesCanDeclareDocumentAsRecord() throws Exception
     {
         // create document in a folder in a collaboration site
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/FileRecordsTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/FileRecordsTests.java
index 2a90dcb5bd..98a7963406 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/FileRecordsTests.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/FileRecordsTests.java
@@ -68,7 +68,7 @@ public class FileRecordsTests extends BaseRMRestTest
 {
     private UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder()
                                                                   .name(ELECTRONIC_RECORD_NAME)
-                                                                  .nodeType(CONTENT_TYPE.toString())
+                                                                  .nodeType(CONTENT_TYPE)
                                                                   .content(RecordContent.builder().mimeType("text/plain").build())
                                                                   .build();
 
@@ -78,14 +78,14 @@ public class FileRecordsTests extends BaseRMRestTest
                                                                                                             .title("Title")
                                                                                                             .build())
                                                                      .name(NONELECTRONIC_RECORD_NAME)
-                                                                     .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
+                                                                     .nodeType(NON_ELECTRONIC_RECORD_TYPE)
                                                                      .build();
 
     /**
      * Invalid  containers where electronic and non-electronic records can be filed
      */
     @DataProvider (name = "invalidContainersToFile")
-    public String[][] getFolderContainers() throws Exception
+    public Object[][] getFolderContainers() throws Exception
     {
         return new String[][] {
             { FILE_PLAN_ALIAS},