mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			17.23
			...
			fix/REPO-5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 02decc91d4 | 
| @@ -7,7 +7,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-community-repo-amps</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <modules> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-governance-services-community-parent</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <modules> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-governance-services-automation-community-repo</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <build> | ||||
| @@ -87,7 +87,7 @@ | ||||
|       <dependency> | ||||
|          <groupId>com.github.docker-java</groupId> | ||||
|          <artifactId>docker-java</artifactId> | ||||
|          <version>3.2.13</version> | ||||
|          <version>3.2.12</version> | ||||
|       </dependency> | ||||
|    </dependencies> | ||||
| </project> | ||||
|   | ||||
| @@ -26,6 +26,8 @@ | ||||
|  */ | ||||
| package org.alfresco.rest.v0; | ||||
|  | ||||
| import static org.testng.AssertJUnit.assertTrue; | ||||
|  | ||||
| import java.text.MessageFormat; | ||||
|  | ||||
| import org.alfresco.rest.core.v0.BaseAPI; | ||||
| @@ -36,9 +38,7 @@ import org.json.JSONObject; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.stereotype.Component; | ||||
| import static org.testng.AssertJUnit.assertTrue; | ||||
| import static org.testng.AssertJUnit.assertEquals; | ||||
| import static org.testng.AssertJUnit.assertNotNull; | ||||
|  | ||||
| /** | ||||
|  * Methods to make API requests using v0 API on Records Management Custom Model Reference Definitions | ||||
|  * | ||||
| @@ -57,8 +57,6 @@ public class CustomDefinitionsAPI extends BaseAPI | ||||
|      * create reference endpoint | ||||
|      */ | ||||
|     private static final String CREATE_RELATIONSHIP_API_ENDPOINT = "{0}node/{1}/customreferences"; | ||||
|     private static final String GET_RELATIONSHIP_API_ENDPOINT = "{0}node/{1}/relationships"; | ||||
|     private static final String DELETE_RELATIONSHIP_API_ENDPOINT = "{0}node/{1}/targetnode/{2}/uniqueName/{3}"; | ||||
|  | ||||
|     /** | ||||
|      * logger | ||||
| @@ -143,48 +141,4 @@ public class CustomDefinitionsAPI extends BaseAPI | ||||
|         assertTrue("Creating relationship from " + recordNodeIdFrom + " to " + recordNodeIdTo + " failed.", success); | ||||
|     } | ||||
|  | ||||
|     public void createRelationship( | ||||
|         String adminUser, | ||||
|         String adminPassword, | ||||
|         int expectedStatus, | ||||
|         String recordNodeIdFrom, | ||||
|         String recordNodeIdTo, | ||||
|         CustomDefinitions relationshipType) { | ||||
|         //create the request body | ||||
|         JSONObject requestParams = new JSONObject(); | ||||
|         requestParams.put("toNode", NODE_REF_WORKSPACE_SPACES_STORE + recordNodeIdTo); | ||||
|         requestParams.put("refId", getCustomReferenceId(adminUser, adminPassword, relationshipType | ||||
|             .getDefinition())); | ||||
|         //send the API request to create the relationship | ||||
|         JSONObject setRelationshipStatus = doPostRequest(adminUser, adminPassword, requestParams, | ||||
|             MessageFormat.format(CREATE_RELATIONSHIP_API_ENDPOINT, "{0}", NODE_PREFIX + recordNodeIdFrom)); | ||||
|         //check the response | ||||
|         assertEquals("POST request for createRelationship was not successful.", expectedStatus, setRelationshipStatus.getJSONObject("status").get("code")); | ||||
|     } | ||||
|  | ||||
|     public JSONObject getRelationshipDetails( | ||||
|         String adminUser, | ||||
|         String adminPassword, | ||||
|         String nodeRef) { | ||||
|         //send the API request to create the relationship | ||||
|         JSONObject relationshipDetails = doGetRequest(adminUser, adminPassword, | ||||
|             MessageFormat.format(GET_RELATIONSHIP_API_ENDPOINT, "{0}", NODE_PREFIX + nodeRef)); | ||||
|         //check the response | ||||
|         assertNotNull("The Relationship detail is not found for the Noderef " + nodeRef, relationshipDetails); | ||||
|         return relationshipDetails; | ||||
|     } | ||||
|  | ||||
|     public void deleteRelationship( | ||||
|         String adminUser, | ||||
|         String adminPassword, | ||||
|         String recordNodeIdFrom, | ||||
|         String recordNodeIdTo, | ||||
|         String relationshipUniqueName) { | ||||
|         //send the API request to create the relationship | ||||
|         JSONObject setRelationshipStatus = doDeleteRequest(adminUser, adminPassword, | ||||
|             MessageFormat.format(DELETE_RELATIONSHIP_API_ENDPOINT, "{0}", NODE_PREFIX + recordNodeIdFrom,NODE_PREFIX + recordNodeIdTo,relationshipUniqueName)); | ||||
|         //check the response | ||||
|         boolean success = (setRelationshipStatus != null) && setRelationshipStatus.getBoolean("success"); | ||||
|         assertTrue("Deleting relationship from " + recordNodeIdFrom + " to " + recordNodeIdTo + " failed.", success); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,7 +73,6 @@ import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.BeforeMethod; | ||||
| import org.testng.annotations.DataProvider; | ||||
| import org.testng.annotations.Test; | ||||
| import org.alfresco.utility.model.TestGroup; | ||||
|  | ||||
| /** | ||||
|  * API tests for declaring document as record and filing it immediately to a record folder location within the file plan | ||||
| @@ -258,7 +257,7 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest | ||||
|      * Then I receive an error indicating that I have attempted to declare and file a document into an invalid record folder | ||||
|      * And the document is not declared as a record | ||||
|      */ | ||||
|     @Test (dataProvider = "invalidDestinationPaths",groups = { TestGroup.NOT_SUPPORTED_ON_SINGLE_PIPELINE }) | ||||
|     @Test (dataProvider = "invalidDestinationPaths") | ||||
|     public void declareAndFileToInvalidLocationUsingActionsAPI(String containerPath, String expectedException) throws Exception | ||||
|     { | ||||
|         STEP("Declare document as record with an invalid location parameter value"); | ||||
|   | ||||
| @@ -62,7 +62,6 @@ import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.BeforeMethod; | ||||
| import org.testng.annotations.DataProvider; | ||||
| import org.testng.annotations.Test; | ||||
| import org.alfresco.utility.model.TestGroup; | ||||
|  | ||||
| /** | ||||
|  * API tests for declaring a document version as record and filing to a record folder location within the file plan | ||||
| @@ -208,7 +207,7 @@ public class FileVersionAsRecordTests extends BaseRMRestTest | ||||
|      * record folder | ||||
|      * And the document is not declared as a version record | ||||
|      */ | ||||
|     @Test (dataProvider = "invalidDestinationPaths", groups = { TestGroup.NOT_SUPPORTED_ON_SINGLE_PIPELINE }) | ||||
|     @Test (dataProvider = "invalidDestinationPaths") | ||||
|     public void declareVersionAndFileToInvalidLocationUsingActionsAPI(String containerPath, String expectedException) throws Exception | ||||
|     { | ||||
|         STEP("Declare document as record version with an invalid location parameter value"); | ||||
|   | ||||
| @@ -1,202 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
|  | ||||
| package org.alfresco.rest.rm.community.records; | ||||
| import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID; | ||||
| import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION; | ||||
| import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON; | ||||
| import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; | ||||
| import java.util.Collections; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.custom.CustomDefinitions; | ||||
| import org.alfresco.rest.rm.community.model.record.Record; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild; | ||||
| import org.alfresco.rest.v0.CustomDefinitionsAPI; | ||||
| import org.alfresco.rest.v0.HoldsAPI; | ||||
| import org.alfresco.rest.v0.RMRolesAndActionsAPI; | ||||
| import org.alfresco.rest.v0.RecordsAPI; | ||||
| import org.alfresco.rest.v0.RecordCategoriesAPI; | ||||
| import org.alfresco.test.AlfrescoTest; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| import org.json.JSONObject; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.Test; | ||||
| import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR; | ||||
| import static org.apache.commons.httpclient.HttpStatus.SC_OK; | ||||
| /** | ||||
|  * Add Relationship tests | ||||
|  * @author Kavit Shah | ||||
|  */ | ||||
| public class AddRelationshipTests extends BaseRMRestTest | ||||
| { | ||||
|     private final String TEST_PREFIX = generateTestPrefix(AddRelationshipTests.class); | ||||
|     private final String CATEGORY = TEST_PREFIX + "category"; | ||||
|     private final String HOLD1 = TEST_PREFIX + "hold1"; | ||||
|     private final String FOLDER = TEST_PREFIX + "RM_2709_1814_FOLDER"; | ||||
|     private final String RECORD1 = TEST_PREFIX + "RM_2709_1814_RECORD_ONE"; | ||||
|     private final String RECORD2 = TEST_PREFIX + "RM_1814_RECORD_TWO"; | ||||
|     private String hold1NodeRef; | ||||
|     @Autowired | ||||
|     private HoldsAPI holdsAPI; | ||||
|     @Autowired | ||||
|     private RecordsAPI recordsAPI; | ||||
|     @Autowired | ||||
|     private CustomDefinitionsAPI customDefinitionsAPI; | ||||
|     @Autowired | ||||
|     private RMRolesAndActionsAPI rmRolesAndActionsAPI; | ||||
|     @Autowired | ||||
|     private RecordCategoriesAPI recordCategoriesAPI; | ||||
|  | ||||
|     @Test (priority = 1) | ||||
|     @AlfrescoTest (jira = "RM-1814") | ||||
|     public void addRelationshipToHoldRecord() | ||||
|     { | ||||
|         String CATEGORY_RELATIONSHIP = CATEGORY + "To Hold"; | ||||
|         //create RM site | ||||
|         createRMSiteIfNotExists(); | ||||
|         //create record category, record folder and records | ||||
|         RecordCategory recordCategory = createCategoryIfDoesNotExist(CATEGORY_RELATIONSHIP); | ||||
|         RecordCategoryChild recordCategoryChild = createRecordFolderInCategory(FOLDER, recordCategory); | ||||
|  | ||||
|         createRecordItems(recordCategoryChild, RECORD1); | ||||
|         Record record2 = createRecordItems(recordCategoryChild, RECORD2); | ||||
|  | ||||
|         //create Hold | ||||
|         hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), | ||||
|             getAdminUser().getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION); | ||||
|         //add RECORD2 to holds | ||||
|         holdsAPI.addItemsToHolds(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             SC_OK, Collections.singletonList(record2.getId()), | ||||
|             Collections.singletonList(hold1NodeRef)); | ||||
|  | ||||
|         // get records nodeRefs | ||||
|         String elRecordFullName1 = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, RECORD1); | ||||
|         String elRecordNodeRef1 = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName1, "/" + CATEGORY_RELATIONSHIP + "/" + FOLDER); | ||||
|  | ||||
|         String elRecordFullName2 = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, RECORD2); | ||||
|         String elRecordNodeRef2 = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName2, "/" + CATEGORY_RELATIONSHIP + "/" + FOLDER); | ||||
|  | ||||
|         // create Relationship | ||||
|         customDefinitionsAPI.createRelationship(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             SC_INTERNAL_SERVER_ERROR, | ||||
|             formatNodeRef(elRecordNodeRef1), | ||||
|             formatNodeRef(elRecordNodeRef2), | ||||
|             CustomDefinitions.ATTACHMENT); | ||||
|  | ||||
|         //delete preconditions | ||||
|         deletePrecondition(); | ||||
|     } | ||||
|  | ||||
|     @Test (priority = 2) | ||||
|     @AlfrescoTest (jira = "RM-1874") | ||||
|     public void deleteRelationship() | ||||
|     { | ||||
|         String CATEGORY_RELATIONSHIP = CATEGORY + "deleteRelationship"; | ||||
|         // create RM site | ||||
|         createRMSiteIfNotExists(); | ||||
|         // create record category, record folder and records | ||||
|         RecordCategory recordCategory = createCategoryIfDoesNotExist(CATEGORY_RELATIONSHIP); | ||||
|         RecordCategoryChild recordCategoryChild = createRecordFolderInCategory(FOLDER, recordCategory); | ||||
|  | ||||
|         createRecordItems(recordCategoryChild, RECORD1); | ||||
|         createRecordItems(recordCategoryChild, RECORD2); | ||||
|  | ||||
|         // Add Relationship | ||||
|         String elRecordFullName1 = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, RECORD1); | ||||
|         String elRecordNodeRef1 = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName1, "/" + CATEGORY_RELATIONSHIP + "/" + FOLDER); | ||||
|  | ||||
|         String elRecordFullName2 = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, RECORD2); | ||||
|         String elRecordNodeRef2 = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName2, "/" + CATEGORY_RELATIONSHIP + "/" + FOLDER); | ||||
|  | ||||
|         customDefinitionsAPI.createRelationship(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             formatNodeRef(elRecordNodeRef1), | ||||
|             formatNodeRef(elRecordNodeRef2), | ||||
|             CustomDefinitions.ATTACHMENT); | ||||
|  | ||||
|         // Get RelationshipDetails | ||||
|         JSONObject relationshipDetails = customDefinitionsAPI.getRelationshipDetails(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             formatNodeRef(elRecordNodeRef1)); | ||||
|  | ||||
|         // Delete RelationshipDetails | ||||
|         customDefinitionsAPI.deleteRelationship(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             formatNodeRef(elRecordNodeRef1), | ||||
|             formatNodeRef(elRecordNodeRef2), | ||||
|             relationshipUniqueName(relationshipDetails)); | ||||
|  | ||||
|         // delete category | ||||
|         tearDown(CATEGORY_RELATIONSHIP); | ||||
|     } | ||||
|  | ||||
|     private void deletePrecondition() | ||||
|     { | ||||
|         holdsAPI.deleteHold(getAdminUser(), hold1NodeRef); | ||||
|     } | ||||
|  | ||||
|     private Record createRecordItems(RecordCategoryChild recordCategoryChild, String record) { | ||||
|         return createElectronicRecord(recordCategoryChild.getId(), record); | ||||
|     } | ||||
|  | ||||
|     private RecordCategory createCategoryIfDoesNotExist(String CATEGORY_ALL) { | ||||
|         return createRootCategory(getDataUser().usingAdmin().getAdminUser(), CATEGORY_ALL); | ||||
|     } | ||||
|  | ||||
|     private RecordCategoryChild createRecordFolderInCategory(String FOLDER_SEARCH, RecordCategory recordCategory) { | ||||
|         return createFolder(getDataUser().usingAdmin().getAdminUser(), recordCategory.getId(), FOLDER_SEARCH); | ||||
|     } | ||||
|  | ||||
|     private String formatNodeRef(String nodeRef) { | ||||
|         return StringUtils.remove(nodeRef,"workspace://SpacesStore/"); | ||||
|     } | ||||
|  | ||||
|     private void tearDown(String category) { | ||||
|         rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, FOLDER); | ||||
|         rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, category); | ||||
|         recordCategoriesAPI.deleteCategory(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), category); | ||||
|     } | ||||
|  | ||||
|     private String relationshipUniqueName(JSONObject relationshipDetails) { | ||||
|         return relationshipDetails.getJSONObject("data").getJSONArray("items").getJSONObject(0).getJSONObject("node") | ||||
|             .get("relationshipUniqueName").toString(); | ||||
|     } | ||||
| } | ||||
| @@ -1,148 +0,0 @@ | ||||
| /*- | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.rest.rm.community.records; | ||||
|  | ||||
| import static java.util.Arrays.asList; | ||||
| import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; | ||||
| import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy; | ||||
| import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel; | ||||
| import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel; | ||||
| import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile; | ||||
| import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE; | ||||
| import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordModel; | ||||
| import static org.alfresco.utility.data.RandomData.getRandomName; | ||||
| import static org.alfresco.utility.report.log.Step.STEP; | ||||
| import static org.springframework.http.HttpStatus.CREATED; | ||||
| import static org.springframework.http.HttpStatus.OK; | ||||
| import org.alfresco.rest.model.RestNodeModel; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.record.Record; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; | ||||
| import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI; | ||||
| import org.alfresco.test.AlfrescoTest; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
| import org.alfresco.rest.v0.RMRolesAndActionsAPI; | ||||
| /** | ||||
|  * This class contains the tests for | ||||
|  * CreateElectronicRecordsTests Action REST API | ||||
|  * | ||||
|  * @author Shishuraj Bisht | ||||
|  */ | ||||
| public class CreateElectronicRecordsTests extends BaseRMRestTest { | ||||
|  | ||||
|     private RecordCategory rootCategory; | ||||
|     private UserModel updateUser; | ||||
|     /** | ||||
|      * data prep services | ||||
|      */ | ||||
|  | ||||
|     @Autowired | ||||
|     private RMRolesAndActionsAPI rmRolesAndActionsAPI; | ||||
|  | ||||
|     private final String TEST_PREFIX = generateTestPrefix(CreateElectronicRecordsTests.class); | ||||
|     private final String RM_ADMIN = TEST_PREFIX + "rm_admin"; | ||||
|  | ||||
|     @BeforeClass (alwaysRun = true) | ||||
|     public void preConditions() | ||||
|     { | ||||
|         STEP("Create RM Site"); | ||||
|         createRMSiteIfNotExists(); | ||||
|  | ||||
|         STEP("Create RM Admin user"); | ||||
|         rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN, | ||||
|             getAdminUser().getPassword(), | ||||
|             "Administrator"); | ||||
|  | ||||
|         STEP("Create root level category"); | ||||
|         rootCategory = createRootCategory(getRandomName("Category")); | ||||
|  | ||||
|         STEP("Create the record folder1 inside the rootCategory"); | ||||
|         String recordFolder1 = createCategoryFolderInFilePlan().getId(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Test v0 methods to create and get electronic records. | ||||
|      */ | ||||
|     @Test | ||||
|     @AlfrescoTest (jira = "RM-2768") | ||||
|     public void createElectronicRecordTest() throws Exception { | ||||
|  | ||||
|         //create electronic record in record folder | ||||
|         String recordFolder1 = createRecordFolder(rootCategory.getId(), getRandomName("recFolder")).getId(); | ||||
|         RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI(); | ||||
|  | ||||
|         Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder1, getFile(IMAGE_FILE)); | ||||
|         assertStatusCode(CREATED); | ||||
|         STEP("Check the electronic record has been created"); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         // Get recordsAPI instance initialised to updateUser | ||||
|         org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI(updateUser); | ||||
|  | ||||
|         for (Record record: asList(electronicRecord)) { | ||||
|             recordsAPI.getRecord(record.getId()); | ||||
|             assertStatusCode(OK); | ||||
|  | ||||
|             // Generate update metadata | ||||
|             String newName = getModifiedPropertyValue(record.getName()); | ||||
|             String newTitle = getModifiedPropertyValue(record.getProperties().getTitle()); | ||||
|             String newDescription = getModifiedPropertyValue(record.getProperties().getDescription()); | ||||
|  | ||||
|             // Update record | ||||
|             recordsAPI.updateRecord(createRecordModel(newName, newDescription, newTitle), record.getId()); | ||||
|             assertStatusCode(OK); | ||||
|         } | ||||
|         // move the record from one folder1 to folder2 | ||||
|         STEP("Create the record folder2 inside the rootCategory"); | ||||
|         String recordFolder2 = createCategoryFolderInFilePlan().getId(); | ||||
|  | ||||
|         STEP("Move record from folder1 to folder2"); | ||||
|         RestNodeModel electronicDocRestNodeModel = getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(electronicRecord.getId())) | ||||
|             .move(createBodyForMoveCopy(recordFolder2)); | ||||
|         assertStatusCode(OK); | ||||
|     } | ||||
|  | ||||
|     private String getModifiedPropertyValue(String originalValue) { | ||||
|         /* to be used to append to modifications */ | ||||
|         String MODIFIED_PREFIX = "modified_"; | ||||
|         return MODIFIED_PREFIX + originalValue; | ||||
|     } | ||||
|  | ||||
|     @AfterClass (alwaysRun = true) | ||||
|     public void deletePreConditions() { | ||||
|         STEP("Delete the created rootCategory along with corresponding record folders/records present in it"); | ||||
|         getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(rootCategory.getId()); | ||||
|     } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -1,145 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.rest.rm.community.records; | ||||
|  | ||||
| import org.alfresco.dataprep.CMISUtil; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.record.Record; | ||||
| import org.alfresco.rest.v0.RMRolesAndActionsAPI; | ||||
| import org.alfresco.rest.v0.RecordsAPI; | ||||
| import org.alfresco.test.AlfrescoTest; | ||||
| import org.alfresco.utility.constants.UserRole; | ||||
| import org.alfresco.utility.model.FileModel; | ||||
| import org.alfresco.utility.model.FolderModel; | ||||
| import org.alfresco.utility.model.SiteModel; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
| import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; | ||||
| import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; | ||||
| import static org.alfresco.utility.report.log.Step.STEP; | ||||
| import static org.springframework.http.HttpStatus.CREATED; | ||||
| import static org.testng.Assert.assertTrue; | ||||
| /** | ||||
|  * This class contains the tests for | ||||
|  * Create the Document, marking them as Record, Hiding them using Site Collaborator | ||||
|  * The Rm_Admin user then verofy if he is able to access the documents using Rest Api | ||||
|  * | ||||
|  * @author Kavit Shah | ||||
|  */ | ||||
| public class DeclareInPlaceRecordTests extends BaseRMRestTest { | ||||
|  | ||||
|     private final String TEST_PREFIX = generateTestPrefix(DeclareInPlaceRecordTests.class); | ||||
|     private final String RM_ADMIN = TEST_PREFIX + "rm_admin"; | ||||
|     private UserModel testUser; | ||||
|     private UserModel RmAdminUser; | ||||
|     private SiteModel testSite; | ||||
|     private FolderModel testFolder; | ||||
|     /** | ||||
|      * data prep services | ||||
|      */ | ||||
|     @Autowired | ||||
|     private RMRolesAndActionsAPI rmRolesAndActionsAPI; | ||||
|     @Autowired | ||||
|     private RecordsAPI recordsAPI; | ||||
|  | ||||
|     @BeforeClass(alwaysRun = true) | ||||
|     public void preConditions() { | ||||
|         STEP("Create RM Site"); | ||||
|         createRMSiteIfNotExists(); | ||||
|  | ||||
|         STEP("Create RM Admin user"); | ||||
|         rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN, | ||||
|             getAdminUser().getPassword(), | ||||
|             "Administrator"); | ||||
|  | ||||
|         RmAdminUser = new UserModel(RM_ADMIN,getAdminUser().getPassword()); | ||||
|  | ||||
|         STEP("Create collab_user user"); | ||||
|         testUser = getDataUser().createRandomTestUser(); | ||||
|         testSite = dataSite.usingAdmin().createPublicRandomSite(); | ||||
|  | ||||
|         // invite collab_user to Collaboration site with Contributor role | ||||
|         getDataUser().addUserToSite(testUser, testSite, UserRole.SiteContributor); | ||||
|  | ||||
|         testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     @AlfrescoTest(jira = "RM-2366") | ||||
|     public void declareInplaceRecord() { | ||||
|  | ||||
|         // Upload document in a folder in a collaboration site | ||||
|         FileModel uploadedDocHidden = dataContent.usingSite(testSite) | ||||
|             .usingUser(testUser) | ||||
|             .usingResource(testFolder) | ||||
|             .createContent(CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|  | ||||
|         // declare uploadedDocument as record | ||||
|         Record uploadedRecordHidden = getRestAPIFactory().getFilesAPI(testUser).declareAsRecord(uploadedDocHidden.getNodeRefWithoutVersion()); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         recordsAPI.hideRecord(testUser.getUsername(),testUser.getPassword(),uploadedRecordHidden.getId()); | ||||
|  | ||||
|         // Upload document in a folder in a collaboration site | ||||
|         FileModel uploadedDocWithoutHidden = dataContent.usingSite(testSite) | ||||
|             .usingUser(testUser) | ||||
|             .usingResource(testFolder) | ||||
|             .createContent(CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|  | ||||
|         Record uploadedRecordWithoutHidden = getRestAPIFactory().getFilesAPI(testUser).declareAsRecord(uploadedDocWithoutHidden.getNodeRefWithoutVersion()); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         assertTrue(isRecordChildOfUnfiledContainer(uploadedRecordHidden.getId()), uploadedRecordHidden.getId() + " doesn't exist in Unfiled Records"); | ||||
|         assertTrue(isRecordChildOfUnfiledContainer(uploadedRecordWithoutHidden.getId()), uploadedRecordWithoutHidden.getId() + " doesn't exist in Unfiled Records"); | ||||
|     } | ||||
|  | ||||
|     @AfterClass(alwaysRun = true) | ||||
|     public void deletePreConditions() { | ||||
|         STEP("Delete the records created in the test"); | ||||
|         getRestAPIFactory() | ||||
|             .getUnfiledContainersAPI(RmAdminUser) | ||||
|             .getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS) | ||||
|             .getEntries() | ||||
|             .stream() | ||||
|                 .forEach(x -> getRestAPIFactory() | ||||
|                     .getRecordsAPI() | ||||
|                     .deleteRecord(x.getEntry().getId())); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private boolean isRecordChildOfUnfiledContainer(String recordId) { | ||||
|         return getRestAPIFactory() | ||||
|             .getUnfiledContainersAPI(RmAdminUser) | ||||
|             .getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS) | ||||
|             .getEntries() | ||||
|             .stream() | ||||
|             .anyMatch(c -> c.getEntry().getId().equals(recordId)); | ||||
|     } | ||||
| } | ||||
| @@ -1,226 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
|  | ||||
| package org.alfresco.rest.rm.community.records; | ||||
|  | ||||
| import org.alfresco.dataprep.CMISUtil; | ||||
| import org.alfresco.rest.core.v0.BaseAPI; | ||||
| import org.alfresco.rest.model.RestNodeModel; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.record.Record; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild; | ||||
| import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI; | ||||
| import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI; | ||||
| import org.alfresco.rest.v0.RMRolesAndActionsAPI; | ||||
| import org.alfresco.rest.v0.RecordsAPI; | ||||
| import org.alfresco.test.AlfrescoTest; | ||||
| import org.alfresco.utility.constants.UserRole; | ||||
| import org.alfresco.utility.model.FileModel; | ||||
| import org.alfresco.utility.model.SiteModel; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.apache.chemistry.opencmis.client.api.CmisObject; | ||||
| import org.apache.http.HttpResponse; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static org.alfresco.rest.core.v0.APIUtils.convertHTTPResponseToJSON; | ||||
| import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; | ||||
| import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE; | ||||
| import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; | ||||
| import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy; | ||||
| import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel; | ||||
| import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; | ||||
| import static org.alfresco.utility.data.RandomData.getRandomName; | ||||
| import static org.alfresco.utility.report.log.Step.STEP; | ||||
| import static org.springframework.http.HttpStatus.CREATED; | ||||
|  | ||||
| public class FileUnfiledRecordsTests extends BaseRMRestTest { | ||||
|  | ||||
|     private final String TEST_PREFIX = generateTestPrefix(FileUnfiledRecordsTests.class); | ||||
|     private final String RM_ADMIN = TEST_PREFIX + "rm_admin"; | ||||
|     public static final String NODE_REF_WORKSPACE_SPACES_STORE = "workspace://SpacesStore/"; | ||||
|     private UserModel testUser; | ||||
|     private SiteModel testSite; | ||||
|     private String unfiledRecordFolderId; | ||||
|     private UserModel RmAdminUser; | ||||
|     private RecordCategory rootCategory; | ||||
|     private RecordCategoryChild recordFolder; | ||||
|     private final String recordName = "RM-2790 record"; | ||||
|     private final String recordTitle = recordName + " title"; | ||||
|     private final String recordDescription = recordName + " description"; | ||||
|     /** | ||||
|      * data prep services | ||||
|      */ | ||||
|     @Autowired | ||||
|     private RMRolesAndActionsAPI rmRolesAndActionsAPI; | ||||
|     @Autowired | ||||
|     private RecordsAPI recordsAPI; | ||||
|  | ||||
|     @BeforeClass(alwaysRun = true) | ||||
|     public void preConditions() { | ||||
|  | ||||
|         STEP("Create RM Site"); | ||||
|         createRMSiteIfNotExists(); | ||||
|  | ||||
|         STEP("Create RM Admin user"); | ||||
|         rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN, | ||||
|             getAdminUser().getPassword(), | ||||
|             "Administrator"); | ||||
|  | ||||
|         RmAdminUser = new UserModel(RM_ADMIN, getAdminUser().getPassword()); | ||||
|  | ||||
|         STEP("Create collab_user user"); | ||||
|         testUser = getDataUser().createRandomTestUser(); | ||||
|         testSite = dataSite.usingAdmin().createPublicRandomSite(); | ||||
|  | ||||
|         // invite collab_user to Collaboration site with Contributor role | ||||
|         getDataUser().addUserToSite(testUser, testSite, UserRole.SiteContributor); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     @AlfrescoTest(jira = "RM-2790") | ||||
|     public void fileUnfiledRecords() throws Exception { | ||||
|  | ||||
|         STEP("Upload the document to test site and then make it reacord"); | ||||
|         // Upload document in a folder in a collaboration site | ||||
|         FileModel uploadedDocbyCollabUser = dataContent.usingSite(testSite) | ||||
|             .usingUser(testUser) | ||||
|             .createContent(CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|  | ||||
|         // declare uploadedDocument as record | ||||
|         Record uploadedDocRecordbyCollabUser = getRestAPIFactory().getFilesAPI(testUser) | ||||
|             .declareAsRecord(uploadedDocbyCollabUser.getNodeRefWithoutVersion()); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         STEP("Create root level category"); | ||||
|         rootCategory = createRootCategory(RmAdminUser, getRandomName("Category")); | ||||
|  | ||||
|         STEP("Create the record folder inside the rootCategory"); | ||||
|         recordFolder = createFolder(RmAdminUser, rootCategory.getId(), getRandomName("Folder")); | ||||
|  | ||||
|         STEP("Create a non-electronic record by completing some of the fields"); | ||||
|         Map<Enum<?>, String> non_electronic_records_properties = new HashMap<>(); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.TITLE, recordTitle); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.DESCRIPTION, recordDescription); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.NAME, recordName); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.PHYSICAL_SIZE, ""); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.NUMBER_OF_COPIES, ""); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.SHELF, ""); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.STORAGE_LOCATION, ""); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.BOX, ""); | ||||
|         non_electronic_records_properties.put(BaseAPI.RMProperty.FILE, ""); | ||||
|  | ||||
|         HttpResponse nonElectronicRecordHttpResponse = recordsAPI.createNonElectronicRecord(getAdminUser().getUsername(), | ||||
|             getAdminUser().getPassword(), non_electronic_records_properties, rootCategory.getName(), recordFolder.getName()); | ||||
|  | ||||
|         String nonElectronicRecordId = getNodeRef(nonElectronicRecordHttpResponse); | ||||
|  | ||||
|         STEP("Check the non-electronic record has been created"); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         STEP("Create a electronic record by completing some of the fields"); | ||||
|         Map<BaseAPI.RMProperty, String> electronic_records_properties = new HashMap<>(); | ||||
|         electronic_records_properties.put(BaseAPI.RMProperty.DESCRIPTION, recordDescription); | ||||
|         electronic_records_properties.put(BaseAPI.RMProperty.NAME, recordName); | ||||
|  | ||||
|         recordsAPI.uploadElectronicRecord(RmAdminUser.getUsername(), | ||||
|             RmAdminUser.getPassword(), electronic_records_properties, recordFolder.getName(), CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|  | ||||
|         CmisObject electronicRecord = recordsAPI.getRecord(RmAdminUser.getUsername(), | ||||
|             RmAdminUser.getPassword(),recordFolder.getName(), electronic_records_properties.get(BaseAPI.RMProperty.NAME)); | ||||
|  | ||||
|         STEP("Check the electronic record has been created"); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         STEP("Create a root folder under FilePlan - Unfiled"); | ||||
|         String unFiledFolder = createUnFileFolder(); | ||||
|  | ||||
|         STEP("Move all the Unfiled Records to unFiledFolder"); | ||||
|         RestNodeModel uploadDocRestNodeModel = getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(uploadedDocRecordbyCollabUser.getId())) | ||||
|             .move(createBodyForMoveCopy(unFiledFolder)); | ||||
|  | ||||
|         RestNodeModel nonElectronicDocRestNodeModel = getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(nonElectronicRecordId)) | ||||
|             .move(createBodyForMoveCopy(unFiledFolder)); | ||||
|  | ||||
|         RestNodeModel electronicDocRestNodeModel = getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(electronicRecord.getId())) | ||||
|             .move(createBodyForMoveCopy(unFiledFolder)); | ||||
|  | ||||
|         STEP("Move all the Record present in the unFiledFolder to Folder inside Root Category"); | ||||
|  | ||||
|         getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(uploadDocRestNodeModel.getId())) | ||||
|             .move(createBodyForMoveCopy(recordFolder.getId())); | ||||
|  | ||||
|         getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(nonElectronicDocRestNodeModel.getId())) | ||||
|             .move(createBodyForMoveCopy(recordFolder.getId())); | ||||
|  | ||||
|         getRestAPIFactory() | ||||
|             .getNodeAPI(toContentModel(electronicDocRestNodeModel.getId())) | ||||
|             .move(createBodyForMoveCopy(recordFolder.getId())); | ||||
|  | ||||
|         getRestAPIFactory().getRecordsAPI().deleteRecord(uploadDocRestNodeModel.getId()); | ||||
|         getRestAPIFactory().getRecordsAPI().deleteRecord(nonElectronicDocRestNodeModel.getId()); | ||||
|         getRestAPIFactory().getRecordsAPI().deleteRecord(electronicDocRestNodeModel.getId()); | ||||
|  | ||||
|         UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI(); | ||||
|         unfiledRecordFoldersAPI.deleteUnfiledRecordFolder(unFiledFolder); | ||||
|  | ||||
|         RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI(); | ||||
|         String recordFolderId = recordFolder.getId(); | ||||
|         recordFolderAPI.deleteRecordFolder(recordFolderId); | ||||
|     } | ||||
|  | ||||
|     @AfterClass (alwaysRun = true) | ||||
|     public void deletePreConditions() | ||||
|     { | ||||
|         STEP("Delete the created rootCategory along with corresponding record folders/records present in it"); | ||||
|         getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(rootCategory.getId()); | ||||
|     } | ||||
|  | ||||
|     private String createUnFileFolder() { | ||||
|         String categoryName = "RM-2790 record Category name " + getRandomAlphanumeric(); | ||||
|  | ||||
|         unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, | ||||
|             categoryName + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId(); | ||||
|         return unfiledRecordFolderId; | ||||
|     } | ||||
|  | ||||
|     private String getNodeRef(HttpResponse httpResponse) { | ||||
|             return convertHTTPResponseToJSON(httpResponse).getString("persistedObject") | ||||
|                 .replace(NODE_REF_WORKSPACE_SPACES_STORE, ""); | ||||
|     } | ||||
| } | ||||
| @@ -1,179 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
|  | ||||
| package org.alfresco.rest.rm.community.records; | ||||
|  | ||||
| import org.alfresco.dataprep.CMISUtil; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.record.Record; | ||||
| import org.alfresco.rest.v0.RecordsAPI; | ||||
| import org.alfresco.utility.Utility; | ||||
| import org.alfresco.utility.constants.UserRole; | ||||
| import org.alfresco.utility.model.FileModel; | ||||
| import org.alfresco.utility.model.SiteModel; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.json.JSONObject; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| import static org.alfresco.utility.report.log.Step.STEP; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| import static org.springframework.http.HttpStatus.CREATED; | ||||
| import static org.springframework.test.util.AssertionErrors.assertTrue; | ||||
| import static org.testng.Assert.fail; | ||||
|  | ||||
| public class InplaceRecordSearchTests extends BaseRMRestTest { | ||||
|  | ||||
|     private UserModel siteCollaborator, siteConsumer, nonSiteMember; | ||||
|     private SiteModel privateSite; | ||||
|     private Record uploadedDocRecordbyCollabUser; | ||||
|     private FileModel uploadedDocbyCollabUser; | ||||
|     @Autowired | ||||
|     private RecordsAPI recordsAPI; | ||||
|  | ||||
|     @BeforeClass(alwaysRun = true) | ||||
|     public void preConditions() { | ||||
|  | ||||
|         STEP("Create RM Site"); | ||||
|         createRMSiteIfNotExists(); | ||||
|  | ||||
|         // And a private collaboration site | ||||
|         privateSite = dataSite.usingAdmin().createPrivateRandomSite(); | ||||
|  | ||||
|         // And a site collaborator | ||||
|         siteCollaborator = getDataUser().createRandomTestUser(); | ||||
|         getDataUser().addUserToSite(siteCollaborator, privateSite, UserRole.SiteCollaborator); | ||||
|  | ||||
|         // And a site consumer | ||||
|         siteConsumer = getDataUser().createRandomTestUser(); | ||||
|         getDataUser().addUserToSite(siteConsumer, privateSite, UserRole.SiteConsumer); | ||||
|  | ||||
|         nonSiteMember = getDataUser().createRandomTestUser(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a RM site | ||||
|      * And a private collaboration site | ||||
|      * And a site collaborator | ||||
|      * And a site consumer | ||||
|      * And a user who is not a member of the site | ||||
|      * And a document that isn't a record | ||||
|      * When the collaborator declares it as a record | ||||
|      * Then the collaborator can browse to the record in the document library | ||||
|      * And can find the record using live search | ||||
|      * And can find the record using advanced search | ||||
|      * And the consumer can browse to the record in the document library | ||||
|      * And can find the record using live search | ||||
|      * And can find the record using advanced search | ||||
|      * And the user who is not a member of the site can't find the record using live search | ||||
|      * And can't find the record using advanced search | ||||
|      */ | ||||
|     @Test | ||||
|     public void searchForInplaceRecord() { | ||||
|         // And a document that isn't a record | ||||
|         uploadedDocbyCollabUser = dataContent.usingSite(privateSite) | ||||
|             .usingUser(siteCollaborator) | ||||
|             .createContent(CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|  | ||||
|         assertNotNull(uploadedDocbyCollabUser.getNodeRef()); | ||||
|  | ||||
|         // declare uploadedDocument as record | ||||
|         uploadedDocRecordbyCollabUser = getRestAPIFactory().getFilesAPI(siteCollaborator) | ||||
|             .declareAsRecord(uploadedDocbyCollabUser.getNodeRefWithoutVersion()); | ||||
|         assertStatusCode(CREATED); | ||||
|  | ||||
|         assertNotNull(uploadedDocRecordbyCollabUser.getId()); | ||||
|  | ||||
|         STEP("Allow the Document to be index for it to be available"); | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             Utility.sleep(1000, 40000, () -> | ||||
|             { | ||||
|                 JSONObject siteConsumerSearchJson = getSearchApi().liveSearchForDocuments(siteConsumer.getUsername(), | ||||
|                     siteConsumer.getPassword(), | ||||
|                     uploadedDocbyCollabUser.getName()); | ||||
|                 assertTrue("Site Consumer not able to find the document.",siteConsumerSearchJson.getJSONArray("items").length() != 0); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) | ||||
|         { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             Utility.sleep(1000, 40000, () -> | ||||
|                 { | ||||
|                     JSONObject siteCollaboratorSearchJson = getSearchApi().liveSearchForDocuments(siteCollaborator.getUsername(), | ||||
|                     siteCollaborator.getPassword(), | ||||
|                     uploadedDocbyCollabUser.getName()); | ||||
|                     assertTrue("Site Collaborator not able to find the document.",siteCollaboratorSearchJson.getJSONArray("items").length() != 0); | ||||
|                 }); | ||||
|         } | ||||
|         catch (InterruptedException e) | ||||
|         { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         JSONObject nonSiteMemberSearchJson = getSearchApi().liveSearchForDocuments(nonSiteMember.getUsername(), | ||||
|             nonSiteMember.getPassword(), | ||||
|             uploadedDocbyCollabUser.getName()); | ||||
|  | ||||
|         assertTrue("Non Site Member is able to access restricted document.",nonSiteMemberSearchJson.getJSONArray("items").isEmpty()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given @see {@link #searchForInplaceRecord()} | ||||
|      * When the collaboration user hides the record in the collaboration site | ||||
|      * Then the collaborator can not browse to the record in the document library | ||||
|      * And can't find the record using live search | ||||
|      * And can't find the record using advanced search | ||||
|      */ | ||||
|     @Test(dependsOnMethods = {"searchForInplaceRecord"}) | ||||
|     public void usersCantFindRecordAfterHide() { | ||||
|         recordsAPI.hideRecord(siteCollaborator.getUsername(),siteCollaborator.getPassword(),uploadedDocRecordbyCollabUser.getId()); | ||||
|  | ||||
|         JSONObject siteCollaboratorSearchJson = getSearchApi().liveSearchForDocuments(siteCollaborator.getUsername(), | ||||
|             siteCollaborator.getPassword(), | ||||
|             uploadedDocbyCollabUser.getName()); | ||||
|         assertTrue("Site Collaborator able to find the document after it is hidden.",siteCollaboratorSearchJson.getJSONArray("items").isEmpty()); | ||||
|     } | ||||
|  | ||||
|     @AfterClass | ||||
|     public void tearDown() { | ||||
|         // clean-up collab site | ||||
|         dataSite.usingAdmin().deleteSite(privateSite); | ||||
|  | ||||
|         // clean-up users siteCollaborator, siteConsumer, nonSiteMember | ||||
|         dataUser.deleteUser(siteCollaborator); | ||||
|         dataUser.deleteUser(siteConsumer); | ||||
|         dataUser.deleteUser(nonSiteMember); | ||||
|     } | ||||
| } | ||||
| @@ -1,539 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Records Management Module | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
|  | ||||
| package org.alfresco.rest.rm.community.records; | ||||
|  | ||||
| import org.alfresco.dataprep.CMISUtil; | ||||
| import org.alfresco.rest.core.v0.BaseAPI; | ||||
| import org.alfresco.rest.rm.community.base.BaseRMRestTest; | ||||
| import org.alfresco.rest.rm.community.model.record.RecordContent; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; | ||||
| import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild; | ||||
| import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild; | ||||
| import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI; | ||||
| import org.alfresco.rest.v0.RMRolesAndActionsAPI; | ||||
| import org.alfresco.rest.v0.RecordsAPI; | ||||
| import org.alfresco.rest.v0.SearchAPI; | ||||
| import org.alfresco.utility.Utility; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.apache.http.HttpResponse; | ||||
| import org.json.JSONObject; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
| import org.json.JSONArray; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
| import java.util.HashMap; | ||||
| import java.util.concurrent.atomic.AtomicBoolean; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.IntStream; | ||||
| import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME; | ||||
| 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.user.UserPermissions.*; | ||||
| import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; | ||||
| import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createTempFile; | ||||
| import static org.alfresco.utility.report.log.Step.STEP; | ||||
| import static org.junit.Assert.assertFalse; | ||||
| import static org.junit.Assert.fail; | ||||
| import static org.testng.Assert.assertTrue; | ||||
| /** | ||||
|  * Tests the search of records in Records Search page | ||||
|  * @author Kavit Shah | ||||
|  */ | ||||
| public class SearchRecordsTests extends BaseRMRestTest { | ||||
|  | ||||
|     private Optional<UserModel> nonRmSiteUser, rm_user_search, rm_manager, rm_admin_search; | ||||
|  | ||||
|     /** The default password used when creating test users. */ | ||||
|     public static final String ROLE_RM_MANAGER = "RecordsManager"; | ||||
|     private final String TEST_PREFIX = generateTestPrefix(SearchRecordsTests.class); | ||||
|     private final String CATEGORY_ALL = TEST_PREFIX + "everybody's category"; | ||||
|     private final String FOLDER_SEARCH = TEST_PREFIX + "basic search folder"; | ||||
|     private final String FOLDER_ADMIN_ONLY = TEST_PREFIX + "rm admin category"; | ||||
|     private final String CATEGORY_ADMIN_ONLY = TEST_PREFIX + "rm admin category"; | ||||
|     public static final String ROLE_RM_USER = "User"; | ||||
|     public static final String ADMIN = "Administrator"; | ||||
|     private final String ELECTRONIC_RECORD = TEST_PREFIX + " Electronic"; | ||||
|     private final String UNFILED_ELECTRONIC_RECORD = TEST_PREFIX + " Unfiled Electronic"; | ||||
|     private final String NON_ELECTRONIC_RECORD = TEST_PREFIX + " Non-Electronic"; | ||||
|     private final String ADMIN_ELECTRONIC_RECORD = TEST_PREFIX + " admin Electronic"; | ||||
|     public static final String TITLE = "Title"; | ||||
|     public static final String DESCRIPTION = "Description"; | ||||
|     public static final String TEST_CONTENT = "This is some test content"; | ||||
|     private RecordCategory categoryAll, category_Admin_Only; | ||||
|     @Autowired | ||||
|     private RMRolesAndActionsAPI rmRolesAndActionsAPI; | ||||
|     @Autowired | ||||
|     private SearchAPI searchAPI; | ||||
|     @Autowired | ||||
|     private RecordsAPI recordsAPI; | ||||
|  | ||||
|     @BeforeClass (alwaysRun = true) | ||||
|     public void createRecordsForSearch() | ||||
|     { | ||||
|         createRMSiteIfNotExists(); | ||||
|         nonRmSiteUser = Optional.ofNullable(getDataUser().createRandomTestUser()); | ||||
|         // create RM manager and RM user | ||||
|         createRMManager(); | ||||
|         createRMUser(); | ||||
|         createRMAdmin(); | ||||
|         categoryAll = createCategoryIfDoesNotExist(CATEGORY_ALL); | ||||
|         createRecordFolderInCategory(FOLDER_SEARCH, categoryAll); | ||||
|  | ||||
|         category_Admin_Only = createCategoryIfDoesNotExist(CATEGORY_ADMIN_ONLY); | ||||
|         createRecordFolderInCategory(FOLDER_ADMIN_ONLY,category_Admin_Only); | ||||
|  | ||||
|         // upload records in folder in category and in Unfiled Records | ||||
|         uploadElectronicRecordInContainer(ELECTRONIC_RECORD, FOLDER_SEARCH); | ||||
|         createNonElectronicRecordInContainer(NON_ELECTRONIC_RECORD, CATEGORY_ALL, FOLDER_SEARCH); | ||||
|         uploadElectronicRecordInContainer(ADMIN_ELECTRONIC_RECORD, FOLDER_ADMIN_ONLY); | ||||
|  | ||||
|         UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder() | ||||
|             .name(UNFILED_ELECTRONIC_RECORD) | ||||
|             .nodeType(CONTENT_TYPE) | ||||
|             .content(RecordContent.builder().mimeType("text/plain").build()) | ||||
|             .build(); | ||||
|         getRecordsFromUnfiledRecordsContainer(electronicRecord); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given I have created record category X which contains record folder Y which contains record Z | ||||
|      * And I have selected to display record category id in the search results | ||||
|      * When I issue a record search whose results will contain record X | ||||
|      * Then record X is displayed in the results | ||||
|      * And the record category X's ID is also displayed in search result meta-data for record X | ||||
|      */ | ||||
|     @Test(priority = 1) | ||||
|     public void searchResultsWithRecordCategoryIdentifier() { | ||||
|         AtomicBoolean electronicRecordFound = new AtomicBoolean(false); | ||||
|         AtomicReference<JSONArray> items = new AtomicReference<>(); | ||||
|         AtomicBoolean recordCategoryIdentifier = new AtomicBoolean(false); | ||||
|  | ||||
|         STEP("Open the record search page and search by the items created"); | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 JSONObject searchResult = (searchAPI | ||||
|                     .rmSearch(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|                         getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|                         "rm", | ||||
|                         "keywords:" + TEST_PREFIX + "*", | ||||
|                         "records/true,undeclared/true,vital/false,folders/false,categories/false,frozen/false,cutoff/false", | ||||
|                         "rma:identifier/asc")); | ||||
|                 items.set((JSONArray) searchResult.get("items")); | ||||
|                 assertFalse("Site Consumer not able to find the document.", ((JSONArray)searchResult.get("items")).isEmpty()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         STEP("Check that the records from file plan have the record category identifier displayed"); | ||||
|         List searchList = IntStream.range(0, items.get().length()).mapToObj(i-> items.get().get(i)).collect(Collectors.toList()); | ||||
|  | ||||
|         searchList.stream().forEach(x -> { | ||||
|             Map<String, String> reconstructedUtilMap = Arrays.stream(x.toString().split(",")) | ||||
|                 .map(s -> s.split(":")) | ||||
|                 .collect(Collectors.toMap(s -> s[0], s -> s[1])); | ||||
|             if(reconstructedUtilMap.get("\"name\"").contains(TEST_PREFIX + " Electronic")) { | ||||
|                 electronicRecordFound.set(true); | ||||
|             } | ||||
|         }); | ||||
|         assertFalse("The File Name with the Prefix " + TEST_PREFIX + " as Electronic Record was not found.", !electronicRecordFound.get()); | ||||
|  | ||||
|         STEP("Change the search filter to return only record folders and record categories"); | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 JSONObject searchResult = (searchAPI | ||||
|                     .rmSearch(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|                         getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|                         "rm", | ||||
|                         "keywords:" + TEST_PREFIX + "*", | ||||
|                         "records/false,undeclared/true,vital/false,folders/true,categories/true,frozen/false,cutoff/false", | ||||
|                         "rma:identifier/asc")); | ||||
|                 items.set((JSONArray) searchResult.get("items")); | ||||
|                 assertFalse("Site Consumer not able to find the document.", ((JSONArray)searchResult.get("items")).isEmpty()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|         STEP("Check that the records folders and categories don't have a record category identifier displayed"); | ||||
|         List recordFolderSearchList = IntStream.range(0, items.get().length()).mapToObj(i-> items.get().get(i)).collect(Collectors.toList()); | ||||
|  | ||||
|         recordFolderSearchList.stream().forEach(x -> { | ||||
|             Map<String, String> reconstructedUtilMap = Arrays.stream(x.toString().split(",")) | ||||
|                 .map(s -> s.split(":")) | ||||
|                 .collect(Collectors.toMap(s -> s[0], s -> s[1])); | ||||
|             if(null != reconstructedUtilMap.get("\"rma_recordCategoryIdentifier\"")) { | ||||
|                 recordCategoryIdentifier.set(true); | ||||
|             } | ||||
|         }); | ||||
|         assertFalse("Record Category Identifier displayed for " + TEST_PREFIX + ".", recordCategoryIdentifier.get()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User with RM User role can see the records he has permission over and all in Unfiled Records | ||||
|      * <p> | ||||
|      * Given that I am a RM User | ||||
|      * I can see only the records in File Plan I have permission over and all in Unfiled Records | ||||
|      */ | ||||
|     @Test (priority = 2) | ||||
|     public void nonRMUserSearchResults() { | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(nonRmSiteUser.get().getUsername(), | ||||
|                         nonRmSiteUser.get().getPassword(), | ||||
|                         ELECTRONIC_RECORD)); | ||||
|                 assertFalse("The file with search term " + ELECTRONIC_RECORD + " was found using RM Not Site User "+ nonRmSiteUser.get().getUsername(),getResult(ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(nonRmSiteUser.get().getUsername(), | ||||
|                         nonRmSiteUser.get().getPassword(), | ||||
|                         UNFILED_ELECTRONIC_RECORD)); | ||||
|                 assertFalse("The file with search term " + UNFILED_ELECTRONIC_RECORD + " was not found using RM Not Site User "+ nonRmSiteUser.get().getUsername(),getResult(UNFILED_ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(nonRmSiteUser.get().getUsername(), | ||||
|                         nonRmSiteUser.get().getPassword(), | ||||
|                         NON_ELECTRONIC_RECORD)); | ||||
|                 assertFalse("The file with search term " + NON_ELECTRONIC_RECORD + " was not found using RM Not Site User "+ nonRmSiteUser.get().getUsername(),getResult(NON_ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = searchAPI | ||||
|                     .searchForDocumentsAsUser(nonRmSiteUser.get().getUsername(), | ||||
|                         nonRmSiteUser.get().getPassword(), | ||||
|                         ADMIN_ELECTRONIC_RECORD); | ||||
|                 assertFalse("The file with search term " + ADMIN_ELECTRONIC_RECORD + " was not found using RM Not Site User "+ nonRmSiteUser.get().getUsername(),getResult(ADMIN_ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User with RM User role can see the records he has permission over and all in Unfiled Records | ||||
|      * <p> | ||||
|      * Given that I am a RM User | ||||
|      * I can see only the records in File Plan I have permission over and all in Unfiled Records | ||||
|      */ | ||||
|     @Test (priority = 3) | ||||
|     public void rmUserSearchResults() { | ||||
|         getRestAPIFactory().getRMUserAPI().addUserPermission(categoryAll.getId(), rm_user_search.get(), PERMISSION_READ_RECORDS); | ||||
|         getRestAPIFactory().getRMUserAPI().addUserPermission(categoryAll.getId(), rm_user_search.get(), PERMISSION_FILE_RECORDS); | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_user_search.get().getUsername(), | ||||
|                         rm_user_search.get().getPassword(), | ||||
|                         ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(ELECTRONIC_RECORD,stringList),"The file with search term" + ELECTRONIC_RECORD + " was not found using RM User "+ rm_user_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_user_search.get().getUsername(), | ||||
|                         rm_user_search.get().getPassword(), | ||||
|                         UNFILED_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(UNFILED_ELECTRONIC_RECORD,stringList),"The file with search term" + UNFILED_ELECTRONIC_RECORD + " was not found using RM User "+ rm_user_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_user_search.get().getUsername(), | ||||
|                         rm_user_search.get().getPassword(), | ||||
|                         NON_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(NON_ELECTRONIC_RECORD,stringList),"The file with search term" + NON_ELECTRONIC_RECORD + " was not found using RM User "+ rm_user_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_user_search.get().getUsername(), | ||||
|                         rm_user_search.get().getPassword(), | ||||
|                         ADMIN_ELECTRONIC_RECORD); | ||||
|                 assertFalse("The file with search term" + ADMIN_ELECTRONIC_RECORD + " was not found using RM User "+ rm_user_search.get().getUsername(),getResult(ADMIN_ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User with RM Manager role can see the records he has permission over and all in Unfiled Records | ||||
|      * <p> | ||||
|      * Given that I am a RM Manager | ||||
|      * I can see only the records in File Plan I have permission over and all in Unfiled Records | ||||
|      */ | ||||
|     @Test (priority = 4) | ||||
|     public void rmManagerSearchResults() { | ||||
|         getRestAPIFactory().getRMUserAPI().addUserPermission(categoryAll.getId(), rm_manager.get(), PERMISSION_READ_RECORDS); | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_manager.get().getUsername(), | ||||
|                         rm_manager.get().getPassword(), | ||||
|                         ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(ELECTRONIC_RECORD,stringList),"The file with search term " + ELECTRONIC_RECORD + " was not found using RM manager User "+ rm_manager.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_manager.get().getUsername(), | ||||
|                         rm_manager.get().getPassword(), | ||||
|                         UNFILED_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(UNFILED_ELECTRONIC_RECORD,stringList),"The file with search term " + UNFILED_ELECTRONIC_RECORD + " was not found using RM manager User "+ rm_manager.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_manager.get().getUsername(), | ||||
|                         rm_manager.get().getPassword(), | ||||
|                         NON_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(NON_ELECTRONIC_RECORD,stringList),"The file with search term " + NON_ELECTRONIC_RECORD + " was not found using RM manager User "+ rm_manager.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_manager.get().getUsername(), | ||||
|                         rm_manager.get().getPassword(), | ||||
|                         ADMIN_ELECTRONIC_RECORD); | ||||
|                 assertFalse("The file with search term" + ADMIN_ELECTRONIC_RECORD + " was found using RM manager User "+ rm_manager.get().getUsername(),getResult(ADMIN_ELECTRONIC_RECORD,stringList)); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User with RM Administrator role can see all the records | ||||
|      * | ||||
|      * Given that I am a RM Administrator | ||||
|      * I can see all the records in File Plan and Unfiled Records through RM Search and Advanced Search | ||||
|      */ | ||||
|     @Test(priority = 5) | ||||
|     public void rmAdminSearchResults() { | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_admin_search.get().getUsername(), | ||||
|                         rm_admin_search.get().getPassword(), | ||||
|                         ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(ELECTRONIC_RECORD,stringList),"The file with search term " + ELECTRONIC_RECORD + " was not found using RM Admin User "+ rm_admin_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_admin_search.get().getUsername(), | ||||
|                         rm_admin_search.get().getPassword(), | ||||
|                         UNFILED_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(UNFILED_ELECTRONIC_RECORD,stringList),"The file with search term " + UNFILED_ELECTRONIC_RECORD + " was not found using RM Admin User "+ rm_admin_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Utility.sleep(1000, 40000, () -> { | ||||
|                 List<String> stringList = (searchAPI | ||||
|                     .searchForDocumentsAsUser(rm_admin_search.get().getUsername(), | ||||
|                         rm_admin_search.get().getPassword(), | ||||
|                         NON_ELECTRONIC_RECORD)); | ||||
|                 assertTrue(getResult(NON_ELECTRONIC_RECORD,stringList),"The file with search term " + NON_ELECTRONIC_RECORD + " was not found using RM Admin User "+ rm_admin_search.get().getUsername()); | ||||
|             }); | ||||
|         } | ||||
|         catch (InterruptedException e) { | ||||
|             fail("InterruptedException received while waiting for results."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void createRMManager() { | ||||
|         // create RM manager | ||||
|         rm_manager = Optional.ofNullable(getDataUser().createRandomTestUser()); | ||||
|         rmRolesAndActionsAPI.assignRoleToUser( | ||||
|             getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             rm_manager.get().getUsername(), | ||||
|             ROLE_RM_MANAGER | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private void createRMUser() { | ||||
|         // create RM manager | ||||
|         rm_user_search = Optional.ofNullable(getDataUser().createRandomTestUser()); | ||||
|         rmRolesAndActionsAPI.assignRoleToUser( | ||||
|             getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             rm_user_search.get().getUsername(), | ||||
|             ROLE_RM_USER | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private void createRMAdmin() { | ||||
|         // create RM Admin | ||||
|         rm_admin_search = Optional.ofNullable(getDataUser().createRandomTestUser()); | ||||
|         rmRolesAndActionsAPI.assignRoleToUser( | ||||
|             getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             rm_admin_search.get().getUsername(), | ||||
|             ADMIN | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private RecordCategory createCategoryIfDoesNotExist(String CATEGORY_ALL) { | ||||
|         return createRootCategory(getDataUser().usingAdmin().getAdminUser(), CATEGORY_ALL); | ||||
|     } | ||||
|  | ||||
|     private RecordCategoryChild createRecordFolderInCategory(String FOLDER_SEARCH, RecordCategory recordCategory) { | ||||
|         return createFolder(getDataUser().usingAdmin().getAdminUser(), recordCategory.getId(), FOLDER_SEARCH); | ||||
|     } | ||||
|  | ||||
|     private void uploadElectronicRecordInContainer(String electronic_record, String folder_search) { | ||||
|         recordsAPI.uploadElectronicRecord(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), | ||||
|             getDefaultElectronicRecordProperties(electronic_record), folder_search, CMISUtil.DocumentType.TEXT_PLAIN); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     protected HttpResponse createNonElectronicRecordInContainer(String name, String categoryName, String folderName) { | ||||
|         Map<BaseAPI.RMProperty, String> defaultProperties = new HashMap<>(); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.NAME, name); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.TITLE, TITLE); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.DESCRIPTION, DESCRIPTION); | ||||
|  | ||||
|         return recordsAPI.createNonElectronicRecord(getDataUser().usingAdmin().getAdminUser().getUsername(), | ||||
|             getDataUser().usingAdmin().getAdminUser().getPassword(), defaultProperties, categoryName, folderName); | ||||
|     } | ||||
|  | ||||
|     public Map<BaseAPI.RMProperty, String> getDefaultElectronicRecordProperties(String recordName) { | ||||
|         Map<BaseAPI.RMProperty, String> defaultProperties = new HashMap<>(); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.NAME, recordName); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.TITLE, TITLE); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.DESCRIPTION, DESCRIPTION); | ||||
|         defaultProperties.put(BaseAPI.RMProperty.CONTENT, TEST_CONTENT); | ||||
|         return defaultProperties; | ||||
|     } | ||||
|  | ||||
|     @AfterClass(alwaysRun = true) | ||||
|     public void standardSearchTeardown() { | ||||
|         // delete categories | ||||
|         deleteRecordCategory(categoryAll.getId()); | ||||
|         deleteRecordCategory(category_Admin_Only.getId()); | ||||
|  | ||||
|         // delete users | ||||
|         Optional.of(nonRmSiteUser).ifPresent(x -> getDataUser().deleteUser(x.get())); | ||||
|         Optional.of(rm_user_search).ifPresent(x -> getDataUser().deleteUser(x.get())); | ||||
|         Optional.of(rm_manager).ifPresent(x -> getDataUser().deleteUser(x.get())); | ||||
|         Optional.of(rm_admin_search).ifPresent(x -> getDataUser().deleteUser(x.get())); | ||||
|     } | ||||
|  | ||||
|     private boolean getResult(String partialRecordName, List<String> searchResults) { | ||||
|         if(null != searchResults) { | ||||
|             for (String searchResult : searchResults) { | ||||
|                 if (searchResult.startsWith(partialRecordName)) { | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private Object[][] getRecordsFromUnfiledRecordsContainer(UnfiledContainerChild electronicRecord) | ||||
|     { | ||||
|         UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI(); | ||||
|         return new String[][] { | ||||
|             { unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, | ||||
|                 createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME)).getId()} | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -7,7 +7,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-governance-services-community-parent</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <modules> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-governance-services-community-repo-parent</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <properties> | ||||
|   | ||||
| @@ -3,8 +3,8 @@ | ||||
| # | ||||
|  | ||||
| # Version label | ||||
| version.major=7 | ||||
| version.minor=3 | ||||
| version.major=23 | ||||
| version.minor=1 | ||||
| version.revision=0 | ||||
| version.label= | ||||
|  | ||||
| @@ -15,4 +15,4 @@ version.edition=Community | ||||
| version.scmrevision=@scm-path@-r@scm-revision@ | ||||
|  | ||||
| # Build number | ||||
| version.build=r@scm-revision@-b@build-number@ | ||||
| version.build=r@scm-revision@-b@build-number@ | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-governance-services-community-repo-parent</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <build> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <modules> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-amps</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <properties> | ||||
|   | ||||
| @@ -176,6 +176,7 @@ public class NodeBrowserScript extends NodeBrowserPost implements Serializable | ||||
| 			{ | ||||
| 				status.setCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); | ||||
| 				status.setMessage(e.getMessage()); | ||||
| 				status.setException(e); | ||||
| 				status.setRedirect(true); | ||||
| 			} | ||||
|     		return tmplMap; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|    <parent> | ||||
|       <groupId>org.alfresco</groupId> | ||||
|       <artifactId>alfresco-community-repo</artifactId> | ||||
|       <version>17.23</version> | ||||
|       <version>23.1.0.23-SNAPSHOT</version> | ||||
|    </parent> | ||||
|  | ||||
|    <dependencies> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <properties> | ||||
| @@ -134,7 +134,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.woodstox</groupId> | ||||
|             <artifactId>woodstox-core</artifactId> | ||||
|             <version>6.2.8</version> | ||||
|             <version>6.2.7</version> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- the cxf libs were updated, see dependencyManagement section --> | ||||
|   | ||||
| @@ -78,10 +78,6 @@ public class ObjectTypeIdLuceneBuilder extends BaseLuceneBuilder | ||||
|         String field = getLuceneFieldName(); | ||||
|         String stringValue = getValueAsString(value); | ||||
|         TypeDefinitionWrapper type = cmisDictionaryService.findType(stringValue); | ||||
|         if (type == null) | ||||
|         { | ||||
|             throw new CmisInvalidArgumentException("Unknown type: " + stringValue); | ||||
|         } | ||||
|         return lqpa | ||||
|                 .getFieldQuery(field, type.getAlfrescoClass().toString(), AnalysisMode.IDENTIFIER, luceneFunction); | ||||
|     } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <dependencies> | ||||
|   | ||||
| @@ -9,6 +9,6 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
| </project> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <properties> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <modules> | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <modules> | ||||
|   | ||||
| @@ -27,11 +27,11 @@ fi | ||||
|  | ||||
| echo "Starting ACS stack in ${DOCKER_COMPOSE_PATH}" | ||||
|  | ||||
| export TRANSFORMERS_TAG=$(mvn help:evaluate -Dexpression=dependency.alfresco-transform-core.version -q -DforceStdout) | ||||
| export TRANSFORM_ROUTER_TAG=$(mvn help:evaluate -Dexpression=dependency.alfresco-transform-service.version -q -DforceStdout) | ||||
| TRANSFORMERS_TAG=$(mvn help:evaluate -Dexpression=dependency.alfresco-transform-core.version -q -DforceStdout) | ||||
| TRANSFORM_ROUTER_TAG=$(mvn help:evaluate -Dexpression=dependency.alfresco-transform-service.version -q -DforceStdout) | ||||
|  | ||||
| # .env files are picked up from project directory correctly on docker-compose 1.23.0+ | ||||
| docker-compose --file "${DOCKER_COMPOSE_PATH}" --project-directory $(dirname "${DOCKER_COMPOSE_PATH}") up -d | ||||
| TRANSFORMERS_TAG=${TRANSFORMERS_TAG} TRANSFORM_ROUTER_TAG=${TRANSFORM_ROUTER_TAG} docker-compose --file "${DOCKER_COMPOSE_PATH}" --project-directory $(dirname "${DOCKER_COMPOSE_PATH}") up -d | ||||
|  | ||||
| if [ $? -eq 0 ] | ||||
| then | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-tests</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <developers> | ||||
|   | ||||
| @@ -1,76 +0,0 @@ | ||||
| package org.alfresco.cmis.search; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
|  | ||||
| import org.alfresco.cmis.CmisProperties; | ||||
| import org.alfresco.utility.Utility; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.annotation.Scope; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.testng.annotations.AfterMethod; | ||||
| import org.testng.annotations.BeforeMethod; | ||||
|  | ||||
| @ContextConfiguration("classpath:alfresco-cmis-context.xml") | ||||
| @Component | ||||
| @Scope(value = "prototype") | ||||
| public abstract class AbstractCmisE2ETest extends AbstractE2EFunctionalTest | ||||
| { | ||||
|     private static Logger LOGGER = LoggerFactory.getLogger(AbstractCmisE2ETest.class); | ||||
|  | ||||
|     @Autowired | ||||
|     protected CmisProperties cmisProperties; | ||||
|  | ||||
|     public String documentContent = "CMIS document content"; | ||||
|  | ||||
|     @BeforeMethod(alwaysRun = true) | ||||
|     public void showStartTestInfo(Method method) | ||||
|     { | ||||
|         LOGGER.info(String.format("*** STARTING Test: [%s] ***", method.getName())); | ||||
|     } | ||||
|  | ||||
|     @AfterMethod(alwaysRun = true) | ||||
|     public void showEndTestInfo(Method method) | ||||
|     { | ||||
|         LOGGER.info(String.format("*** ENDING Test: [%s] ***", method.getName())); | ||||
|     } | ||||
|  | ||||
|     public Integer getElasticWaitTimeInSeconds() | ||||
|     { | ||||
|         return cmisProperties.envProperty().getSolrWaitTimeInSeconds(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Repeat Elastic Query till results count returns expectedCountResults | ||||
|      * @param query CMIS Query to be executed | ||||
|      * @param expectedCountResults Number of results expected | ||||
|      * @return true when results count is equals to expectedCountResults | ||||
|      */ | ||||
|     protected boolean waitForIndexing(String query, long expectedCountResults) | ||||
|     { | ||||
|  | ||||
|         for (int searchCount = 1; searchCount <= SEARCH_MAX_ATTEMPTS; searchCount++) | ||||
|         { | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 cmisApi.withQuery(query).assertResultsCount().equals(expectedCountResults); | ||||
|                 return true; | ||||
|             } | ||||
|             catch (AssertionError ae) | ||||
|             { | ||||
|                 LOGGER.info(String.format("WaitForIndexing in Progress: %s", ae)); | ||||
|             } | ||||
|  | ||||
|  | ||||
|             Utility.waitToLoopTime(getElasticWaitTimeInSeconds(), "Wait For Indexing"); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -1,58 +0,0 @@ | ||||
| package org.alfresco.cmis.search; | ||||
|  | ||||
| import org.alfresco.cmis.CmisWrapper; | ||||
| import org.alfresco.dataprep.SiteService.Visibility; | ||||
| import org.alfresco.utility.data.DataContent; | ||||
| import org.alfresco.utility.data.DataSite; | ||||
| import org.alfresco.utility.data.DataUser; | ||||
| import org.alfresco.utility.data.RandomData; | ||||
| import org.alfresco.utility.model.SiteModel; | ||||
| import org.alfresco.utility.model.UserModel; | ||||
| import org.alfresco.utility.network.ServerHealth; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; | ||||
| import org.testng.annotations.BeforeClass; | ||||
|  | ||||
| @ContextConfiguration ("classpath:alfresco-cmis-context.xml") | ||||
| public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringContextTests | ||||
| { | ||||
|     /** The number of retries that a query will be tried before giving up. */ | ||||
|     protected static final int SEARCH_MAX_ATTEMPTS = 20; | ||||
|  | ||||
|     @Autowired | ||||
|     protected ServerHealth serverHealth; | ||||
|  | ||||
|     @Autowired | ||||
|     protected DataSite dataSite; | ||||
|  | ||||
|     @Autowired | ||||
|     protected DataContent dataContent; | ||||
|  | ||||
|     @Autowired | ||||
|     protected CmisWrapper cmisApi; | ||||
|  | ||||
|     @Autowired | ||||
|     protected DataUser dataUser; | ||||
|  | ||||
|     protected UserModel testUser, adminUserModel; | ||||
|     protected SiteModel testSite; | ||||
|  | ||||
|     protected static String unique_searchString; | ||||
|  | ||||
|     @BeforeClass (alwaysRun = true) | ||||
|     public void setup() | ||||
|     { | ||||
|         serverHealth.assertServerIsOnline(); | ||||
|  | ||||
|         adminUserModel = dataUser.getAdminUser(); | ||||
|         testUser = dataUser.createRandomTestUser("UserSearch"); | ||||
|  | ||||
|         testSite = new SiteModel(RandomData.getRandomName("SiteSearch")); | ||||
|         testSite.setVisibility(Visibility.PRIVATE); | ||||
|  | ||||
|         testSite = dataSite.usingUser(testUser).createSite(testSite); | ||||
|  | ||||
|         unique_searchString = testSite.getTitle().replace("SiteSearch", "Unique"); | ||||
|     } | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| package org.alfresco.cmis.search; | ||||
|  | ||||
| import org.alfresco.utility.Utility; | ||||
| import org.alfresco.utility.data.provider.XMLDataConfig; | ||||
| import org.alfresco.utility.data.provider.XMLTestDataProvider; | ||||
| import org.alfresco.utility.model.FileModel; | ||||
| import org.alfresco.utility.model.FileType; | ||||
| import org.alfresco.utility.model.FolderModel; | ||||
| import org.alfresco.utility.model.QueryModel; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.AfterClass; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| public class SearchInFolderTests extends AbstractCmisE2ETest | ||||
| { | ||||
|     private FolderModel parentFolder, subFolder1, subFolder2, subFolder3; | ||||
|     private FileModel subFile1, subFile2, subFile3, subFile4, subFile5; | ||||
|  | ||||
|     @BeforeClass(alwaysRun = true) | ||||
|     public void createTestData() throws Exception | ||||
|     { | ||||
|         // create input data | ||||
|         parentFolder = FolderModel.getRandomFolderModel(); | ||||
|         subFolder1 = FolderModel.getRandomFolderModel(); | ||||
|         subFolder2 = FolderModel.getRandomFolderModel(); | ||||
|         subFolder3 = new FolderModel("subFolder"); | ||||
|         subFile5 = new FileModel("fifthFile.txt",FileType.TEXT_PLAIN, "fifthFile content"); | ||||
|         subFile1 = new FileModel("firstFile", FileType.MSEXCEL); | ||||
|         subFile2 = FileModel.getRandomFileModel(FileType.MSPOWERPOINT2007); | ||||
|         subFile3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN); | ||||
|         subFile4 = new FileModel("fourthFile", "fourthFileTitle", "fourthFileDescription", FileType.MSWORD2007); | ||||
|  | ||||
|         cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder) | ||||
|                 .then().usingResource(parentFolder) | ||||
|                 .createFile(subFile5).assertThat().contentIs("fifthFile content") | ||||
|                 .createFolder(subFolder1) | ||||
|                 .createFolder(subFolder2) | ||||
|                 .createFolder(subFolder3) | ||||
|                 .createFile(subFile1) | ||||
|                 .createFile(subFile2) | ||||
|                 .createFile(subFile3) | ||||
|                 .createFile(subFile4); | ||||
|         // wait for index | ||||
|         Utility.waitToLoopTime(getElasticWaitTimeInSeconds()); | ||||
|     } | ||||
|  | ||||
|     @AfterClass(alwaysRun = true) | ||||
|     public void cleanupEnvironment() | ||||
|     { | ||||
|         dataContent.deleteSite(testSite); | ||||
|     } | ||||
|  | ||||
|     @Test(dataProviderClass = XMLTestDataProvider.class, dataProvider = "getQueriesData") | ||||
|     @XMLDataConfig(file = "src/test/resources/search-in-folder.xml") | ||||
|     public void executeCMISQuery(QueryModel query) | ||||
|     { | ||||
|         String currentQuery = String.format(query.getValue(), parentFolder.getNodeRef()); | ||||
|         cmisApi.authenticateUser(testUser); | ||||
|         Assert.assertTrue(waitForIndexing(currentQuery, query.getResults()), String.format("Result count not as expected for query: %s", currentQuery)); | ||||
|     } | ||||
| } | ||||
| @@ -7,7 +7,7 @@ alfresco.port=8082 | ||||
| admin.user=admin | ||||
| admin.password=admin | ||||
|  | ||||
| solrWaitTimeInSeconds=60 | ||||
| solrWaitTimeInSeconds=30 | ||||
|  | ||||
| # in containers we cannot access directly JMX, so we will use http://jolokia.org agent | ||||
| # disabling this we will use direct JMX calls to server | ||||
|   | ||||
| @@ -1,23 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!--CMIS Queries: passing the search query as first param and results expected --> | ||||
| <testData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> | ||||
| 	<queries> | ||||
| 		<query value="SELECT cmis:name, cmis:parentId, cmis:path, cmis:allowedChildObjectTypeIds FROM cmis:folder where IN_FOLDER('%s') AND cmis:name = 'subFolder'" expectedResults="1" /> | ||||
| 		<query value="SELECT cmis:name, cmis:objectId, cmis:lastModifiedBy, cmis:creationDate, cmis:contentStreamFileName FROM cmis:document where IN_FOLDER('%s') AND cmis:name = 'fourthFile'" expectedResults="1" /> | ||||
| 		<query value="SELECT cmis:parentId FROM cmis:folder where IN_FOLDER('%s')" expectedResults="3" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s')" expectedResults="5" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') ORDER BY cmis:name ASC" expectedResults="5" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') ORDER BY cmis:name DESC" expectedResults="5" /> | ||||
| 		<query value="SELECT * FROM cmis:folder where IN_FOLDER('%s') ORDER BY cmis:lastModificationDate ASC"  expectedResults="3" /> | ||||
| 		<query value="SELECT * FROM cmis:folder where IN_FOLDER('%s') ORDER BY cmis:lastModificationDate DESC"  expectedResults="3" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') ORDER BY cmis:createdBy DESC" expectedResults="5" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name IS NOT NULL" expectedResults="5" /> | ||||
| 		<query value="SELECT * FROM cmis:folder where IN_FOLDER('%s') AND cmis:name IS NOT NULL" expectedResults="3" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name LIKE 'fourthFile'" expectedResults="1" /> | ||||
| 		<query value="SELECT * FROM cmis:folder where IN_FOLDER('%s') AND NOT(cmis:name NOT IN ('subFolder'))" expectedResults="1" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name IN ('fourthFile', 'fifthFile.txt')" expectedResults="2" /> | ||||
| 		<query value="SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name NOT IN ('fourthFile', 'fifthFile.txt')" expectedResults="3" /> | ||||
| 		<query value="SELECT * FROM cmis:folder where IN_FOLDER('%s') AND cmis:name <> 'subFolder'" expectedResults="2" /> | ||||
| 		<query value="SELECT cmis:secondaryObjectTypeIds FROM cmis:folder where IN_FOLDER('%s') AND cmis:name = 'subFolder'" expectedResults="1" /> | ||||
| 	</queries> | ||||
| </testData>  | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-tests</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <developers> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-tests</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <developers> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-tests</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <developers> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ import org.testng.annotations.Test; | ||||
|  */ | ||||
| public class GetProcessSanityTests extends RestTest | ||||
| { | ||||
|     private UserModel userWhoStartsProcess, assignee, user; | ||||
|     private UserModel userWhoStartsProcess, assignee; | ||||
|     private RestProcessModel addedProcess, process; | ||||
|  | ||||
|     @BeforeClass(alwaysRun = true) | ||||
| @@ -24,7 +24,6 @@ public class GetProcessSanityTests extends RestTest | ||||
|     { | ||||
|         userWhoStartsProcess = dataUser.createRandomTestUser(); | ||||
|         assignee = dataUser.createRandomTestUser(); | ||||
|         user = dataUser.createRandomTestUser(); | ||||
|         addedProcess = restClient.authenticateUser(userWhoStartsProcess).withWorkflowAPI().addProcess("activitiAdhoc", assignee, false, CMISUtil.Priority.High); | ||||
|     } | ||||
|  | ||||
| @@ -60,13 +59,4 @@ public class GetProcessSanityTests extends RestTest | ||||
|         process.assertThat().field("id").is(addedProcess.getId()) | ||||
|                 .and().field("startUserId").is(addedProcess.getStartUserId()); | ||||
|     } | ||||
|  | ||||
|     @TestRail(section = { TestGroup.REST_API, TestGroup.PROCESSES }, executionType = ExecutionType.SANITY, | ||||
|             description = "Verify User that is not involved in a process cannot get that process using REST API and status code is FORBIDDEN (403)") | ||||
|     @Test(groups = { TestGroup.REST_API, TestGroup.WORKFLOW, TestGroup.PROCESSES, TestGroup.SANITY }) | ||||
|     public void shouldNotGetProcessesByNotInvolvedUser() throws Exception | ||||
|     { | ||||
|         process = restClient.authenticateUser(user).withWorkflowAPI().usingProcess(addedProcess).getProcess(); | ||||
|         restClient.assertStatusCodeIs(HttpStatus.FORBIDDEN); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-tests</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <developers> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <properties> | ||||
| @@ -144,7 +144,7 @@ | ||||
|             <plugin> | ||||
|                 <groupId>org.codehaus.mojo</groupId> | ||||
|                 <artifactId>buildnumber-maven-plugin</artifactId> | ||||
|                 <version>3.0.0</version> | ||||
|                 <version>1.4</version> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <phase>validate</phase> | ||||
|   | ||||
							
								
								
									
										60
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>alfresco-community-repo</artifactId> | ||||
|     <version>17.23</version> | ||||
|     <version>23.1.0.23-SNAPSHOT</version> | ||||
|     <packaging>pom</packaging> | ||||
|     <name>Alfresco Community Repo Parent</name> | ||||
|  | ||||
| @@ -23,11 +23,11 @@ | ||||
|     </modules> | ||||
|  | ||||
|     <properties> | ||||
|         <acs.version.major>7</acs.version.major> | ||||
|         <acs.version.minor>3</acs.version.minor> | ||||
|         <acs.version.major>23</acs.version.major> | ||||
|         <acs.version.minor>1</acs.version.minor> | ||||
|         <acs.version.revision>0</acs.version.revision> | ||||
|         <acs.version.label /> | ||||
|         <amp.min.version>${acs.version.major}.0.0</amp.min.version> | ||||
|         <amp.min.version>${acs.version.major}.1.0</amp.min.version> | ||||
|  | ||||
|         <version.edition>Community</version.edition> | ||||
|         <licenseName>community</licenseName> | ||||
| @@ -54,51 +54,51 @@ | ||||
|         <dependency.alfresco-transform-service.version>1.5.3</dependency.alfresco-transform-service.version> | ||||
|         <dependency.alfresco-transform-core.version>2.6.0</dependency.alfresco-transform-core.version> | ||||
|         <dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version> | ||||
|         <dependency.acs-event-model.version>0.0.15</dependency.acs-event-model.version> | ||||
|         <dependency.acs-event-model.version>0.0.13</dependency.acs-event-model.version> | ||||
|  | ||||
|         <dependency.spring.version>5.3.21</dependency.spring.version> | ||||
|         <dependency.spring.version>5.3.18</dependency.spring.version> | ||||
|         <dependency.antlr.version>3.5.2</dependency.antlr.version> | ||||
|         <dependency.jackson.version>2.13.3</dependency.jackson.version> | ||||
|         <dependency.jackson-databind.version>2.13.3</dependency.jackson-databind.version> | ||||
|         <dependency.cxf.version>3.5.2</dependency.cxf.version> | ||||
|         <dependency.jackson.version>2.13.1</dependency.jackson.version> | ||||
|         <dependency.jackson-databind.version>2.13.1</dependency.jackson-databind.version> | ||||
|         <dependency.cxf.version>3.5.0</dependency.cxf.version> | ||||
|         <dependency.opencmis.version>1.0.0</dependency.opencmis.version> | ||||
|         <dependency.webscripts.version>8.30</dependency.webscripts.version> | ||||
|         <dependency.webscripts.version>8.29</dependency.webscripts.version> | ||||
|         <dependency.bouncycastle.version>1.70</dependency.bouncycastle.version> | ||||
|         <dependency.mockito-core.version>3.11.2</dependency.mockito-core.version> | ||||
|         <dependency.org-json.version>20220320</dependency.org-json.version> | ||||
|         <dependency.org-json.version>20211205</dependency.org-json.version> | ||||
|         <dependency.commons-dbcp.version>2.9.0</dependency.commons-dbcp.version> | ||||
|         <dependency.commons-io.version>2.11.0</dependency.commons-io.version> | ||||
|         <dependency.gson.version>2.8.9</dependency.gson.version> | ||||
|         <dependency.gson.version>2.8.5</dependency.gson.version> | ||||
|         <dependency.httpclient.version>4.5.13</dependency.httpclient.version> | ||||
|         <dependency.httpcore.version>4.4.15</dependency.httpcore.version> | ||||
|         <dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version> | ||||
|         <dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version> | ||||
|         <dependency.slf4j.version>1.7.35</dependency.slf4j.version> | ||||
|         <dependency.gytheio.version>0.16</dependency.gytheio.version> | ||||
|         <dependency.groovy.version>3.0.11</dependency.groovy.version> | ||||
|         <dependency.groovy.version>3.0.9</dependency.groovy.version> | ||||
|         <dependency.tika.version>2.2.1</dependency.tika.version> | ||||
|         <dependency.spring-security.version>5.7.1</dependency.spring-security.version> | ||||
|         <dependency.spring-security.version>5.6.1</dependency.spring-security.version> | ||||
|         <dependency.truezip.version>7.7.10</dependency.truezip.version> | ||||
|         <dependency.poi.version>4.1.2</dependency.poi.version> | ||||
|         <dependency.ooxml-schemas.version>1.4</dependency.ooxml-schemas.version> | ||||
|         <dependency.keycloak.version>15.0.2</dependency.keycloak.version> | ||||
|         <dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version> | ||||
|         <dependency.jboss.logging.version>3.4.3.Final</dependency.jboss.logging.version> | ||||
|         <dependency.camel.version>3.15.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies (can cause dependency conflicts)--> | ||||
|         <dependency.activemq.version>5.16.1</dependency.activemq.version> | ||||
|         <dependency.apache-compress.version>1.21</dependency.apache-compress.version> | ||||
|         <dependency.apache.taglibs.version>1.2.5</dependency.apache.taglibs.version> | ||||
|         <dependency.awaitility.version>4.2.0</dependency.awaitility.version> | ||||
|         <dependency.awaitility.version>4.1.1</dependency.awaitility.version> | ||||
|         <dependency.swagger-ui.version>3.38.0</dependency.swagger-ui.version> | ||||
|         <dependency.swagger-parser.version>1.0.61</dependency.swagger-parser.version> | ||||
|         <dependency.swagger-parser.version>1.0.56</dependency.swagger-parser.version> | ||||
|         <dependency.maven-filtering.version>3.1.1</dependency.maven-filtering.version> | ||||
|         <dependency.maven-artifact.version>3.8.6</dependency.maven-artifact.version> | ||||
|         <dependency.maven-artifact.version>3.8.4</dependency.maven-artifact.version> | ||||
|         <dependency.jdom2.version>2.0.6.1</dependency.jdom2.version> | ||||
|  | ||||
|         <dependency.jakarta-jaxb-api.version>2.3.3</dependency.jakarta-jaxb-api.version> | ||||
|         <dependency.jakarta-ws-api.version>2.3.3</dependency.jakarta-ws-api.version> | ||||
|         <dependency.jakarta-soap-api.version>1.4.2</dependency.jakarta-soap-api.version> | ||||
|         <dependency.jakarta-activation-api.version>1.2.2</dependency.jakarta-activation-api.version> | ||||
|         <dependency.jakarta-annotation-api.version>2.1.1</dependency.jakarta-annotation-api.version> | ||||
|         <dependency.jakarta-annotation-api.version>1.3.5</dependency.jakarta-annotation-api.version> | ||||
|         <dependency.jakarta-transaction-api.version>1.3.3</dependency.jakarta-transaction-api.version> | ||||
|         <dependency.jakarta-jws-api.version>2.1.0</dependency.jakarta-jws-api.version> | ||||
|         <dependency.jakarta-mail-api.version>1.6.5</dependency.jakarta-mail-api.version> | ||||
| @@ -113,11 +113,11 @@ | ||||
|         <alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version> | ||||
|         <license-maven-plugin.version>2.0.1.alfresco-2</license-maven-plugin.version> | ||||
|  | ||||
|         <dependency.postgresql.version>42.4.0</dependency.postgresql.version> | ||||
|         <dependency.postgresql.version>42.3.2</dependency.postgresql.version> | ||||
|         <dependency.mysql.version>8.0.27</dependency.mysql.version> | ||||
|         <dependency.mysql-image.version>8</dependency.mysql-image.version> | ||||
|         <dependency.mariadb.version>2.7.4</dependency.mariadb.version> | ||||
|         <dependency.tas-utility.version>3.0.48</dependency.tas-utility.version> | ||||
|         <dependency.tas-utility.version>3.0.47</dependency.tas-utility.version> | ||||
|         <dependency.rest-assured.version>3.3.0</dependency.rest-assured.version> | ||||
|         <dependency.tas-restapi.version>1.80</dependency.tas-restapi.version> | ||||
|         <dependency.tas-cmis.version>1.31</dependency.tas-cmis.version> | ||||
| @@ -147,7 +147,7 @@ | ||||
|         <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection> | ||||
|         <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection> | ||||
|         <url>https://github.com/Alfresco/alfresco-community-repo</url> | ||||
|         <tag>17.23</tag> | ||||
|         <tag>HEAD</tag> | ||||
|     </scm> | ||||
|  | ||||
|     <distributionManagement> | ||||
| @@ -632,13 +632,13 @@ | ||||
|             <dependency> | ||||
|                 <groupId>com.drewnoakes</groupId> | ||||
|                 <artifactId>metadata-extractor</artifactId> | ||||
|                 <version>2.18.0</version> | ||||
|                 <version>2.16.0</version> | ||||
|             </dependency> | ||||
|             <!-- upgrade dependency from TIKA --> | ||||
|             <dependency> | ||||
|                 <groupId>com.github.junrar</groupId> | ||||
|                 <artifactId>junrar</artifactId> | ||||
|                 <version>7.5.2</version> | ||||
|                 <version>7.4.1</version> | ||||
|             </dependency> | ||||
|             <dependency> | ||||
|                 <groupId>com.github.fge</groupId> | ||||
| @@ -649,7 +649,7 @@ | ||||
|             <dependency> | ||||
|                 <groupId>org.jsoup</groupId> | ||||
|                 <artifactId>jsoup</artifactId> | ||||
|                 <version>1.15.1</version> | ||||
|                 <version>1.14.3</version> | ||||
|             </dependency> | ||||
|             <!-- upgrade dependency from TIKA --> | ||||
|             <dependency> | ||||
| @@ -728,7 +728,7 @@ | ||||
|             <dependency> | ||||
|                 <groupId>joda-time</groupId> | ||||
|                 <artifactId>joda-time</artifactId> | ||||
|                 <version>2.10.14</version> | ||||
|                 <version>2.10.13</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- provided dependencies --> | ||||
| @@ -868,7 +868,7 @@ | ||||
|             <dependency> | ||||
|                 <groupId>org.projectlombok</groupId> | ||||
|                 <artifactId>lombok</artifactId> | ||||
|                 <version>1.18.24</version> | ||||
|                 <version>1.18.22</version> | ||||
|                 <scope>provided</scope> | ||||
|             </dependency> | ||||
|         </dependencies> | ||||
| @@ -888,7 +888,7 @@ | ||||
|                 <plugin> | ||||
|                     <groupId>io.fabric8</groupId> | ||||
|                     <artifactId>docker-maven-plugin</artifactId> | ||||
|                     <version>0.40.1</version> | ||||
|                     <version>0.39.1</version> | ||||
|                 </plugin> | ||||
|                 <plugin> | ||||
|                     <artifactId>maven-surefire-plugin</artifactId> | ||||
| @@ -909,7 +909,7 @@ | ||||
|                 <plugin> | ||||
|                     <groupId>org.apache.maven.plugins</groupId> | ||||
|                     <artifactId>maven-javadoc-plugin</artifactId> | ||||
|                     <version>3.4.0</version> | ||||
|                     <version>3.3.1</version> | ||||
|                 </plugin> | ||||
|                 <plugin> | ||||
|                     <groupId>org.apache.maven.plugins</groupId> | ||||
| @@ -919,7 +919,7 @@ | ||||
|                 <plugin> | ||||
|                     <groupId>org.apache.maven.plugins</groupId> | ||||
|                     <artifactId>maven-dependency-plugin</artifactId> | ||||
|                     <version>3.3.0</version> | ||||
|                     <version>3.1.2</version> | ||||
|                 </plugin> | ||||
|                 <plugin> | ||||
|                     <artifactId>maven-assembly-plugin</artifactId> | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <dependencies> | ||||
| @@ -47,7 +47,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>org.apache.santuario</groupId> | ||||
|             <artifactId>xmlsec</artifactId> | ||||
|             <version>3.0.0</version> | ||||
|             <version>2.3.0</version> | ||||
|         </dependency> | ||||
|         <!-- newer version, see REPO-3133 --> | ||||
|         <dependency> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -390,9 +390,8 @@ public class LockInfoImpl implements Serializable, LockInfo | ||||
|         else | ||||
|         { | ||||
|             Date now = dateNow(); | ||||
|             long remainingTimeoutInSecondsRoundedUp = (Math.max(expires.getTime() - now.getTime(), 0) + 999) / 1000; | ||||
|  | ||||
|             return remainingTimeoutInSecondsRoundedUp; | ||||
|             long timeout = ((expires.getTime() - now.getTime()) / 1000); | ||||
|             return timeout; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,28 +1,28 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.webdav; | ||||
|  | ||||
| import java.util.Date; | ||||
| @@ -449,18 +449,30 @@ public class LockMethod extends WebDAVMethod | ||||
|      */ | ||||
|     protected final void createLock(FileInfo lockNode, String userName) throws WebDAVServerException | ||||
|     { | ||||
|         if (!createExclusive) { | ||||
|         // Create Lock token | ||||
|         lockToken = WebDAV.makeLockToken(lockNode.getNodeRef(), userName); | ||||
|  | ||||
|         if (createExclusive) | ||||
|         { | ||||
|             // Lock the node | ||||
|             lockInfo.setTimeoutSeconds(getLockTimeout()); | ||||
|             lockInfo.setExclusiveLockToken(lockToken); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Shared lock creation should already have been prohibited when parsing the request body | ||||
|             throw new WebDAVServerException(HttpServletResponse.SC_PRECONDITION_FAILED); | ||||
|         } | ||||
|  | ||||
|         lockToken = WebDAV.makeLockToken(lockNode.getNodeRef(), userName); | ||||
|         lockInfo.setExclusiveLockToken(lockToken); | ||||
|         // Store lock depth | ||||
|         lockInfo.setDepth(WebDAV.getDepthName(m_depth)); | ||||
|         lockInfo.setScope(WebDAV.XML_EXCLUSIVE); | ||||
|         // Store lock scope (shared/exclusive) | ||||
|         String scope = createExclusive ? WebDAV.XML_EXCLUSIVE : WebDAV.XML_SHARED; | ||||
|         lockInfo.setScope(scope); | ||||
|         // Store the owner of this lock | ||||
|         lockInfo.setOwner(userName); | ||||
|  | ||||
|         getDAVLockService().lock(lockNode.getNodeRef(), lockInfo, getLockTimeout()); | ||||
|         // Lock the node | ||||
|         getDAVLockService().lock(lockNode.getNodeRef(), lockInfo); | ||||
|          | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|   | ||||
| @@ -1,28 +1,28 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
|  | ||||
| package org.alfresco.repo.webdav; | ||||
|  | ||||
| @@ -56,9 +56,7 @@ public interface WebDAVLockService | ||||
|     void lock(NodeRef nodeRef, String userName, int timeout); | ||||
|  | ||||
|     void lock(NodeRef nodeRef, LockInfo lockInfo); | ||||
|  | ||||
|     void lock(NodeRef nodeRef, LockInfo lockInfo, int timeout); | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * Shared method for webdav/vti to unlock node. Unlocked node is automatically removed from | ||||
|      * current sessions's locked resources list. | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -32,6 +32,7 @@ import java.util.List; | ||||
| import javax.servlet.http.HttpSession; | ||||
|  | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.lock.LockUtils; | ||||
| import org.alfresco.repo.lock.mem.Lifetime; | ||||
| import org.alfresco.repo.lock.mem.LockState; | ||||
| import org.alfresco.repo.security.authentication.AuthenticationUtil; | ||||
| @@ -236,15 +237,57 @@ public class WebDAVLockServiceImpl implements WebDAVLockService | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void lock(NodeRef nodeRef, LockInfo lockInfo) { | ||||
|         int timeout = (int) lockInfo.getRemainingTimeoutSeconds(); | ||||
|         lock(nodeRef, lockInfo, timeout); | ||||
|     } | ||||
|     public void lock(NodeRef nodeRef, LockInfo lockInfo) | ||||
|     { | ||||
|         boolean performSessionBehavior = false; | ||||
|         long timeout; | ||||
|          | ||||
|         timeout = lockInfo.getRemainingTimeoutSeconds();     | ||||
|          | ||||
|         // ALF-11777 fix, do not lock node for more than 24 hours (webdav and vti) | ||||
|         if (timeout >= WebDAV.TIMEOUT_24_HOURS || timeout == WebDAV.TIMEOUT_INFINITY) | ||||
|         {    | ||||
|             timeout = WebDAV.TIMEOUT_24_HOURS; | ||||
|             lockInfo.setTimeoutSeconds((int) timeout); | ||||
|             performSessionBehavior = true; | ||||
|         } | ||||
|          | ||||
|         // TODO: lock children according to depth? lock type? | ||||
|         final String additionalInfo = lockInfo.toJSON(); | ||||
|         lockService.lock(nodeRef, LockType.WRITE_LOCK, (int) timeout, Lifetime.EPHEMERAL, additionalInfo); | ||||
|          | ||||
|  | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             logger.debug(nodeRef + " was locked for " + timeout + " seconds."); | ||||
|         } | ||||
|  | ||||
|         if (performSessionBehavior) | ||||
|         { | ||||
|             HttpSession session = currentSession.get(); | ||||
|  | ||||
|             if (session == null) | ||||
|             { | ||||
|                 if (logger.isDebugEnabled()) | ||||
|                 { | ||||
|                     logger.debug("Couldn't find current session."); | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             storeObjectInSessionList(session, LOCKED_RESOURCES, new Pair<String, NodeRef>(AuthenticationUtil.getRunAsUser(), nodeRef)); | ||||
|  | ||||
|             if (logger.isDebugEnabled()) | ||||
|             { | ||||
|                 logger.debug(nodeRef + " was added to the session " + session.getId() + " for post expiration processing."); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Shared method for webdav/vti protocols to lock node. If node is locked for more than 24 hours it is automatically added | ||||
|      * to the current session locked resources list. | ||||
|      * | ||||
|      *  | ||||
|      * @param nodeRef the node to lock | ||||
|      * @param userName userName | ||||
|      * @param timeout the number of seconds before the locks expires | ||||
| @@ -252,68 +295,8 @@ public class WebDAVLockServiceImpl implements WebDAVLockService | ||||
|     @Override | ||||
|     public void lock(NodeRef nodeRef, String userName, int timeout) | ||||
|     { | ||||
|         LockInfo lockInfo = createLock(nodeRef, userName, true); | ||||
|         lock(nodeRef, lockInfo, timeout); | ||||
|     } | ||||
|  | ||||
|     public void lock(NodeRef nodeRef, LockInfo lockInfo, int timeout) | ||||
|     { | ||||
|         // ALF-11777 fix, do not lock node for more than 24 hours (webdav and vti) | ||||
|         boolean performSessionBehavior = false; | ||||
|         if (timeout > WebDAV.TIMEOUT_24_HOURS || timeout == WebDAV.TIMEOUT_INFINITY) | ||||
|         { | ||||
|             timeout = WebDAV.TIMEOUT_24_HOURS; | ||||
|             performSessionBehavior = true; | ||||
|         } | ||||
|  | ||||
|         validateLockTimeout(timeout); | ||||
|         lockInner(nodeRef, lockInfo, timeout); | ||||
|  | ||||
|         if (performSessionBehavior) | ||||
|         { | ||||
|             performLockSessionBehavior(nodeRef); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateLockTimeout(int timeout) { | ||||
|         if (timeout != WebDAV.TIMEOUT_INFINITY && timeout == LockService.TIMEOUT_INFINITY) { | ||||
|             throw new IllegalArgumentException("Timeout == " + LockService.TIMEOUT_INFINITY + | ||||
|                     " is treated as permanence for locks. For maximum allowed timeout set " + WebDAV.TIMEOUT_INFINITY); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void lockInner(NodeRef nodeRef, LockInfo lockInfo, int timeout) { | ||||
|         //Update/set true expiry date of a lock to be used in additional information | ||||
|         lockInfo.setTimeoutSeconds(timeout); | ||||
|  | ||||
|         // TODO: lock children according to depth? lock type? | ||||
|         final String additionalInfo = lockInfo.toJSON(); | ||||
|         lockService.lock(nodeRef, LockType.WRITE_LOCK, timeout, Lifetime.EPHEMERAL, additionalInfo); | ||||
|  | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             logger.debug(nodeRef + " was locked for " + timeout + " seconds."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void performLockSessionBehavior(NodeRef nodeRef) { | ||||
|         HttpSession session = currentSession.get(); | ||||
|  | ||||
|         if (session == null) | ||||
|         { | ||||
|             if (logger.isDebugEnabled()) | ||||
|             { | ||||
|                 logger.debug("Couldn't find current session."); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         storeObjectInSessionList(session, LOCKED_RESOURCES, new Pair<String, NodeRef>(AuthenticationUtil.getRunAsUser(), nodeRef)); | ||||
|  | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             logger.debug(nodeRef + " was added to the session " + session.getId() + " for post expiration processing."); | ||||
|         } | ||||
|         LockInfo lockInfo = createLock(nodeRef, userName, true, timeout); | ||||
|         lock(nodeRef, lockInfo); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @@ -461,15 +444,19 @@ public class WebDAVLockServiceImpl implements WebDAVLockService | ||||
|      * @param nodeRef NodeRef | ||||
|      * @param userName String | ||||
|      * @param createExclusive boolean | ||||
|      * @param timeoutSecs int | ||||
|      */ | ||||
|     private LockInfo createLock(NodeRef nodeRef, String userName, boolean createExclusive) | ||||
|     private LockInfo createLock(NodeRef nodeRef, String userName, boolean createExclusive, int timeoutSecs) | ||||
|     { | ||||
|         // Create Lock token | ||||
|         String lockToken = WebDAV.makeLockToken(nodeRef, userName); | ||||
|  | ||||
|         LockInfo lockInfo = new LockInfoImpl(); | ||||
|          | ||||
|         if (createExclusive) | ||||
|         { | ||||
|             // Lock the node | ||||
|             lockInfo.setTimeoutSeconds(timeoutSecs); | ||||
|             lockInfo.setExclusiveLockToken(lockToken); | ||||
|         } | ||||
|         else | ||||
| @@ -477,11 +464,15 @@ public class WebDAVLockServiceImpl implements WebDAVLockService | ||||
|             lockInfo.addSharedLockToken(lockToken); | ||||
|         } | ||||
|  | ||||
|         // Store lock depth | ||||
|         lockInfo.setDepth(WebDAV.getDepthName(WebDAV.DEPTH_INFINITY)); | ||||
|         // Store lock scope (shared/exclusive) | ||||
|         String scope = createExclusive ? WebDAV.XML_EXCLUSIVE : WebDAV.XML_SHARED; | ||||
|         lockInfo.setScope(scope); | ||||
|         // Store the owner of this lock | ||||
|         lockInfo.setOwner(userName); | ||||
|  | ||||
|          | ||||
|         // TODO: to help with debugging/refactoring (remove later) | ||||
|         String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); | ||||
|         if (!currentUser.equals(userName)) | ||||
|         { | ||||
|   | ||||
| @@ -511,9 +511,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes | ||||
|         { | ||||
|             throw new InvalidArgumentException("processId is required to get the process info"); | ||||
|         } | ||||
|  | ||||
|         validateIfUserAllowedToWorkWithProcess(processId); | ||||
|  | ||||
|          | ||||
|         HistoricProcessInstance processInstance = activitiProcessEngine | ||||
|                 .getHistoryService() | ||||
|                 .createHistoricProcessInstanceQuery() | ||||
|   | ||||
| @@ -3,7 +3,6 @@ function main() | ||||
|  | ||||
| // Get the args | ||||
| var filter = args["filter"]; | ||||
| if (filter!==null && !filter.includes(":")) {filter += " [hint:useCQ]";} | ||||
| var maxResults = args["maxResults"]; | ||||
| var skipCountStr = args["skipCount"]; | ||||
| var skipCount = skipCountStr != null ? parseInt(skipCountStr) : -1; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ function main() | ||||
|    // Get the args | ||||
|    var siteShortName = url.templateArgs.shortname, | ||||
|       site = siteService.getSite(siteShortName), | ||||
|       filter = ((args.filter != null) ? args.filter : (args.shortNameFilter != null) ? args.shortNameFilter : "" )+ " [hint:useCQ]", | ||||
|       filter = (args.filter != null) ? args.filter : (args.shortNameFilter != null) ? args.shortNameFilter : "", | ||||
|       maxResults = (args.maxResults == null) ? 10 : parseInt(args.maxResults, 10), | ||||
|       authorityType = args.authorityType, | ||||
|       zone = args.zone, | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2020 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -35,6 +35,7 @@ import org.alfresco.util.testing.category.LuceneTests; | ||||
| import org.alfresco.util.testing.category.RedundantTests; | ||||
| import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.impl.JUnitHelper; | ||||
| import org.apache.chemistry.opencmis.tck.tests.basics.BasicsTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.control.ControlTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.crud.BulkUpdatePropertiesTest; | ||||
| import org.apache.chemistry.opencmis.tck.tests.crud.CRUDTestGroup; | ||||
| @@ -68,7 +69,7 @@ public abstract class AbstractEnterpriseOpenCMIS11TCKTest extends AbstractEnterp | ||||
|     @Test | ||||
|     public void testCMISTCKBasics() throws Exception | ||||
|     { | ||||
|         AlfrescoCMISBasicsTestGroup basicsTestGroup = new AlfrescoCMISBasicsTestGroup(); | ||||
|         BasicsTestGroup basicsTestGroup = new BasicsTestGroup(); | ||||
|         JUnitHelper.run(basicsTestGroup); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,76 +0,0 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.rest.api.tests; | ||||
|  | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import org.apache.chemistry.opencmis.client.api.CmisObject; | ||||
| import org.apache.chemistry.opencmis.client.api.Property; | ||||
| import org.apache.chemistry.opencmis.tck.CmisTestResult; | ||||
| import org.apache.chemistry.opencmis.tck.tests.basics.BasicsTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.basics.RootFolderTest; | ||||
|  | ||||
| import static org.mockito.Mockito.spy; | ||||
| import static org.mockito.Mockito.when; | ||||
|  | ||||
| class AlfrescoCMISBasicsTestGroup extends BasicsTestGroup | ||||
| { | ||||
|     @Override | ||||
|     public void init(Map<String, String> parameters) throws Exception | ||||
|     { | ||||
|         super.init(parameters); | ||||
|  | ||||
|         replaceRootFolderTest(); | ||||
|     } | ||||
|  | ||||
|     private void replaceRootFolderTest() throws Exception { | ||||
|         getTests().removeIf(t -> t instanceof RootFolderTest); | ||||
|         addTest(new RootFolderTest() | ||||
|         { | ||||
|             @Override | ||||
|             protected CmisTestResult assertEquals(CmisObject expected, CmisObject actual, CmisTestResult success, CmisTestResult failure, boolean checkAcls, boolean checkPolicies) | ||||
|             { | ||||
|                 return super.assertEquals(hideAsynchronouslyChangedProperties(expected), hideAsynchronouslyChangedProperties(actual), success, failure, checkAcls, checkPolicies); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private CmisObject hideAsynchronouslyChangedProperties(final CmisObject target) | ||||
|     { | ||||
|         CmisObject spiedObject = spy(target); | ||||
|         when(spiedObject.getProperties()).then(a -> { | ||||
|             List<Property<?>> properties = (List<Property<?>>) a.callRealMethod(); | ||||
|             return properties.stream() | ||||
|                     .filter(p -> !p.getId().startsWith("cmis:lastMod")) | ||||
|                     .collect(Collectors.toUnmodifiableList()); | ||||
|         }); | ||||
|  | ||||
|         return spiedObject; | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -27,13 +27,19 @@ package org.alfresco.rest.api.tests; | ||||
|  | ||||
| import java.text.MessageFormat; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import org.alfresco.error.AlfrescoRuntimeException; | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.opencmis.OpenCMISClientContext; | ||||
| import org.alfresco.opencmis.tck.tests.query.QueryForObjectCustom; | ||||
| import org.alfresco.opencmis.tck.tests.query.QueryInFolderTestCustom; | ||||
| import org.alfresco.opencmis.tck.tests.query.QueryLikeTestCustom; | ||||
| import org.alfresco.repo.dictionary.DictionaryDAO; | ||||
| import org.alfresco.repo.dictionary.M2Aspect; | ||||
| import org.alfresco.repo.dictionary.M2Model; | ||||
| import org.alfresco.repo.dictionary.M2Property; | ||||
| import org.alfresco.repo.model.Repository; | ||||
| import org.alfresco.repo.security.authentication.AuthenticationUtil; | ||||
| import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; | ||||
| @@ -41,8 +47,10 @@ import org.alfresco.repo.web.util.JettyComponent; | ||||
| import org.alfresco.service.cmr.model.FileFolderService; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.cmr.repository.NodeService; | ||||
| import org.alfresco.service.cmr.repository.StoreRef; | ||||
| import org.alfresco.service.cmr.search.SearchService; | ||||
| import org.alfresco.service.namespace.NamespaceService; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| import org.alfresco.service.transaction.TransactionService; | ||||
| import org.alfresco.util.testing.category.LuceneTests; | ||||
| import org.alfresco.util.testing.category.RedundantTests; | ||||
| @@ -50,11 +58,13 @@ import org.apache.chemistry.opencmis.commons.enums.BindingType; | ||||
| import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.impl.JUnitHelper; | ||||
| import org.apache.chemistry.opencmis.tck.impl.TestParameters; | ||||
| import org.apache.chemistry.opencmis.tck.tests.basics.BasicsTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.control.ControlTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.crud.CRUDTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.filing.FilingTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.query.ContentChangesSmokeTest; | ||||
| import org.apache.chemistry.opencmis.tck.tests.query.QuerySmokeTest; | ||||
| import org.apache.chemistry.opencmis.tck.tests.types.TypesTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.versioning.CheckedOutTest; | ||||
| import org.apache.chemistry.opencmis.tck.tests.versioning.VersionDeleteTest; | ||||
| import org.apache.chemistry.opencmis.tck.tests.versioning.VersioningSmokeTest; | ||||
| @@ -113,12 +123,13 @@ public class TestEnterpriseAtomPubTCK extends AbstractEnterpriseOpenCMIS10TCKTes | ||||
|         overrideVersionableAspectProperties(jetty.getApplicationContext()); | ||||
| 	} | ||||
|  | ||||
|     @Test | ||||
|     public void testCMISTCKBasics() throws Exception | ||||
|     { | ||||
|         AlfrescoCMISBasicsTestGroup basicsTestGroup = new AlfrescoCMISBasicsTestGroup(); | ||||
|         JUnitHelper.run(basicsTestGroup); | ||||
|     } | ||||
| // Commented out: See https://issues.alfresco.com/jira/browse/MNT-11123?focusedCommentId=339130&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-339130 | ||||
| //    @Test | ||||
| //    public void testCMISTCKBasics() throws Exception | ||||
| //    { | ||||
| //        BasicsTestGroup basicsTestGroup = new BasicsTestGroup(); | ||||
| //        JUnitHelper.run(basicsTestGroup); | ||||
| //    } | ||||
|      | ||||
|     @Test | ||||
|     public void testCMISTCKCRUD() throws Exception | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Remote API | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -25,6 +25,8 @@ | ||||
|  */ | ||||
| package org.alfresco.rest.api.tests; | ||||
|  | ||||
| import static org.junit.Assume.assumeFalse; | ||||
|  | ||||
| import java.text.MessageFormat; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| @@ -40,6 +42,7 @@ import org.apache.chemistry.opencmis.commons.enums.BindingType; | ||||
| import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.impl.JUnitHelper; | ||||
| import org.apache.chemistry.opencmis.tck.impl.TestParameters; | ||||
| import org.apache.chemistry.opencmis.tck.tests.basics.BasicsTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.control.ControlTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.crud.CRUDTestGroup; | ||||
| import org.apache.chemistry.opencmis.tck.tests.filing.FilingTestGroup; | ||||
| @@ -90,7 +93,7 @@ public class TestPublicApiAtomPub10TCK extends AbstractEnterpriseOpenCMIS10TCKTe | ||||
|     @Test | ||||
|     public void testCMISTCKBasics() throws Exception | ||||
|     { | ||||
|         AlfrescoCMISBasicsTestGroup basicsTestGroup = new AlfrescoCMISBasicsTestGroup(); | ||||
|         BasicsTestGroup basicsTestGroup = new BasicsTestGroup(); | ||||
|         JUnitHelper.run(basicsTestGroup); | ||||
|     } | ||||
|      | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <parent> | ||||
|         <groupId>org.alfresco</groupId> | ||||
|         <artifactId>alfresco-community-repo</artifactId> | ||||
|         <version>17.23</version> | ||||
|         <version>23.1.0.23-SNAPSHOT</version> | ||||
|     </parent> | ||||
|  | ||||
|     <dependencies> | ||||
| @@ -126,7 +126,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>com.ibm.icu</groupId> | ||||
|             <artifactId>icu4j</artifactId> | ||||
|             <version>71.1</version> | ||||
|             <version>70.1</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.googlecode.json-simple</groupId> | ||||
| @@ -236,7 +236,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>org.freemarker</groupId> | ||||
|             <artifactId>freemarker</artifactId> | ||||
|             <version>2.3.20-alfresco-patched-20220413</version> | ||||
|             <version>2.3.20-alfresco-patched-20200421</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.xmlbeans</groupId> | ||||
| @@ -265,7 +265,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>com.sun.xml.fastinfoset</groupId> | ||||
|             <artifactId>FastInfoset</artifactId> | ||||
|             <version>2.1.0</version> | ||||
|             <version>2.0.0</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.htmlparser</groupId> | ||||
| @@ -374,7 +374,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.woodstox</groupId> | ||||
|             <artifactId>woodstox-core</artifactId> | ||||
|             <version>6.2.8</version> | ||||
|             <version>6.2.7</version> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- GData --> | ||||
| @@ -413,7 +413,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>org.mybatis</groupId> | ||||
|             <artifactId>mybatis</artifactId> | ||||
|             <version>3.5.10</version> | ||||
|             <version>3.5.9</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.mybatis</groupId> | ||||
| @@ -800,7 +800,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>org.aspectj</groupId> | ||||
|             <artifactId>aspectjrt</artifactId> | ||||
|             <version>1.9.9.1</version> | ||||
|             <version>1.9.7</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>commons-net</groupId> | ||||
|   | ||||
| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.action; | ||||
|  | ||||
| import java.util.Objects; | ||||
|  | ||||
| /** | ||||
|  * Instances of this class are responsible for holding an action id with additional data used to identify the action's | ||||
|  * execution context like: | ||||
|  * <ul> | ||||
|  *     <li>REST API</li> | ||||
|  *     <li>rules execution</li> | ||||
|  *     <li>...</li> | ||||
|  * </ul> | ||||
|  */ | ||||
| public class ActionExecutionContext | ||||
| { | ||||
|     private final String actionId; | ||||
|     private final String executionSource; | ||||
|  | ||||
|     private ActionExecutionContext(String actionId, String executionSource) | ||||
|     { | ||||
|         this.actionId = actionId; | ||||
|         this.executionSource = executionSource; | ||||
|     } | ||||
|  | ||||
|     String getActionId() | ||||
|     { | ||||
|         return actionId; | ||||
|     } | ||||
|  | ||||
|     String getExecutionSource() | ||||
|     { | ||||
|         return executionSource; | ||||
|     } | ||||
|  | ||||
|     boolean isExecutionSourceKnown() | ||||
|     { | ||||
|         return Objects.nonNull(executionSource); | ||||
|     } | ||||
|  | ||||
|     public static Builder builder(final String actionId) | ||||
|     { | ||||
|         Objects.requireNonNull(actionId); | ||||
|         return new Builder(actionId); | ||||
|     } | ||||
|  | ||||
|     public static class Builder | ||||
|     { | ||||
|         private final String actionId; | ||||
|         private String executionSource; | ||||
|  | ||||
|         private Builder(String actionId) | ||||
|         { | ||||
|             this.actionId = actionId; | ||||
|         } | ||||
|  | ||||
|         public ActionExecutionContext build() | ||||
|         { | ||||
|             return new ActionExecutionContext(actionId, executionSource); | ||||
|         } | ||||
|  | ||||
|         public Builder withExecutionSource(final String executionSource) | ||||
|         { | ||||
|             Objects.requireNonNull(executionSource); | ||||
|             this.executionSource = executionSource; | ||||
|             return this; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2020 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -33,7 +33,14 @@ import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Objects; | ||||
| import java.util.Optional; | ||||
| import java.util.Properties; | ||||
| import java.util.Set; | ||||
| import java.util.function.Function; | ||||
| import java.util.function.Predicate; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
|  | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.action.evaluator.ActionConditionEvaluator; | ||||
| @@ -120,6 +127,8 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A | ||||
|     private ActionTrackingService actionTrackingService; | ||||
|     private PolicyComponent policyComponent; | ||||
|     private ActionServiceMonitor monitor; | ||||
|     private Properties configProperties; | ||||
|     private ActionExecutionValidator actionExecutionValidator; | ||||
|  | ||||
|     /** | ||||
|      * The asynchronous action execution queues map of name, queue | ||||
| @@ -236,7 +245,17 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A | ||||
|     { | ||||
|         this.asynchronousActionExecutionQueues = asynchronousActionExecutionQueues; | ||||
|     } | ||||
|      | ||||
|  | ||||
|     public void setConfigurationProperties(Properties properties) | ||||
|     { | ||||
|         this.configProperties = properties; | ||||
|     } | ||||
|  | ||||
|     protected Properties getConfigurationProperties() | ||||
|     { | ||||
|         return configProperties; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method registers an {@link AsynchronousActionExecutionQueue} with the {@link ActionService}. | ||||
|      * @param key String | ||||
| @@ -256,6 +275,11 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A | ||||
|                     ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "getCopyCallback")); | ||||
|         this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"), | ||||
|                     ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "onCopyComplete")); | ||||
|         if (configProperties == null) | ||||
|         { | ||||
|             configProperties = applicationContext.getBean("global-properties", Properties.class); | ||||
|         } | ||||
|         actionExecutionValidator = new ActionExecutionValidator(configProperties::getProperty, actionDefinitions::containsKey); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -1870,5 +1894,58 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A | ||||
|         LoggingAwareExecuter executer = (LoggingAwareExecuter) this.applicationContext.getBean(action.getActionDefinitionName()); | ||||
|         return executer.onLogException(logger,t, message); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     @Override | ||||
|     public boolean isExposed(ActionExecutionContext actionExecutionContext) | ||||
|     { | ||||
|         return actionExecutionValidator.isExposed(actionExecutionContext); | ||||
|     } | ||||
|  | ||||
|     static class ActionExecutionValidator | ||||
|     { | ||||
|         private final Function<String, String> config; | ||||
|         private final Predicate<String> isPublic; | ||||
|  | ||||
|         ActionExecutionValidator(Function<String, String> config, Predicate<String> isPublic) | ||||
|         { | ||||
|             this.config = Objects.requireNonNull(config); | ||||
|             this.isPublic = Objects.requireNonNull(isPublic); | ||||
|         } | ||||
|  | ||||
|         boolean isExposed(ActionExecutionContext actionExecutionContext) | ||||
|         { | ||||
|             Objects.requireNonNull(actionExecutionContext); | ||||
|             return isExposedInConfig(actionExecutionContext).orElseGet(() -> isPublic(actionExecutionContext)); | ||||
|         } | ||||
|  | ||||
|         private Optional<Boolean> isExposedInConfig(ActionExecutionContext actionExecutionContext) | ||||
|         { | ||||
|             return getConfigKeys(actionExecutionContext). | ||||
|                     map(config). | ||||
|                     filter(Objects::nonNull). | ||||
|                     map(Boolean::parseBoolean). | ||||
|                     findFirst(); | ||||
|         } | ||||
|  | ||||
|         private Boolean isPublic(ActionExecutionContext actionExecutionContext) | ||||
|         { | ||||
|             return isPublic.test(actionExecutionContext.getActionId()); | ||||
|         } | ||||
|  | ||||
|         private static Stream<String> getConfigKeys(ActionExecutionContext actionExecutionContext) | ||||
|         { | ||||
|             if (actionExecutionContext.isExecutionSourceKnown()) | ||||
|             { | ||||
|                 return Stream.of( | ||||
|                         getConfigKey(actionExecutionContext.getExecutionSource(), actionExecutionContext.getActionId()), | ||||
|                         getConfigKey(actionExecutionContext.getActionId())); | ||||
|             } | ||||
|             return Stream.of(getConfigKey(actionExecutionContext.getActionId())); | ||||
|         } | ||||
|  | ||||
|         static String getConfigKey(String... parts) | ||||
|         { | ||||
|             return Stream.of(parts).collect(Collectors.joining(".", "org.alfresco.repo.action.", ".exposed")); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2016 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -125,4 +125,14 @@ public interface RuntimeActionService | ||||
|      * @return true if it was handled, false for default handling | ||||
|      */ | ||||
|     public boolean onLogException(Action action, Log logger, Throwable t, String message); | ||||
|  | ||||
|     /** | ||||
|      * Allows you to check if an action can be executed/used in a given execution context | ||||
|      * @param actionExecutionContext describes action and its execution context | ||||
|      * @return true if action can be executed, false otherwise | ||||
|      */ | ||||
|     default boolean isExposed(ActionExecutionContext actionExecutionContext) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -23,100 +23,100 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||
| 
 | ||||
| import org.alfresco.error.AlfrescoRuntimeException; | ||||
| import org.alfresco.repo.action.ParameterDefinitionImpl; | ||||
| import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; | ||||
| import org.alfresco.repo.action.executer.TestModeable; | ||||
| import org.alfresco.service.cmr.action.Action; | ||||
| import org.alfresco.service.cmr.action.ParameterDefinition; | ||||
| import org.alfresco.service.cmr.dictionary.DataTypeDefinition; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| 
 | ||||
| public class ErrorProneActionExecutor extends ActionExecuterAbstractBase | ||||
|                                 implements InitializingBean, TestModeable | ||||
| { | ||||
|     private static Log logger = LogFactory.getLog(ErrorProneActionExecutor.class); | ||||
| 
 | ||||
|     public static final String PARAM_FAILING_PERSON_NODEREF = "failingPersonNodeRef"; | ||||
|     public static final String PARAM_PERSON_NODEREF = "personNodeRef"; | ||||
|     public static final String PARAM_USERNAME = "userName"; | ||||
| 
 | ||||
|     public static final String NAME = "errorProneActionExecutor"; | ||||
| 
 | ||||
|     // count of number of successful notifications | ||||
| 	private AtomicInteger numSuccessful = new AtomicInteger(); | ||||
| 	 | ||||
|     // count of number of failed notifications | ||||
| 	private AtomicInteger numFailed = new AtomicInteger(); | ||||
|      | ||||
| 	public int getNumSuccess() | ||||
| 	{ | ||||
| 		return numSuccessful.get(); | ||||
| 	} | ||||
| 	 | ||||
| 	public int getNumFailed() | ||||
| 	{ | ||||
| 		return numFailed.get(); | ||||
| 	} | ||||
| 
 | ||||
|     /** | ||||
|      * Send an email message | ||||
|      *  | ||||
|      * @throws AlfrescoRuntimeException | ||||
|      */ | ||||
|     @Override | ||||
|     protected void executeImpl( | ||||
|             final Action ruleAction, | ||||
|             final NodeRef actionedUponNodeRef)  | ||||
|     { | ||||
| 		NodeRef failingPersonNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_FAILING_PERSON_NODEREF); | ||||
| 		NodeRef personNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_PERSON_NODEREF); | ||||
| 		String userName = (String)ruleAction.getParameterValue(PARAM_USERNAME); | ||||
| 
 | ||||
| 		System.out.println("userName = " + userName); | ||||
| 
 | ||||
| 		if(personNodeRef.equals(failingPersonNodeRef)) | ||||
| 		{ | ||||
| 			numFailed.incrementAndGet(); | ||||
| 			throw new AlfrescoRuntimeException(""); | ||||
| 		} | ||||
| 
 | ||||
| 		numSuccessful.incrementAndGet(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Add the parameter definitions | ||||
|      */ | ||||
|     @Override | ||||
|     protected void addParameterDefinitions(List<ParameterDefinition> paramList)  | ||||
|     { | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_FAILING_PERSON_NODEREF, DataTypeDefinition.NODE_REF, true, "Failing Person NodeRef")); | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_PERSON_NODEREF, DataTypeDefinition.NODE_REF, true, "Person NodeRef")); | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_USERNAME, DataTypeDefinition.TEXT, true, "Username")); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	public boolean isTestMode() | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void setTestMode(boolean testMode) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void afterPropertiesSet() throws Exception | ||||
| 	{ | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||
| 
 | ||||
| import org.alfresco.error.AlfrescoRuntimeException; | ||||
| import org.alfresco.repo.action.ParameterDefinitionImpl; | ||||
| import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; | ||||
| import org.alfresco.repo.action.executer.TestModeable; | ||||
| import org.alfresco.service.cmr.action.Action; | ||||
| import org.alfresco.service.cmr.action.ParameterDefinition; | ||||
| import org.alfresco.service.cmr.dictionary.DataTypeDefinition; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| 
 | ||||
| public class ErrorProneActionExecutor extends ActionExecuterAbstractBase | ||||
|                                 implements InitializingBean, TestModeable | ||||
| { | ||||
|     private static Log logger = LogFactory.getLog(ErrorProneActionExecutor.class); | ||||
| 
 | ||||
|     public static final String PARAM_FAILING_PERSON_NODEREF = "failingPersonNodeRef"; | ||||
|     public static final String PARAM_PERSON_NODEREF = "personNodeRef"; | ||||
|     public static final String PARAM_USERNAME = "userName"; | ||||
| 
 | ||||
|     public static final String NAME = "errorProneActionExecutor"; | ||||
| 
 | ||||
|     // count of number of successful notifications | ||||
| 	private AtomicInteger numSuccessful = new AtomicInteger(); | ||||
| 	 | ||||
|     // count of number of failed notifications | ||||
| 	private AtomicInteger numFailed = new AtomicInteger(); | ||||
|      | ||||
| 	public int getNumSuccess() | ||||
| 	{ | ||||
| 		return numSuccessful.get(); | ||||
| 	} | ||||
| 	 | ||||
| 	public int getNumFailed() | ||||
| 	{ | ||||
| 		return numFailed.get(); | ||||
| 	} | ||||
| 
 | ||||
|     /** | ||||
|      * Send an email message | ||||
|      *  | ||||
|      * @throws AlfrescoRuntimeException | ||||
|      */ | ||||
|     @Override | ||||
|     protected void executeImpl( | ||||
|             final Action ruleAction, | ||||
|             final NodeRef actionedUponNodeRef)  | ||||
|     { | ||||
| 		NodeRef failingPersonNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_FAILING_PERSON_NODEREF); | ||||
| 		NodeRef personNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_PERSON_NODEREF); | ||||
| 		String userName = (String)ruleAction.getParameterValue(PARAM_USERNAME); | ||||
| 
 | ||||
| 		System.out.println("userName = " + userName); | ||||
| 
 | ||||
| 		if(personNodeRef.equals(failingPersonNodeRef)) | ||||
| 		{ | ||||
| 			numFailed.incrementAndGet(); | ||||
| 			throw new AlfrescoRuntimeException(""); | ||||
| 		} | ||||
| 
 | ||||
| 		numSuccessful.incrementAndGet(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Add the parameter definitions | ||||
|      */ | ||||
|     @Override | ||||
|     protected void addParameterDefinitions(List<ParameterDefinition> paramList)  | ||||
|     { | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_FAILING_PERSON_NODEREF, DataTypeDefinition.NODE_REF, true, "Failing Person NodeRef")); | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_PERSON_NODEREF, DataTypeDefinition.NODE_REF, true, "Person NodeRef")); | ||||
|         paramList.add(new ParameterDefinitionImpl(PARAM_USERNAME, DataTypeDefinition.TEXT, true, "Username")); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	public boolean isTestMode() | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void setTestMode(boolean testMode) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void afterPropertiesSet() throws Exception | ||||
| 	{ | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -23,72 +23,96 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.service.cmr.action.Action; | ||||
| import org.alfresco.service.cmr.action.ActionService; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| 
 | ||||
| public class ErrorProneUserNotifier extends AbstractUserNotifier | ||||
| { | ||||
| 
 | ||||
| 	private NodeRef failingPersonNodeRef; | ||||
| 	private ActionService actionService; | ||||
| 
 | ||||
| 	public ErrorProneUserNotifier(NodeRef failingPersonNodeRef) | ||||
| 	{ | ||||
| 		this.failingPersonNodeRef = failingPersonNodeRef; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setActionService(ActionService actionService) | ||||
| 	{ | ||||
| 		this.actionService = actionService; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected boolean skipUser(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Long getFeedId(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef); | ||||
| 
 | ||||
| 		// where did we get up to ? | ||||
| 		Long emailFeedDBID = (Long)personProps.get(ContentModel.PROP_EMAIL_FEED_ID); | ||||
| 		if (emailFeedDBID != null) | ||||
| 		{ | ||||
| 			// increment min feed id | ||||
| 			emailFeedDBID++; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			emailFeedDBID = -1L; | ||||
| 		} | ||||
| 		 | ||||
| 		return emailFeedDBID; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void notifyUser(NodeRef personNodeRef, String subjectText, Object[] subjectParams, | ||||
| 			Map<String, Object> model, String templateNodeRef) | ||||
| 	{ | ||||
| 
 | ||||
| 		String userName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); | ||||
| 
 | ||||
|         Action action = actionService.createAction(ErrorProneActionExecutor.NAME); | ||||
| 
 | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_FAILING_PERSON_NODEREF, failingPersonNodeRef); | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_PERSON_NODEREF, personNodeRef); | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_USERNAME, userName); | ||||
| 
 | ||||
|         actionService.executeAction(action, null); | ||||
| 	} | ||||
| } | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.service.cmr.action.Action; | ||||
| import org.alfresco.service.cmr.action.ActionService; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| 
 | ||||
| public class ErrorProneUserNotifier extends AbstractUserNotifier | ||||
| { | ||||
| //	private AtomicInteger numSuccessful = new AtomicInteger(); | ||||
| //	private AtomicInteger numFailed = new AtomicInteger(); | ||||
| 
 | ||||
| 	private NodeRef failingPersonNodeRef; | ||||
| 	private ActionService actionService; | ||||
| 
 | ||||
| 	public ErrorProneUserNotifier(NodeRef failingPersonNodeRef) | ||||
| 	{ | ||||
| 		this.failingPersonNodeRef = failingPersonNodeRef; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setActionService(ActionService actionService) | ||||
| 	{ | ||||
| 		this.actionService = actionService; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected boolean skipUser(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Long getFeedId(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef); | ||||
| 
 | ||||
| 		// where did we get up to ? | ||||
| 		Long emailFeedDBID = (Long)personProps.get(ContentModel.PROP_EMAIL_FEED_ID); | ||||
| 		if (emailFeedDBID != null) | ||||
| 		{ | ||||
| 			// increment min feed id | ||||
| 			emailFeedDBID++; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			emailFeedDBID = -1L; | ||||
| 		} | ||||
| 		 | ||||
| 		return emailFeedDBID; | ||||
| 	} | ||||
| 
 | ||||
| //	public int getNumSuccess() | ||||
| //	{ | ||||
| //		return numSuccessful.get(); | ||||
| //	} | ||||
| //	 | ||||
| //	public int getNumFailed() | ||||
| //	{ | ||||
| //		return numFailed.get(); | ||||
| //	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void notifyUser(NodeRef personNodeRef, String subjectText, Object[] subjectParams, | ||||
| 			Map<String, Object> model, String templateNodeRef) | ||||
| 	{ | ||||
| //		super.notifyUser(personNodeRef, subjectText, model, templateNodeRef); | ||||
| 
 | ||||
| 		String userName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); | ||||
| 
 | ||||
|         Action action = actionService.createAction(ErrorProneActionExecutor.NAME); | ||||
| 
 | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_FAILING_PERSON_NODEREF, failingPersonNodeRef); | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_PERSON_NODEREF, personNodeRef); | ||||
|         action.setParameterValue(ErrorProneActionExecutor.PARAM_USERNAME, userName); | ||||
| 
 | ||||
|         actionService.executeAction(action, null); | ||||
| //		String userName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); | ||||
| // | ||||
| //		System.out.println("userName = " + userName); | ||||
| // | ||||
| //		if(personNodeRef.equals(failingPersonNodeRef)) | ||||
| //		{ | ||||
| //			numFailed.incrementAndGet(); | ||||
| //			throw new AlfrescoRuntimeException(""); | ||||
| //		} | ||||
| // | ||||
| //		numSuccessful.incrementAndGet(); | ||||
| 	} | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -23,95 +23,95 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.BitSet; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||
| 
 | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| 
 | ||||
| /** | ||||
|  * A test user notifier. | ||||
|  * | ||||
|  * @since 4.0 | ||||
|  */ | ||||
| public class MockUserNotifier extends AbstractUserNotifier | ||||
| { | ||||
|     /** | ||||
|      * Default alfresco installation url | ||||
|      */ | ||||
| 	private BitSet notifiedPersonsTracker = new BitSet(); | ||||
|     private AtomicInteger count = new AtomicInteger(0); | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected boolean skipUser(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Long getFeedId(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef); | ||||
| 
 | ||||
| 		// where did we get up to ? | ||||
| 		Long emailFeedDBID = (Long)personProps.get(ContentModel.PROP_EMAIL_FEED_ID); | ||||
| 		if (emailFeedDBID != null) | ||||
| 		{ | ||||
| 			// increment min feed id | ||||
| 			emailFeedDBID++; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			emailFeedDBID = -1L; | ||||
| 		} | ||||
| 		 | ||||
| 		return emailFeedDBID; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void notifyUser(NodeRef personNodeRef, String subjectText, Object[] subjectParams, Map<String, Object> model, String templateNodeRef) | ||||
| 	{ | ||||
| 		String username = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); | ||||
| 		if(username.startsWith("user")) | ||||
| 		{ | ||||
| 			int id = Integer.parseInt(username.substring(4)); | ||||
| 
 | ||||
| 			boolean b = false; | ||||
| 			synchronized(notifiedPersonsTracker) | ||||
| 			{ | ||||
| 				b = notifiedPersonsTracker.get(id); | ||||
| 			} | ||||
| 			if(b) | ||||
| 			{ | ||||
| 				System.out.println("Already set: " + id); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				synchronized(notifiedPersonsTracker) | ||||
| 				{ | ||||
| 					notifiedPersonsTracker.set(id); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		count.incrementAndGet(); | ||||
| 	} | ||||
| 	 | ||||
| 	public int countNotifications() | ||||
| 	{ | ||||
| 		return count.get();		 | ||||
| 	} | ||||
| 	 | ||||
| 	public int nextUserId() | ||||
| 	{ | ||||
| 		synchronized(notifiedPersonsTracker) | ||||
| 		{ | ||||
| 			return notifiedPersonsTracker.nextClearBit(1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| package org.alfresco.repo.activities.feed; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.BitSet; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||
| 
 | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| 
 | ||||
| /** | ||||
|  * A test user notifier. | ||||
|  * | ||||
|  * @since 4.0 | ||||
|  */ | ||||
| public class MockUserNotifier extends AbstractUserNotifier | ||||
| { | ||||
|     /** | ||||
|      * Default alfresco installation url | ||||
|      */ | ||||
| 	private BitSet notifiedPersonsTracker = new BitSet(); | ||||
|     private AtomicInteger count = new AtomicInteger(0); | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected boolean skipUser(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Long getFeedId(NodeRef personNodeRef) | ||||
| 	{ | ||||
| 		Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef); | ||||
| 
 | ||||
| 		// where did we get up to ? | ||||
| 		Long emailFeedDBID = (Long)personProps.get(ContentModel.PROP_EMAIL_FEED_ID); | ||||
| 		if (emailFeedDBID != null) | ||||
| 		{ | ||||
| 			// increment min feed id | ||||
| 			emailFeedDBID++; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			emailFeedDBID = -1L; | ||||
| 		} | ||||
| 		 | ||||
| 		return emailFeedDBID; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void notifyUser(NodeRef personNodeRef, String subjectText, Object[] subjectParams, Map<String, Object> model, String templateNodeRef) | ||||
| 	{ | ||||
| 		String username = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); | ||||
| 		if(username.startsWith("user")) | ||||
| 		{ | ||||
| 			int id = Integer.parseInt(username.substring(4)); | ||||
| 
 | ||||
| 			boolean b = false; | ||||
| 			synchronized(notifiedPersonsTracker) | ||||
| 			{ | ||||
| 				b = notifiedPersonsTracker.get(id); | ||||
| 			} | ||||
| 			if(b) | ||||
| 			{ | ||||
| 				System.out.println("Already set: " + id); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				synchronized(notifiedPersonsTracker) | ||||
| 				{ | ||||
| 					notifiedPersonsTracker.set(id); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		count.incrementAndGet(); | ||||
| 	} | ||||
| 	 | ||||
| 	public int countNotifications() | ||||
| 	{ | ||||
| 		return count.get();		 | ||||
| 	} | ||||
| 	 | ||||
| 	public int nextUserId() | ||||
| 	{ | ||||
| 		synchronized(notifiedPersonsTracker) | ||||
| 		{ | ||||
| 			return notifiedPersonsTracker.nextClearBit(1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * Copyright (C) 2019-2022 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software. | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of | ||||
|   | ||||
| @@ -91,7 +91,7 @@ public class EventGeneratorQueue implements InitializingBean | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 LOGGER.error("Unexpected error while enqueuing maker function for repository event" + e); | ||||
|                 LOGGER.error("Unexpected error while enqueuing maker function for repository event", e); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| @@ -122,7 +122,7 @@ public class EventGeneratorQueue implements InitializingBean | ||||
|                         } | ||||
|                         catch (Exception e) | ||||
|                         { | ||||
|                             LOGGER.error("Unexpected error while dequeuing and sending repository event" + e); | ||||
|                             LOGGER.error("Unexpected error while dequeuing and sending repository event", e); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2018 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -321,7 +321,7 @@ public class LockServiceImpl implements LockService, | ||||
|     public void lock(NodeRef nodeRef, LockType lockType) | ||||
|     { | ||||
|         // Lock with no expiration | ||||
|         lock(nodeRef, lockType, TIMEOUT_INFINITY); | ||||
|         lock(nodeRef, lockType, 0); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -371,8 +371,16 @@ public class LockServiceImpl implements LockService, | ||||
|     public void lock(NodeRef nodeRef, LockType lockType, int timeToExpire, Lifetime lifetime, String additionalInfo) | ||||
|     { | ||||
|         invokeBeforeLock(nodeRef, lockType); | ||||
|         validateTimeToExpire(timeToExpire, lifetime); | ||||
|         lifetime = switchLifetimeMode(timeToExpire, lifetime); | ||||
|         if (lifetime.equals(Lifetime.EPHEMERAL) && (timeToExpire > MAX_EPHEMERAL_LOCK_SECONDS)) | ||||
|         { | ||||
|             throw new IllegalArgumentException("Attempt to create ephemeral lock for " + | ||||
|                     timeToExpire + " seconds - exceeds maximum allowed time."); | ||||
|         } | ||||
|         if (lifetime.equals(Lifetime.EPHEMERAL) && (timeToExpire > ephemeralExpiryThreshold)) | ||||
|         { | ||||
|             lifetime = Lifetime.PERSISTENT; | ||||
|         } | ||||
|           | ||||
|          | ||||
|         nodeRef = tenantService.getName(nodeRef); | ||||
|          | ||||
| @@ -434,22 +442,6 @@ public class LockServiceImpl implements LockService, | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateTimeToExpire(int timeToExpire, Lifetime lifetime) { | ||||
|         if (lifetime.equals(Lifetime.EPHEMERAL) && (timeToExpire > MAX_EPHEMERAL_LOCK_SECONDS)) | ||||
|         { | ||||
|             throw new IllegalArgumentException("Attempt to create ephemeral lock for " + | ||||
|                     timeToExpire + " seconds - exceeds maximum allowed time."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Lifetime switchLifetimeMode(int timeToExpire, Lifetime lifetime) { | ||||
|         if (lifetime.equals(Lifetime.EPHEMERAL) && (timeToExpire > ephemeralExpiryThreshold)) | ||||
|         { | ||||
|             return Lifetime.PERSISTENT; | ||||
|         } | ||||
|         return lifetime; | ||||
|     } | ||||
|      | ||||
|     private void persistLockProps(NodeRef nodeRef, LockType lockType, Lifetime lifetime, String userName, Date expiryDate, String additionalInfo) | ||||
|     {   | ||||
| @@ -476,16 +468,16 @@ public class LockServiceImpl implements LockService, | ||||
|      */ | ||||
|     private Date makeExpiryDate(int timeToExpire) | ||||
|     { | ||||
|         boolean permanent = timeToExpire <= TIMEOUT_INFINITY; | ||||
|         if (permanent) { | ||||
|             return null; | ||||
|         // Set the expiry date | ||||
|         Date expiryDate = null; | ||||
|         if (timeToExpire > 0) | ||||
|         { | ||||
|             expiryDate = new Date(); | ||||
|             Calendar calendar = Calendar.getInstance(); | ||||
|             calendar.setTime(expiryDate); | ||||
|             calendar.add(Calendar.SECOND, timeToExpire); | ||||
|             expiryDate = calendar.getTime(); | ||||
|         } | ||||
|  | ||||
|         Calendar calendar = Calendar.getInstance(); | ||||
|         calendar.setTime(new Date()); | ||||
|         calendar.add(Calendar.SECOND, timeToExpire); | ||||
|         Date expiryDate = calendar.getTime(); | ||||
|  | ||||
|         return expiryDate; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -369,7 +369,7 @@ public class RenditionDefinitionRegistry2Impl implements RenditionDefinitionRegi | ||||
|             renditionNamesWithMaxSize = data.renditionsFor.get(sourceMimetype); | ||||
|             if (renditionNamesWithMaxSize == null) | ||||
|             { | ||||
|                 renditionNamesWithMaxSize = getRenditionNamesWithMaxSize(data, sourceMimetype); | ||||
|                 renditionNamesWithMaxSize = getRenditionNamesWithMaxSize(sourceMimetype); | ||||
|                 data.renditionsFor.put(sourceMimetype, renditionNamesWithMaxSize); | ||||
|             } | ||||
|         } | ||||
| @@ -394,9 +394,10 @@ public class RenditionDefinitionRegistry2Impl implements RenditionDefinitionRegi | ||||
|  | ||||
|     // Gets a list of rendition names that can be created from the given sourceMimetype. | ||||
|     // Includes the maxSize for each. | ||||
|     private Set<Pair<String,Long>> getRenditionNamesWithMaxSize(Data data, String sourceMimetype) | ||||
|     private Set<Pair<String,Long>> getRenditionNamesWithMaxSize(String sourceMimetype) | ||||
|     { | ||||
|         Set<Pair<String,Long>> renditions = new HashSet(); | ||||
|         Data data = getData(); | ||||
|         for (Map.Entry<String, RenditionDefinition2> entry : data.renditionDefinitions.entrySet()) | ||||
|         { | ||||
|             RenditionDefinition2 renditionDefinition2 = entry.getValue(); | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -23,7 +23,7 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.search.impl; | ||||
| package org.alfresco.repo.search.impl.solr; | ||||
| 
 | ||||
| import org.alfresco.opencmis.dictionary.CMISDictionaryService; | ||||
| import org.alfresco.opencmis.search.CMISQueryOptions; | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -23,7 +23,7 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.search.impl; | ||||
| package org.alfresco.repo.search.impl.solr; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| @@ -36,7 +36,6 @@ import org.alfresco.repo.domain.solr.SearchDAO; | ||||
| import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryLanguage; | ||||
| import org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI; | ||||
| import org.alfresco.repo.search.impl.querymodel.QueryModelException; | ||||
| import org.alfresco.repo.search.impl.solr.SolrJSONResultSet; | ||||
| import org.alfresco.repo.search.results.ChildAssocRefResultSet; | ||||
| import org.alfresco.repo.solr.NodeParameters; | ||||
| import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||
| @@ -62,16 +61,12 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|     LuceneQueryLanguageSPI indexQueryLanguage; | ||||
|      | ||||
|     QueryConsistency queryConsistency = QueryConsistency.DEFAULT; | ||||
|     QueryConsistency solrQueryConsistency = null; // Deprecated | ||||
|      | ||||
|     private NodeService nodeService; | ||||
|      | ||||
|     private SearchDAO searchDao; | ||||
|      | ||||
|     private Boolean hybridEnabled; | ||||
|     private Boolean solrHybridEnabled; // Deprecated | ||||
| 
 | ||||
|     private String subsystemName; | ||||
|     private boolean hybridEnabled; | ||||
|      | ||||
|     /** | ||||
|      * @param dbQueryLanguage the dbQueryLanguage to set | ||||
| @@ -97,12 +92,6 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|         this.queryConsistency = queryConsistency; | ||||
|     } | ||||
| 
 | ||||
|     // Deprecated | ||||
|     public void setSolrQueryConsistency(QueryConsistency solrQueryConsistency) | ||||
|     { | ||||
|         this.solrQueryConsistency = solrQueryConsistency; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param nodeService the nodeService to set | ||||
|      */ | ||||
| @@ -116,35 +105,17 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|         this.searchDao = searchDao; | ||||
|     } | ||||
| 
 | ||||
|     public void setHybridEnabled(Boolean hybridEnabled) | ||||
|     public void setHybridEnabled(boolean hybridEnabled) | ||||
|     { | ||||
|         this.hybridEnabled = hybridEnabled; | ||||
|     } | ||||
| 
 | ||||
|     // Deprecated | ||||
|     public void setSolrHybridEnabled(Boolean solrHybridEnabled) | ||||
|     { | ||||
|         this.solrHybridEnabled = solrHybridEnabled; | ||||
|     } | ||||
| 
 | ||||
|     public void setSubsystemName(String subsystemName) | ||||
|     { | ||||
|         this.subsystemName = subsystemName; | ||||
|     } | ||||
| 
 | ||||
|     public ResultSet executeQuery(SearchParameters searchParameters) | ||||
|     { | ||||
|         QueryConsistency consistency = searchParameters.getQueryConsistency(); | ||||
|         if(consistency == QueryConsistency.DEFAULT) | ||||
|         { | ||||
|             if(solrQueryConsistency != null) | ||||
|             { | ||||
|                 consistency = solrQueryConsistency; | ||||
|             } | ||||
|             else  | ||||
|             { | ||||
|                 consistency = queryConsistency; | ||||
|             } | ||||
|             consistency = queryConsistency; | ||||
|         } | ||||
|   | ||||
|         switch(consistency) | ||||
| @@ -154,7 +125,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|             { | ||||
|                 if(logger.isDebugEnabled()) | ||||
|                 { | ||||
|                     logger.debug("Using "+subsystemName+" query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|                     logger.debug("Using SOLR query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|                 } | ||||
|                 StopWatch stopWatch = new StopWatch("index only"); | ||||
|                 stopWatch.start(); | ||||
| @@ -162,7 +133,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|                 stopWatch.stop(); | ||||
|                 if (logger.isDebugEnabled()) | ||||
|                 { | ||||
|                     logger.debug(subsystemName+" returned " + results.length() + " results in " + | ||||
|                     logger.debug("SOLR returned " + results.length() + " results in " + | ||||
|                                  stopWatch.getLastTaskTimeMillis() + "ms"); | ||||
|                 } | ||||
|                 return results; | ||||
| @@ -194,7 +165,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|                 throw new QueryModelException("No query language available"); | ||||
|             } | ||||
|         case HYBRID: | ||||
|             if (((solrHybridEnabled != null) && (!solrHybridEnabled)) || (hybridEnabled == null) || (!hybridEnabled)) | ||||
|             if (!hybridEnabled) | ||||
|             { | ||||
|                 throw new DisabledFeatureException("Hybrid query is disabled."); | ||||
|             } | ||||
| @@ -238,7 +209,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|                     { | ||||
|                         if(logger.isDebugEnabled()) | ||||
|                         { | ||||
|                             logger.debug("Using "+subsystemName+" query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|                             logger.debug("Using SOLR query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|                         } | ||||
|                         stopWatch.start(); | ||||
| 
 | ||||
| @@ -247,7 +218,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|                         stopWatch.stop(); | ||||
|                         if (logger.isDebugEnabled()) | ||||
|                         { | ||||
|                             logger.debug(subsystemName+" returned " + results.length() + " results in " + | ||||
|                             logger.debug("SOLR returned " + results.length() + " results in " + | ||||
|                                          stopWatch.getLastTaskTimeMillis() + "ms"); | ||||
|                         } | ||||
|                         return results; | ||||
| @@ -260,14 +231,14 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|                 { | ||||
|                     if(logger.isDebugEnabled()) | ||||
|                     { | ||||
|                         logger.debug("(No DB QL) Using "+subsystemName+" query: "+"dbQueryLanguage==null"+" for "+searchParameters); | ||||
|                         logger.debug("(No DB QL) Using SOLR query: "+"dbQueryLanguage==null"+" for "+searchParameters); | ||||
|                     } | ||||
|                     stopWatch.start(); | ||||
|                     ResultSet results = indexQueryLanguage.executeQuery(searchParameters); | ||||
|                     stopWatch.stop(); | ||||
|                     if (logger.isDebugEnabled()) | ||||
|                     { | ||||
|                         logger.debug(subsystemName+" returned " + results.length() + " results in " + | ||||
|                         logger.debug("SOLR returned " + results.length() + " results in " + | ||||
|                                      stopWatch.getLastTaskTimeMillis() + "ms"); | ||||
|                     } | ||||
|                     return results; | ||||
| @@ -311,21 +282,21 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|     {         | ||||
|         if (indexQueryLanguage == null || dbQueryLanguage == null) | ||||
|         { | ||||
|             throw new QueryModelException("Both "+subsystemName+" and DB query language required for hybrid search [index=" + | ||||
|             throw new QueryModelException("Both index and DB query language required for hybrid search [index=" + | ||||
|                                           indexQueryLanguage + ", DB=" + dbQueryLanguage + "]"); | ||||
|         } | ||||
|          | ||||
|         StopWatch stopWatch = new StopWatch("hybrid search"); | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             logger.debug("Hybrid search, using "+subsystemName+" query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|             logger.debug("Hybrid search, using SOLR query: "+dbQueryLanguage.getName()+" for "+searchParameters); | ||||
|         } | ||||
|         stopWatch.start("index query"); | ||||
|         ResultSet indexResults = indexQueryLanguage.executeQuery(searchParameters); | ||||
|         stopWatch.stop(); | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             logger.debug(subsystemName+" query returned " + indexResults.length() + " results in " + | ||||
|             logger.debug("SOLR query returned " + indexResults.length() + " results in " + | ||||
|                          stopWatch.getLastTaskTimeMillis() + "ms"); | ||||
|         } | ||||
|         // TODO: if the results are up-to-date, then nothing more to do - return the results. | ||||
| @@ -334,7 +305,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|         { | ||||
|             if (logger.isWarnEnabled()) | ||||
|             { | ||||
|                 logger.warn("Hybrid search can only use database when "+subsystemName+" is also in use. " + | ||||
|                 logger.warn("Hybrid search can only use database when SOLR is also in use. " + | ||||
|                             "Skipping DB search, returning results from index."); | ||||
|             } | ||||
|             return indexResults;             | ||||
| @@ -374,7 +345,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|         { | ||||
|             nodeRefs.add(n.getNodeRef()); | ||||
|         } | ||||
|         // Only use the Search Index results for nodes that haven't changed since indexing. | ||||
|         // Only use the SOLR results for nodes that haven't changed since indexing. | ||||
|         for (ChildAssociationRef car : indexResults.getChildAssocRefs()) | ||||
|         { | ||||
|             if (!nodeRefs.contains(car.getChildRef())) | ||||
| @@ -389,7 +360,7 @@ public class DbOrIndexSwitchingQueryLanguage extends AbstractLuceneQueryLanguage | ||||
|         stopWatch.stop(); // merge result sets | ||||
|         if (logger.isDebugEnabled()) | ||||
|         { | ||||
|             String stats = String.format(subsystemName+"=%d, DB=%d, total=%d", | ||||
|             String stats = String.format("SOLR=%d, DB=%d, total=%d", | ||||
|                         indexResults.length(), dbResults.length(), results.length()); | ||||
|             logger.debug("Hybrid search returning combined results with counts: " + stats); | ||||
|             logger.debug(stopWatch.prettyPrint()); | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -23,19 +23,19 @@ | ||||
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.search.impl; | ||||
| 
 | ||||
| /** | ||||
|  * Identifies an attempt to use a disabled feature. | ||||
|  *  | ||||
|  * @author Matt Ward | ||||
|  */ | ||||
| public class DisabledFeatureException extends RuntimeException | ||||
| { | ||||
|     private static final long serialVersionUID = 1L; | ||||
| 
 | ||||
|     DisabledFeatureException(String message) | ||||
|     { | ||||
|         super(message); | ||||
|     } | ||||
| package org.alfresco.repo.search.impl.solr; | ||||
| 
 | ||||
| /** | ||||
|  * Identifies an attempt to use a disabled feature. | ||||
|  *  | ||||
|  * @author Matt Ward | ||||
|  */ | ||||
| public class DisabledFeatureException extends RuntimeException | ||||
| { | ||||
|     private static final long serialVersionUID = 1L; | ||||
| 
 | ||||
|     DisabledFeatureException(String message) | ||||
|     { | ||||
|         super(message); | ||||
|     } | ||||
| } | ||||
| @@ -1,29 +1,29 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.search.impl; | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.search.impl.solr; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| @@ -52,19 +52,19 @@ import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery; | ||||
| /** | ||||
|  * @author Andy | ||||
|  */ | ||||
| public class OpenCMISQueryServiceImpl implements CMISQueryService | ||||
| public class SolrOpenCMISQueryServiceImpl implements CMISQueryService | ||||
| { | ||||
|     private LuceneQueryLanguageSPI queryLanguage; | ||||
|     private LuceneQueryLanguageSPI solrQueryLanguage; | ||||
|      | ||||
|     private NodeService nodeService; | ||||
| 
 | ||||
|     private DictionaryService alfrescoDictionaryService; | ||||
| 
 | ||||
|     private CMISDictionaryService cmisDictionaryService; | ||||
| 
 | ||||
|     public void setQueryLanguage(LuceneQueryLanguageSPI queryLanguage) | ||||
|      | ||||
|     public void setSolrQueryLanguage(LuceneQueryLanguageSPI solrQueryLanguage) | ||||
|     { | ||||
|         this.queryLanguage = queryLanguage; | ||||
|         this.solrQueryLanguage = solrQueryLanguage; | ||||
|     } | ||||
| 
 | ||||
|     public void setNodeService(NodeService nodeService) | ||||
| @@ -87,7 +87,7 @@ public class OpenCMISQueryServiceImpl implements CMISQueryService | ||||
|     { | ||||
|     	SearchParameters searchParameters = options.getAsSearchParmeters(); | ||||
|     	searchParameters.addExtraParameter("cmisVersion", options.getCmisVersion().toString()); | ||||
|         ResultSet rs = queryLanguage.executeQuery(searchParameters); | ||||
|         ResultSet rs = solrQueryLanguage.executeQuery(searchParameters); | ||||
|          | ||||
|         CapabilityJoin joinSupport = getJoinSupport(); | ||||
|         if(options.getQueryMode() == CMISQueryOptions.CMISQueryMode.CMS_WITH_ALFRESCO_EXTENSIONS) | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -42,8 +42,6 @@ import org.alfresco.service.cmr.repository.NodeRef; | ||||
| @AlfrescoPublicApi | ||||
| public interface LockService | ||||
| { | ||||
|    int TIMEOUT_INFINITY = 0; | ||||
|  | ||||
|    /** | ||||
|     * Places a lock on a node.   | ||||
|     * <p> | ||||
|   | ||||
| @@ -75,6 +75,9 @@ | ||||
|         <property name="monitor"> | ||||
|             <ref bean="actionServiceMonitor"/> | ||||
|         </property> | ||||
|         <property name="configurationProperties"> | ||||
|             <ref bean="global-properties"/> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="defaultAsynchronousActionExecutionQueue" class="org.alfresco.repo.action.AsynchronousActionExecutionQueueImpl" init-method="init"> | ||||
| @@ -375,10 +378,10 @@ | ||||
|          <value>false</value> | ||||
|       </property> | ||||
|       <property name="nodeService"> | ||||
|          <ref bean="NodeService"/> | ||||
|          <ref bean="nodeService"/> | ||||
|       </property> | ||||
|       <property name="versionService"> | ||||
|          <ref bean="VersionService"/> | ||||
|          <ref bean="versionService"/> | ||||
|       </property> | ||||
|    </bean> | ||||
|  | ||||
| @@ -474,7 +477,7 @@ | ||||
|             <ref bean="NodeService" /> | ||||
|         </property> | ||||
|         <property name="cociService"> | ||||
|             <ref bean="CheckOutCheckInService"></ref> | ||||
|             <ref bean="checkOutCheckInService"></ref> | ||||
|         </property> | ||||
|         <property name="applicableTypes"> | ||||
|             <list> | ||||
| @@ -488,7 +491,7 @@ | ||||
|             <ref bean="NodeService" /> | ||||
|         </property> | ||||
|         <property name="cociService"> | ||||
|             <ref bean="CheckOutCheckInService"></ref> | ||||
|             <ref bean="checkOutCheckInService"></ref> | ||||
|         </property> | ||||
|         <property name="applicableTypes"> | ||||
|             <list> | ||||
| @@ -530,7 +533,13 @@ | ||||
|             </list> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|      | ||||
|     <bean id="errorProneActionExecutor" class="org.alfresco.repo.activities.feed.ErrorProneActionExecutor" parent="action-executer"> | ||||
|       <property name="publicAction"> | ||||
|          <value>false</value> | ||||
|       </property> | ||||
|    </bean> | ||||
|     | ||||
|     <!-- Import MailService from the OutboundSMTP subsystem (needed for email space/invited users actions) --> | ||||
|     <bean id="mailService" class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory"> | ||||
|         <property name="sourceApplicationContextFactory"> | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| <!-- Core and miscellaneous bean definitions --> | ||||
| <beans> | ||||
|  | ||||
|     <bean id="base.search.cmis.alfresco.switching" abstract="true" class="org.alfresco.repo.search.impl.DbOrIndexSwitchingQueryLanguage"> | ||||
|     <bean id="search.cmis.alfresco.switching" class="org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
| @@ -19,19 +19,15 @@ | ||||
|         <property name="indexQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.index" /> | ||||
|         </property> | ||||
|  | ||||
|         <property name="queryConsistency" value="${query.cmis.queryConsistency}"/> | ||||
|         <property name="solrQueryConsistency" value="${solr.query.cmis.queryConsistency}"/> | ||||
|  | ||||
|         <!-- Deprecated --> | ||||
|         <property name="hybridEnabled" value="${query.hybrid.enabled}"/> | ||||
|         <property name="solrHybridEnabled" value="${solr.query.hybrid.enabled}"/> | ||||
|  | ||||
|         <property name="queryConsistency"> | ||||
|             <value>${solr.query.cmis.queryConsistency}</value> | ||||
|         </property> | ||||
|         <property name="nodeService" ref="NodeService"/> | ||||
|         <property name="searchDao" ref="searchDAO"/> | ||||
|         <property name="hybridEnabled" value="${solr.query.hybrid.enabled}"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="base.search.cmis.alfresco.switching1.1" abstract="true" class="org.alfresco.repo.search.impl.DbOrIndexSwitchingQueryLanguage"> | ||||
|     <bean id="search.cmis.alfresco.switching1.1" class="org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
| @@ -46,15 +42,12 @@ | ||||
|         <property name="indexQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.index" /> | ||||
|         </property> | ||||
|  | ||||
|         <property name="queryConsistency" value="${query.cmis.queryConsistency}"/> | ||||
|  | ||||
|         <!-- Deprecated --> | ||||
|         <property name="solrQueryConsistency" value="${solr.query.cmis.queryConsistency}"/>  | ||||
|  | ||||
|         <property name="queryConsistency"> | ||||
|             <value>${solr.query.cmis.queryConsistency}</value> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="base.search.cmis.strict.switching" abstract="true" class="org.alfresco.repo.search.impl.DbOrIndexSwitchingQueryLanguage"> | ||||
|     <bean id="search.cmis.strict.switching" class="org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
| @@ -69,19 +62,15 @@ | ||||
|         <property name="indexQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.index" /> | ||||
|         </property> | ||||
|  | ||||
|         <property name="queryConsistency" value="${query.cmis.queryConsistency}"/> | ||||
|         <property name="solrQueryConsistency" value="${solr.query.cmis.queryConsistency}"/> | ||||
|  | ||||
|         <!-- Deprecated --> | ||||
|         <property name="hybridEnabled" value="${query.hybrid.enabled}"/> | ||||
|         <property name="solrHybridEnabled" value="${solr.query.hybrid.enabled}"/> | ||||
|  | ||||
|         <property name="queryConsistency"> | ||||
|             <value>${solr.query.cmis.queryConsistency}</value> | ||||
|         </property> | ||||
|         <property name="nodeService" ref="NodeService"/> | ||||
|         <property name="searchDao" ref="searchDAO"/> | ||||
|         <property name="hybridEnabled" value="${solr.query.hybrid.enabled}"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.db" class="org.alfresco.repo.search.impl.DbCmisQueryLanguage" > | ||||
|     <bean id="search.cmis.alfresco.db" class="org.alfresco.repo.search.impl.solr.DbCmisQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
| @@ -101,7 +90,7 @@ | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.db1.1" class="org.alfresco.repo.search.impl.DbCmisQueryLanguage" > | ||||
|     <bean id="search.cmis.alfresco.db1.1" class="org.alfresco.repo.search.impl.solr.DbCmisQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
|   | ||||
| @@ -64,8 +64,8 @@ | ||||
|         </property> | ||||
|         <!-- Query collections should be loaded on demand using this component - once loaded thay are available for use --> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="base.search.fts.alfresco.switching" abstract="true" class="org.alfresco.repo.search.impl.DbOrIndexSwitchingQueryLanguage"> | ||||
|      | ||||
|     <bean id="search.fts.alfresco.switching" class="org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|                 <ref bean="search.indexerAndSearcherFactory" /> | ||||
| @@ -80,16 +80,12 @@ | ||||
|         <property name="indexQueryLanguage"> | ||||
|             <ref bean="search.fts.alfresco.index" /> | ||||
|         </property> | ||||
|  | ||||
|         <property name="queryConsistency" value="${query.fts.queryConsistency}"/> | ||||
|         <property name="solrQueryConsistency" value="${solr.query.fts.queryConsistency}"/> | ||||
|  | ||||
|         <!-- Deprecated --> | ||||
|         <property name="hybridEnabled" value="${query.hybrid.enabled}"/> | ||||
|         <property name="solrHybridEnabled" value="${solr.query.hybrid.enabled}"/>  | ||||
|  | ||||
|         <property name="queryConsistency"> | ||||
|             <value>${solr.query.fts.queryConsistency}</value> | ||||
|         </property> | ||||
|         <property name="searchDao" ref="searchDAO"/> | ||||
|     </bean> | ||||
|         <property name="hybridEnabled" value="${solr.query.hybrid.enabled}"/> | ||||
|     </bean>  | ||||
|  | ||||
|     <bean id="search.fts.alfresco.db" class="org.alfresco.repo.search.impl.solr.DbAftsQueryLanguage" > | ||||
|         <property name="dictionaryService" ref="dictionaryService" /> | ||||
|   | ||||
| @@ -2,14 +2,9 @@ search.solrTrackingSupport.enabled=true | ||||
| search.solrTrackingSupport.ignorePathsForSpecificTypes=false | ||||
| search.solrTrackingSupport.ignorePathsForSpecificAspects=false | ||||
|  | ||||
| # Deprecated | ||||
| solr.query.fts.queryConsistency= | ||||
| solr.query.cmis.queryConsistency= | ||||
| solr.query.hybrid.enabled= | ||||
|  | ||||
| query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.hybrid.enabled=false | ||||
| solr.query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.hybrid.enabled=false | ||||
|  | ||||
| search.solrShardRegistry.purgeOnInit=false | ||||
| search.solrShardRegistry.shardInstanceTimeoutInSeconds=300 | ||||
|   | ||||
| @@ -99,11 +99,7 @@ | ||||
|             <ref bean="search.indexerAndSearcherFactory" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.switching" parent="base.search.fts.alfresco.switching" > | ||||
|         <property name="subsystemName" value="noindex"/> | ||||
|     </bean> | ||||
|  | ||||
|      | ||||
|     <bean id="search.fts.alfresco.index" class="org.alfresco.repo.search.impl.solr.NoIndexQueryLanguage" > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|   | ||||
| @@ -5,19 +5,7 @@ | ||||
|  | ||||
|    <import resource="../common-opencmis-context.xml" /> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching" parent="base.search.cmis.alfresco.switching" > | ||||
|         <property name="subsystemName" value="noindex"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching1.1" parent="base.search.cmis.alfresco.switching1.1" > | ||||
|         <property name="subsystemName" value="noindex"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.strict.switching" parent="base.search.cmis.strict.switching" > | ||||
|         <property name="subsystemName" value="noindex"/> | ||||
|     </bean> | ||||
|  | ||||
|   <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|   <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService" /> | ||||
|         </property> | ||||
| @@ -27,12 +15,12 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService1.1" /> | ||||
|         </property> | ||||
| @@ -42,7 +30,7 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching1.1" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|   | ||||
| @@ -2,14 +2,9 @@ search.solrTrackingSupport.enabled=true | ||||
| search.solrTrackingSupport.ignorePathsForSpecificTypes=false | ||||
| search.solrTrackingSupport.ignorePathsForSpecificAspects=false | ||||
|  | ||||
| # Deprecated | ||||
| solr.query.fts.queryConsistency= | ||||
| solr.query.cmis.queryConsistency= | ||||
| solr.query.hybrid.enabled= | ||||
|  | ||||
| query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.hybrid.enabled=false | ||||
| solr.query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.hybrid.enabled=false | ||||
|  | ||||
| search.solrShardRegistry.purgeOnInit=false | ||||
| search.solrShardRegistry.shardInstanceTimeoutInSeconds=300 | ||||
|   | ||||
| @@ -4,19 +4,7 @@ | ||||
| <beans> | ||||
|    <import resource="../common-opencmis-context.xml" /> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching" parent="base.search.cmis.alfresco.switching" > | ||||
|         <property name="subsystemName" value="solr"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching1.1" parent="base.search.cmis.alfresco.switching1.1" > | ||||
|         <property name="subsystemName" value="solr"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.strict.switching" parent="base.search.cmis.strict.switching" > | ||||
|         <property name="subsystemName" value="solr"/> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService" /> | ||||
|         </property> | ||||
| @@ -26,12 +14,12 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService1.1" /> | ||||
|         </property> | ||||
| @@ -41,7 +29,7 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching1.1" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|   | ||||
| @@ -168,11 +168,7 @@ | ||||
|         </property> | ||||
|          | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.switching" parent="base.search.fts.alfresco.switching" > | ||||
|         <property name="subsystemName" value="solr"/> | ||||
|     </bean> | ||||
|  | ||||
|      | ||||
|     <bean id="search.index.alfresco" class="org.alfresco.repo.search.impl.solr.SolrQueryLanguage"  > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|   | ||||
| @@ -2,14 +2,9 @@ search.solrTrackingSupport.enabled=true | ||||
| search.solrTrackingSupport.ignorePathsForSpecificTypes=false | ||||
| search.solrTrackingSupport.ignorePathsForSpecificAspects=false | ||||
|  | ||||
| # Deprecated | ||||
| solr.query.fts.queryConsistency= | ||||
| solr.query.cmis.queryConsistency= | ||||
| solr.query.hybrid.enabled= | ||||
|  | ||||
| query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.hybrid.enabled=false | ||||
| solr.query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.hybrid.enabled=false | ||||
|  | ||||
| search.solrShardRegistry.purgeOnInit=false | ||||
| search.solrShardRegistry.shardInstanceTimeoutInSeconds=300 | ||||
|   | ||||
| @@ -4,19 +4,7 @@ | ||||
| <beans> | ||||
|    <import resource="../common-opencmis-context.xml" /> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching" parent="base.search.cmis.alfresco.switching" > | ||||
|         <property name="subsystemName" value="solr4"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching1.1" parent="base.search.cmis.alfresco.switching1.1" > | ||||
|         <property name="subsystemName" value="solr4"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.strict.switching" parent="base.search.cmis.strict.switching" > | ||||
|         <property name="subsystemName" value="solr4"/> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService" /> | ||||
|         </property> | ||||
| @@ -26,12 +14,12 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService1.1" /> | ||||
|         </property> | ||||
| @@ -41,7 +29,7 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching1.1" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|   | ||||
| @@ -218,10 +218,6 @@ | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.switching" parent="base.search.fts.alfresco.switching" > | ||||
|         <property name="subsystemName" value="sol4"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.index" class="org.alfresco.repo.search.impl.solr.SolrQueryLanguage"  > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|   | ||||
| @@ -2,14 +2,9 @@ search.solrTrackingSupport.enabled=true | ||||
| search.solrTrackingSupport.ignorePathsForSpecificTypes=false | ||||
| search.solrTrackingSupport.ignorePathsForSpecificAspects=false | ||||
|  | ||||
| # Deprecated | ||||
| solr.query.fts.queryConsistency= | ||||
| solr.query.cmis.queryConsistency= | ||||
| solr.query.hybrid.enabled= | ||||
|  | ||||
| query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| query.hybrid.enabled=false | ||||
| solr.query.fts.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.cmis.queryConsistency=TRANSACTIONAL_IF_POSSIBLE | ||||
| solr.query.hybrid.enabled=false | ||||
|  | ||||
| search.solrShardRegistry.purgeOnInit=false | ||||
| search.solrShardRegistry.shardInstanceTimeoutInSeconds=300 | ||||
|   | ||||
| @@ -4,19 +4,7 @@ | ||||
| <beans> | ||||
|    <import resource="../common-opencmis-context.xml" /> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching" parent="base.search.cmis.alfresco.switching" > | ||||
|         <property name="subsystemName" value="solr6"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.alfresco.switching1.1" parent="base.search.cmis.alfresco.switching1.1" > | ||||
|         <property name="subsystemName" value="solr6"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.cmis.strict.switching" parent="base.search.cmis.strict.switching" > | ||||
|         <property name="subsystemName" value="solr6"/> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService" /> | ||||
|         </property> | ||||
| @@ -26,12 +14,12 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.OpenCMISQueryServiceImpl" > | ||||
|    <bean id="search.OpenCMISQueryService1.1" class="org.alfresco.repo.search.impl.solr.SolrOpenCMISQueryServiceImpl" > | ||||
|        <property name="cmisDictionaryService"> | ||||
|             <ref bean="OpenCMISDictionaryService1.1" /> | ||||
|         </property> | ||||
| @@ -41,7 +29,7 @@ | ||||
|         <property name="alfrescoDictionaryService"> | ||||
|             <ref bean="dictionaryService" /> | ||||
|         </property> | ||||
|         <property name="queryLanguage"> | ||||
|         <property name="solrQueryLanguage"> | ||||
|             <ref bean="search.cmis.alfresco.switching1.1" /> | ||||
|         </property> | ||||
|     </bean> | ||||
|   | ||||
| @@ -238,10 +238,6 @@ | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.switching" parent="base.search.fts.alfresco.switching" > | ||||
|         <property name="subsystemName" value="solr6"/> | ||||
|     </bean> | ||||
|  | ||||
|     <bean id="search.fts.alfresco.index" class="org.alfresco.repo.search.impl.solr.SolrQueryLanguage"  > | ||||
|         <property name="factories"> | ||||
|             <list> | ||||
|   | ||||
| @@ -176,6 +176,7 @@ import org.junit.runners.Suite; | ||||
|     org.alfresco.repo.action.CompositeActionImplTest.class, | ||||
|     org.alfresco.repo.action.CompositeActionConditionImplTest.class, | ||||
|     org.alfresco.repo.action.executer.TransformActionExecuterTest.class, | ||||
|     org.alfresco.repo.action.PrivateActionValidationTest.class, | ||||
|     org.alfresco.repo.audit.AuditableAnnotationTest.class, | ||||
|     org.alfresco.repo.audit.PropertyAuditFilterTest.class, | ||||
|     org.alfresco.repo.audit.access.NodeChangeTest.class, | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2016 Alfresco Software Limited | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * %% | ||||
|  * This file is part of the Alfresco software.  | ||||
|  * If the software was purchased under a paid Alfresco license, the terms of  | ||||
| @@ -25,28 +25,27 @@ | ||||
|  */ | ||||
| package org.alfresco.repo.action; | ||||
|  | ||||
| import static org.alfresco.repo.action.ActionExecutionContext.builder; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.lang.reflect.Field; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.Date; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Properties; | ||||
|  | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; | ||||
| import org.alfresco.repo.action.evaluator.InCategoryEvaluator; | ||||
| import org.alfresco.repo.action.evaluator.NoConditionEvaluator; | ||||
| import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation; | ||||
| import org.alfresco.repo.action.executer.ActionExecuter; | ||||
| import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; | ||||
| import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; | ||||
| import org.alfresco.repo.action.executer.CheckInActionExecuter; | ||||
| import org.alfresco.repo.action.executer.CheckOutActionExecuter; | ||||
| import org.alfresco.repo.action.executer.CompositeActionExecuter; | ||||
| import org.alfresco.repo.action.executer.MoveActionExecuter; | ||||
| import org.alfresco.repo.action.executer.ScriptActionExecuter; | ||||
| import org.alfresco.repo.content.MimetypeMap; | ||||
| import org.alfresco.repo.security.authentication.AuthenticationUtil; | ||||
| import org.alfresco.repo.transaction.RetryingTransactionHelper; | ||||
| @@ -65,19 +64,14 @@ import org.alfresco.service.cmr.action.CompositeActionCondition; | ||||
| import org.alfresco.service.cmr.action.ParameterDefinition; | ||||
| import org.alfresco.service.cmr.coci.CheckOutCheckInService; | ||||
| import org.alfresco.service.cmr.repository.ContentData; | ||||
| import org.alfresco.service.cmr.repository.ContentWriter; | ||||
| import org.alfresco.service.cmr.repository.NodeRef; | ||||
| import org.alfresco.service.cmr.repository.NodeService; | ||||
| import org.alfresco.service.cmr.security.PermissionService; | ||||
| import org.alfresco.service.cmr.security.PersonService; | ||||
| import org.alfresco.service.namespace.NamespaceService; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| import org.alfresco.service.transaction.TransactionService; | ||||
| import org.alfresco.test_category.BaseSpringTestsCategory; | ||||
| import org.alfresco.util.ApplicationContextHelper; | ||||
| import org.alfresco.util.BaseAlfrescoSpringTest; | ||||
| import org.alfresco.util.GUID; | ||||
| import org.alfresco.util.PropertyMap; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.experimental.categories.Category; | ||||
| @@ -103,13 +97,18 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest | ||||
|     private NodeRef nodeRef; | ||||
|     private NodeRef folder; | ||||
|     private RetryingTransactionHelper transactionHelper; | ||||
|     private Properties globalConfig; | ||||
|     private RuntimeActionService runtimeActionService; | ||||
|  | ||||
|      | ||||
|     @Before | ||||
|     public void before() throws Exception | ||||
|     { | ||||
|         super.before(); | ||||
|  | ||||
|         this.transactionHelper = (RetryingTransactionHelper)this.applicationContext.getBean("retryingTransactionHelper"); | ||||
|         this.transactionHelper = applicationContext.getBean("retryingTransactionHelper", RetryingTransactionHelper.class); | ||||
|         this.globalConfig = applicationContext.getBean("global-properties", Properties.class); | ||||
|         this.runtimeActionService = this.applicationContext.getBean("actionService", RuntimeActionService.class); | ||||
|  | ||||
|         // Create the node used for tests | ||||
|         this.nodeRef = this.nodeService.createNode( | ||||
| @@ -1295,6 +1294,89 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest | ||||
|        assertEquals(123455, action.getExecutionEndDate().getTime()); | ||||
|        assertEquals(null, action.getExecutionFailureMessage()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testActionExposureBasedOnConfiguration() | ||||
|     { | ||||
|         globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed"); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.public-test-action.exposed", "true"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed"); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.public-test-action.exposed", "false"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed"); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("public-test-action").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed"); | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.source.public-test-action.exposed", "true"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed"); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed"); | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.source.public-test-action.exposed", "false"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed"); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed"); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.private-test-action.exposed", "true"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed"); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("private-test-action").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.private-test-action.exposed", "false"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed"); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed"); | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.source.private-test-action.exposed", "true"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed"); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").build())); | ||||
|         assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build())); | ||||
|  | ||||
|         globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed"); | ||||
|         globalConfig.setProperty("org.alfresco.repo.action.source.private-test-action.exposed", "false"); | ||||
|         globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed"); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build())); | ||||
|         assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testIfGlobalConfigurationIsUsedEvenIfNotInjectedBySpring() | ||||
|     { | ||||
|         TestExtendedActionServiceImpl extended = applicationContext.getBean("extendedActionServiceWithoutConfigurationProperty", TestExtendedActionServiceImpl.class); | ||||
|  | ||||
|         assertNotNull(extended.getConfigurationProperties()); | ||||
|         assertSame(globalConfig, extended.getConfigurationProperties()); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * This method returns an {@link Action} which will fail when executed. | ||||
| @@ -1509,8 +1591,26 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest | ||||
|            throw new ActionServiceTransientException("action failed intentionally in " + TransientFailActionExecuter.class.getSimpleName()); | ||||
|        } | ||||
|     } | ||||
|      | ||||
|  | ||||
|     public static class NoOpActionExecuter extends ActionExecuterAbstractBase | ||||
|     { | ||||
|         @Override | ||||
|         protected void addParameterDefinitions(List<ParameterDefinition> paramList) | ||||
|         { | ||||
|             //do nothing | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected void executeImpl(Action action, NodeRef actionedUponNodeRef) | ||||
|         { | ||||
|             //do nothing | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static class TestExtendedActionServiceImpl extends ActionServiceImpl | ||||
|     { | ||||
|  | ||||
|     } | ||||
|      | ||||
|     protected static class CancellableSleepAction extends ActionImpl implements CancellableAction | ||||
|     { | ||||
|   | ||||
| @@ -0,0 +1,152 @@ | ||||
| /* | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>. | ||||
|  * #L% | ||||
|  */ | ||||
| package org.alfresco.repo.action; | ||||
|  | ||||
| import static org.alfresco.repo.action.ActionExecutionContext.builder; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| import static org.junit.Assert.fail; | ||||
|  | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
|  | ||||
| import org.alfresco.repo.action.ActionServiceImpl.ActionExecutionValidator; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
|  | ||||
| public class PrivateActionValidationTest | ||||
| { | ||||
|     @Test | ||||
|     public void shouldFailOnNullContext() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of()); | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             validator.isExposed(null); | ||||
|         } | ||||
|         catch (NullPointerException e) | ||||
|         { | ||||
|             assertNotNull(e); | ||||
|             return; | ||||
|         } | ||||
|         fail("Expected NPE."); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void privateActionShouldNotBeExposedByDefault() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of()); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateA").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void publicActionShouldBeExposedByDefault() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of("publicA")); | ||||
|  | ||||
|         Assert.assertTrue(validator.isExposed(builder("publicA").build())); | ||||
|         Assert.assertTrue(validator.isExposed(builder("publicA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void privateActionShouldBeExposedByConfigurationBasedOnActionId() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.privateA.exposed", "true"), Set.of()); | ||||
|  | ||||
|         Assert.assertTrue(validator.isExposed(builder("privateA").build())); | ||||
|         Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build())); | ||||
|         Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test2").build())); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test2").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void privateActionShouldBeExposedByConfigurationBasedOnActionIdAndExecutionSource() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.test.privateA.exposed", "true"), Set.of()); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateA").build())); | ||||
|         Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateA").withExecutionSource("test2").build())); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test2").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void executionSourceConfigurationShouldTakePrecedenceOverGeneralConfigurationForPrivateAction() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.test.privateA.exposed", "true", | ||||
|                 "org.alfresco.repo.action.privateA.exposed", "false"), Set.of()); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("privateA").build())); | ||||
|         Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void publicActionShouldNotBeExposedByConfigurationBasedOnActionId() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.publicA.exposed", "false"), Set.of("publicA")); | ||||
|  | ||||
|         Assert.assertFalse(validator.isExposed(builder("publicA").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void publicActionShouldNotBeExposedByConfigurationBasedOnActionIdAndExecutionSource() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.test.publicA.exposed", "false"), Set.of("publicA")); | ||||
|  | ||||
|         Assert.assertTrue(validator.isExposed(builder("publicA").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void executionSourceConfigurationShouldTakePrecedenceOverGeneralConfigurationForPublicAction() | ||||
|     { | ||||
|         final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of( | ||||
|                 "org.alfresco.repo.action.test.publicA.exposed", "false", | ||||
|                 "org.alfresco.repo.action.publicA.exposed", "true"), Set.of("publicA")); | ||||
|  | ||||
|         Assert.assertTrue(validator.isExposed(builder("publicA").build())); | ||||
|         Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build())); | ||||
|     } | ||||
|  | ||||
|     private ActionExecutionValidator givenActionExecutionValidator(Map<String, String> configuration, Set<String> publicActions) | ||||
|     { | ||||
|         return new ActionExecutionValidator(configuration::get, publicActions::contains); | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -25,6 +25,10 @@ | ||||
|  */ | ||||
| package org.alfresco.repo.activities.feed; | ||||
|  | ||||
| import static junit.framework.Assert.fail; | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertTrue; | ||||
|  | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.activities.post.lookup.PostLookup; | ||||
| import org.alfresco.repo.domain.activities.ActivitiesDAO; | ||||
| @@ -48,7 +52,6 @@ import org.alfresco.service.namespace.NamespaceService; | ||||
| import org.alfresco.service.namespace.QName; | ||||
| import org.alfresco.service.transaction.TransactionService; | ||||
| import org.alfresco.util.ApplicationContextHelper; | ||||
| import org.alfresco.util.BaseSpringTest; | ||||
| import org.alfresco.util.GUID; | ||||
| import org.alfresco.util.PropertyMap; | ||||
| import org.json.JSONObject; | ||||
| @@ -59,7 +62,6 @@ import org.quartz.JobDetail; | ||||
| import org.quartz.Scheduler; | ||||
| import org.springframework.beans.factory.ObjectFactory; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| @@ -69,10 +71,10 @@ import java.util.List; | ||||
|  *  | ||||
|  * @author steveglover | ||||
|  */ | ||||
| @ContextConfiguration({"classpath:alfresco/application-context.xml", | ||||
|         "classpath:alfresco/feednotifier-tests/test-action-services-context.xml"}) | ||||
| public class FeedNotifierTest extends BaseSpringTest | ||||
| public class FeedNotifierTest | ||||
| { | ||||
|     private static ApplicationContext ctx = null; | ||||
|  | ||||
|     private PersonService personService; | ||||
|     private NodeService nodeService; | ||||
|     private NamespaceService namespaceService; | ||||
| @@ -102,12 +104,14 @@ public class FeedNotifierTest extends BaseSpringTest | ||||
|     { | ||||
|         ApplicationContextHelper.setUseLazyLoading(false); | ||||
|         ApplicationContextHelper.setNoAutoStart(true); | ||||
|  | ||||
|         ctx = ApplicationContextHelper.getApplicationContext(); | ||||
|     } | ||||
|  | ||||
|     @Before | ||||
|     public void before() throws Exception | ||||
|     { | ||||
|         ChildApplicationContextFactory activitiesFeed = (ChildApplicationContextFactory) applicationContext.getBean("ActivitiesFeed"); | ||||
|         ChildApplicationContextFactory activitiesFeed = (ChildApplicationContextFactory) ctx.getBean("ActivitiesFeed"); | ||||
|         ApplicationContext activitiesFeedCtx = activitiesFeed.getApplicationContext(); | ||||
|         this.feedNotifier = (FeedNotifierImpl) activitiesFeedCtx.getBean("feedNotifier"); | ||||
|         this.activityService = (ActivityService) activitiesFeedCtx.getBean("activityService"); | ||||
| @@ -115,7 +119,7 @@ public class FeedNotifierTest extends BaseSpringTest | ||||
|         this.feedGenerator = (FeedGenerator) activitiesFeedCtx.getBean("feedGenerator"); | ||||
|         ObjectFactory<ActivitiesFeedModelBuilder> feedModelBuilderFactory = (ObjectFactory<ActivitiesFeedModelBuilder>) activitiesFeedCtx.getBean("feedModelBuilderFactory"); | ||||
|  | ||||
|         Scheduler scheduler = (Scheduler) applicationContext.getBean("schedulerFactory"); | ||||
|         Scheduler scheduler = (Scheduler) ctx.getBean("schedulerFactory"); | ||||
|  | ||||
|         JobDetail feedGeneratorJobDetail = (JobDetail) activitiesFeedCtx.getBean("feedGeneratorJobDetail"); | ||||
|         JobDetail postLookupJobDetail = (JobDetail) activitiesFeedCtx.getBean("postLookupJobDetail"); | ||||
| @@ -130,17 +134,17 @@ public class FeedNotifierTest extends BaseSpringTest | ||||
|         scheduler.pauseJob(postCleanerJobDetail.getKey()); | ||||
|         scheduler.pauseJob(feedNotifierJobDetail.getKey()); | ||||
|  | ||||
|         this.personService = (PersonService) applicationContext.getBean("personService"); | ||||
|         this.nodeService = (NodeService) applicationContext.getBean("nodeService"); | ||||
|         this.namespaceService = (NamespaceService) applicationContext.getBean("namespaceService"); | ||||
|         this.siteService = (SiteService) applicationContext.getBean("siteService"); | ||||
|         this.repoAdminService = (RepoAdminService) applicationContext.getBean("repoAdminService"); | ||||
|         this.transactionService = (TransactionService) applicationContext.getBean("transactionService"); | ||||
|         this.postDAO = (ActivityPostDAO) applicationContext.getBean("postDAO"); | ||||
|         this.fileFolderService = (FileFolderService) applicationContext.getBean("fileFolderService"); | ||||
|         this.subscriptionService = (SubscriptionService) applicationContext.getBean("SubscriptionService"); | ||||
|         this.errorProneActionExecutor = (ErrorProneActionExecutor) applicationContext.getBean("errorProneActionExecutor"); | ||||
|         this.actionService = (ActionService) applicationContext.getBean("ActionService"); | ||||
|         this.personService = (PersonService) ctx.getBean("personService"); | ||||
|         this.nodeService = (NodeService) ctx.getBean("nodeService"); | ||||
|         this.namespaceService = (NamespaceService) ctx.getBean("namespaceService"); | ||||
|         this.siteService = (SiteService) ctx.getBean("siteService"); | ||||
|         this.repoAdminService = (RepoAdminService) ctx.getBean("repoAdminService"); | ||||
|         this.transactionService = (TransactionService) ctx.getBean("transactionService"); | ||||
|         this.postDAO = (ActivityPostDAO) ctx.getBean("postDAO"); | ||||
|         this.fileFolderService = (FileFolderService) ctx.getBean("fileFolderService"); | ||||
|         this.subscriptionService = (SubscriptionService) ctx.getBean("SubscriptionService"); | ||||
|         this.errorProneActionExecutor = (ErrorProneActionExecutor) ctx.getBean("errorProneActionExecutor"); | ||||
|         this.actionService = (ActionService) ctx.getBean("ActionService"); | ||||
|  | ||||
|         // create some users | ||||
|         transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -28,7 +28,7 @@ package org.alfresco.repo.search; | ||||
| import javax.transaction.UserTransaction; | ||||
|  | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.search.impl.DisabledFeatureException; | ||||
| import org.alfresco.repo.search.impl.solr.DisabledFeatureException; | ||||
| import org.alfresco.repo.security.authentication.AuthenticationComponent; | ||||
| import org.alfresco.repo.security.authentication.AuthenticationUtil; | ||||
| import org.alfresco.repo.security.authentication.MutableAuthenticationDao; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * #%L | ||||
|  * Alfresco Repository | ||||
|  * %% | ||||
|  * Copyright (C) 2005 - 2022 Alfresco Software Limited | ||||
|  * 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  | ||||
| @@ -38,8 +38,6 @@ import java.util.List; | ||||
| import org.alfresco.model.ContentModel; | ||||
| import org.alfresco.repo.domain.node.Node; | ||||
| import org.alfresco.repo.domain.solr.SearchDAO; | ||||
| import org.alfresco.repo.search.impl.DbOrIndexSwitchingQueryLanguage; | ||||
| import org.alfresco.repo.search.impl.DisabledFeatureException; | ||||
| import org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI; | ||||
| import org.alfresco.repo.search.impl.querymodel.QueryModelException; | ||||
| import org.alfresco.repo.solr.NodeParameters; | ||||
|   | ||||
| @@ -1,12 +0,0 @@ | ||||
| <?xml version='1.0' encoding='UTF-8'?> | ||||
| <!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'> | ||||
|  | ||||
| <beans> | ||||
|  | ||||
|    <bean id="errorProneActionExecutor" class="org.alfresco.repo.activities.feed.ErrorProneActionExecutor" parent="action-executer"> | ||||
|       <property name="publicAction"> | ||||
|          <value>false</value> | ||||
|       </property> | ||||
|    </bean> | ||||
|  | ||||
| </beans> | ||||
| @@ -11,6 +11,18 @@ | ||||
|          <value>1000</value> | ||||
|       </property> | ||||
|    </bean> | ||||
|  | ||||
|    <bean id="public-test-action" class="org.alfresco.repo.action.ActionServiceImplTest$NoOpActionExecuter" parent="action-executer"> | ||||
|       <property name="publicAction"> | ||||
|          <value>true</value> | ||||
|       </property> | ||||
|    </bean> | ||||
|  | ||||
|    <bean id="private-test-action" class="org.alfresco.repo.action.ActionServiceImplTest$NoOpActionExecuter" parent="action-executer"> | ||||
|       <property name="publicAction"> | ||||
|          <value>false</value> | ||||
|       </property> | ||||
|    </bean> | ||||
|     | ||||
|    <bean id="sleepActionFilter" class="org.alfresco.repo.action.ActionServiceImplTest$SleepActionFilter" parent="baseActionFilter"> | ||||
|        <property name="name"> | ||||
| @@ -31,4 +43,28 @@ | ||||
|    <bean id="transient-fail-action" | ||||
|          class="org.alfresco.repo.action.ActionServiceImplTest$TransientFailActionExecuter" | ||||
|          parent="action-executer" /> | ||||
|  | ||||
|    <bean id="extendedActionServiceWithoutConfigurationProperty" class="org.alfresco.repo.action.ActionServiceImplTest$TestExtendedActionServiceImpl" init-method="init"> | ||||
|       <property name="policyComponent"> | ||||
|          <ref bean="policyComponent" /> | ||||
|       </property> | ||||
|       <property name="nodeService"> | ||||
|          <ref bean="NodeService" /> | ||||
|       </property> | ||||
|       <property name="searchService"> | ||||
|          <ref bean="ADMSearchService" /> | ||||
|       </property> | ||||
|       <property name="authenticationContext"> | ||||
|          <ref bean="authenticationContext" /> | ||||
|       </property> | ||||
|       <property name="actionTrackingService"> | ||||
|          <ref bean="actionTrackingService" /> | ||||
|       </property> | ||||
|       <property name="dictionaryService"> | ||||
|          <ref bean="DictionaryService" /> | ||||
|       </property> | ||||
|       <property name="monitor"> | ||||
|          <ref bean="actionServiceMonitor"/> | ||||
|       </property> | ||||
|    </bean> | ||||
| </beans> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user