Commit 8dc8245b authored by Francesco Corti's avatar Francesco Corti

first commit

parent 32a141bf
##2017 Alfresco Virtual Global Hackathon
A sample project demonstrating the use of [aps-unit-test-utils](https://github.com/fcorti/aps-unit-test-utils) developed during the 2017 Alfresco Virtual Global Hackathon
##APS process of my.alfresco.com decommission
Checkout the following two blogs for more details
[alfresco-process-services-unit-testing-part-1](https://community.alfresco.com/community/bpm/blog/2017/10/13/alfresco-process-services-unit-testing-i)
[alfresco-process-services-unit-testing-part-2](https://community.alfresco.com/community/bpm/blog/2017/10/13/alfresco-process-services-unit-testing-ii)
For a CI/CD example of APS apps, checkout the following
[alfresco-process-services-ci-cd-example](https://community.alfresco.com/community/bpm/blog/2017/10/11/cicd-example-for-alfresco-process-services-applications)
This project contains the Alfresco Process Services source code implementing the decommission process of the customers on my.alfresco.com.
......@@ -3,18 +3,23 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.alfresco.aps</groupId>
<artifactId>aps-unit-test-example</artifactId>
<artifactId>aps-my-alfresco-com-decommission</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>APS Project Example</name>
<description>An example project showing the use of https://github.com/fcorti/aps-unit-test-utils for testing processes</description>
<name>APS my.alfresco.com decommission</name>
<description>APS my.alfresco.com decommission.</description>
<dependencies>
<dependency>
<groupId>com.alfresco.aps</groupId>
<artifactId>aps-unit-test-utils</artifactId>
<version>[1.0-SNAPSHOT,)</version>
</dependency>
</dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
......@@ -48,4 +53,4 @@
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
</project>
This is a postman setup.
Postman version 6.2.5.
Postman collection version 2.1.
Import the local APS environment and customize the settings.
Import the two collections into postman.
The General one is about generic services you might use and need.
The Process instances creation is about massively creating process instances.
The massive creation is done using the Run option of the collection.
Into the setup use the salesforce_ids.json file that lists the salesforceId.
The salesforce_ids.json is created from the Excel Sheet of the project.
{
"id": "6894b368-df26-4fff-80a5-ad1452979fc2",
"name": "local APS",
"values": [
{
"key": "aps",
"value": "http://localhost:8080",
"description": "",
"enabled": true
},
{
"key": "user",
"value": "admin@app.activiti.com",
"description": "",
"enabled": true
},
{
"key": "password",
"value": "admin",
"description": "",
"enabled": true
},
{
"key": "processDefinitionId",
"value": "MyAlfrescoComdecommision:33:27510",
"description": "",
"enabled": true
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2018-08-24T09:10:51.904Z",
"_postman_exported_using": "Postman/6.2.5"
}
\ No newline at end of file
{
"info": {
"_postman_id": "06882642-2966-4c00-af23-b013f52f4fd5",
"name": "my.alfresco.com decommission - General",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"_postman_id": "f839a1af-ae16-4ab9-9aa3-1c20c9b1f956",
"name": "Process definitions",
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "{{password}}",
"type": "string"
},
{
"key": "username",
"value": "{{user}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{aps}}/activiti-app/api/enterprise/process-definitions",
"host": [
"{{aps}}"
],
"path": [
"activiti-app",
"api",
"enterprise",
"process-definitions"
]
}
},
"response": []
},
{
"_postman_id": "33ecafc4-ce0f-4797-b6af-06f492feeb83",
"name": "Process instance list",
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "{{password}}",
"type": "string"
},
{
"key": "username",
"value": "{{user}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"filter\": {\n \t\"processDefinitionId\": \"{{processDefinitionId}}\"\n }\n}"
},
"url": {
"raw": "{{aps}}/activiti-app/api/enterprise/process-instances/filter",
"host": [
"{{aps}}"
],
"path": [
"activiti-app",
"api",
"enterprise",
"process-instances",
"filter"
]
}
},
"response": []
},
{
"_postman_id": "7de5be3e-d064-456f-aca4-a92c43c5ef79",
"name": "Process instance deletetion",
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "{{password}}",
"type": "string"
},
{
"key": "username",
"value": "{{user}}",
"type": "string"
}
]
},
"method": "DELETE",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{aps}}/activiti-app/api/enterprise/process-instances/{{processInstanceId}}",
"host": [
"{{aps}}"
],
"path": [
"activiti-app",
"api",
"enterprise",
"process-instances",
"{{processInstanceId}}"
]
}
},
"response": []
}
]
}
\ No newline at end of file
{
"info": {
"_postman_id": "d02baf72-839a-4bd9-ba69-0de742a89bf3",
"name": "my.alfresco.com decommission - Process instances creation",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"_postman_id": "3cab7abf-ec10-4dee-afeb-581421255ef4",
"name": "Create a dismission process instance ",
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "{{password}}",
"type": "string"
},
{
"key": "username",
"value": "{{user}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"processDefinitionId\": \"{{processDefinitionId}}\",\n \"variables\": [\n {\n \"name\": \"salesforceId\",\n \"value\": \"{{salesforceId}}\"\n }\n ]\n}"
},
"url": {
"raw": "{{aps}}/activiti-app/api/enterprise/process-instances",
"host": [
"{{aps}}"
],
"path": [
"activiti-app",
"api",
"enterprise",
"process-instances"
]
}
},
"response": []
}
]
}
\ No newline at end of file
This diff is collapsed.
package com.activiti.extension.bean;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AlfrescoUploadJavaDelegate implements JavaDelegate {
private static Logger logger = LoggerFactory.getLogger(AlfrescoUploadJavaDelegate.class);
@Override
public void execute(DelegateExecution execution) throws Exception {
String alfrescoPath = (String) execution.getVariable("alfrescoPath");
logger.info("TODO: Alfresco upload on path '" + alfrescoPath + "'.");
}
}
package com.activiti.extension.bean;
import java.io.File;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.util.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.activiti.testutils.resources.AlfrescoResourceProperties;
import com.activiti.testutils.resources.MyAlfrescoComDecommissionResourceProperties;
import com.activiti.testutils.resources.ProcessUtil;
import com.activiti.testutils.resources.RestUtil;
public class BulkExportJavaDelegate implements JavaDelegate {
private static Logger logger = LoggerFactory.getLogger(BulkExportJavaDelegate.class);
MyAlfrescoComDecommissionResourceProperties myAlfrescoComDecommissionResourceProperties;
AlfrescoResourceProperties alfrescoResourceProperties;
@Override
public void execute(DelegateExecution execution) throws Exception {
String alfrescoTenant = (String) execution.getVariable(ProcessUtil.MY_ALFRESCO_COM_TENANT_VARIABLE);
myAlfrescoComDecommissionResourceProperties = new MyAlfrescoComDecommissionResourceProperties();
myAlfrescoComDecommissionResourceProperties.load();
alfrescoResourceProperties = new AlfrescoResourceProperties();
alfrescoResourceProperties.load();
createFolder(myAlfrescoComDecommissionResourceProperties.getProperty(MyAlfrescoComDecommissionResourceProperties.ARCHIVE_PATH));
String alfrescoExportPath = myAlfrescoComDecommissionResourceProperties.getProperty(MyAlfrescoComDecommissionResourceProperties.ARCHIVE_PATH) + File.separator + alfrescoTenant;
String alfrescoUUID = getAlfrescoUUID(alfrescoTenant);
getArchive(alfrescoUUID, alfrescoExportPath);
execution.setVariable(ProcessUtil.MY_ALFRESCO_COM_EXPORT_PATH_VARIABLE, alfrescoExportPath);
}
private void createFolder(String path) throws Exception {
File folder = new File(path);
if (!folder.exists()) {
folder.mkdir();
}
}
private void deleteFolder(String path) throws Exception {
File folder = new File(path);
if (folder.exists()) {
folder.delete();
}
}
private String getAlfrescoUUID(String alfrescoTenant) throws Exception {
// TODO: alfrescoTenant will be used in the endpoint definition.
JSONObject result = RestUtil.querySites(
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_BASE_URL) + alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_REST_GETROOT),
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_USER),
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_PASSWORD));
if (!result.has("entry")) {
throw new Exception("Error in retrieving the root node of Alfresco Content Services for network '" + alfrescoTenant + "'.");
}
String alfrescoUUID = result.getJSONObject("entry").getString("id");
logger.info("Retrieved the UUID='" + alfrescoUUID + "' for the Alfresco Content Services network '" + alfrescoTenant + "'.");
return alfrescoUUID;
}
private void getArchive(String alfrescoUUID, String targetPath) throws Exception {
deleteFolder(targetPath);
createFolder(targetPath);
String bulkExportResult = RestUtil.createArchive(
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_BASE_URL) + alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_BULK_EXPORT_EXPORT_REST_ENDPOINT) + "?" +
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_BULK_EXPORT_EXPORT_PARAMETER_NODEREF) + "=" + "workspace://SpacesStore/" + alfrescoUUID + "&" +
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_BULK_EXPORT_EXPORT_PARAMETER_BASE) + "=" + targetPath,
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_USER),
alfrescoResourceProperties.getProperty(AlfrescoResourceProperties.ALFRESCO_PASSWORD));
if (bulkExportResult.contains("ERROR occured")) {
throw new Exception("Bulk Export failed with message '" + bulkExportResult + "'.");
}
logger.info("Bulk export completed with success into folder '" + targetPath + "'.");
}
}
package com.activiti.extension.bean;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DownloadConfirmationJavaDelegate implements JavaDelegate {
private static Logger logger = LoggerFactory.getLogger(DownloadConfirmationJavaDelegate.class);
@Override
public void execute(DelegateExecution execution) throws Exception {
String alfrescoPath = (String) execution.getVariable("alfrescoPath");
execution.setVariable("downloadedFromAlfresco", true);
logger.info("TODO: Download confirmation of '" + alfrescoPath + "'.");
}
}
package com.activiti.extension.bean;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EmailNotificationJavaDelegate implements JavaDelegate {
private static Logger logger = LoggerFactory.getLogger(EmailNotificationJavaDelegate.class);
@Override
public void execute(DelegateExecution execution) throws Exception {
logger.info("TODO: Email notification.");
}
}
package com.activiti.extension.bean;
import java.io.File;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.activiti.domain.idm.User;
import com.activiti.service.api.UserService;
import com.activiti.testutils.resources.MyAlfrescoComDecommissionResourceProperties;
import com.activiti.testutils.resources.ProcessUtil;
import com.activiti.testutils.resources.SpreadsheetUtil;
@Component("salesforceInquiry")
public class SalesforceInquiryJavaDelegate implements JavaDelegate {
private static Logger logger = LoggerFactory.getLogger(SalesforceInquiryJavaDelegate.class);
@Autowired(required = false)
UserService userService;
MyAlfrescoComDecommissionResourceProperties myAlfrescoComDecommissionResourceProperties;
@Override
public void execute(DelegateExecution execution) throws Exception {
String salesforceId = (String) execution.getVariable(ProcessUtil.SALESFORCE_CUSTOMER_ID_VARIABLE);
myAlfrescoComDecommissionResourceProperties = new MyAlfrescoComDecommissionResourceProperties();
myAlfrescoComDecommissionResourceProperties.load();
Sheet sheet = SpreadsheetUtil.getSheet(new File(getClass().getClassLoader().getResource(myAlfrescoComDecommissionResourceProperties.getProperty(MyAlfrescoComDecommissionResourceProperties.SALESFORCE_SPREADSHEET_FILE_NAME)).getFile()), SpreadsheetUtil.SALESFORCE_SHEET_NUMBER);
Row customerRow = SpreadsheetUtil.getUniqueRow(sheet, SpreadsheetUtil.SALESFORCE_CUSTOMER_ID_COLUMN_DESCRIPTION, salesforceId);
int columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.CUSTOMER_TENANT_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.MY_ALFRESCO_COM_TENANT_VARIABLE, SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex)));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.CUSTOMER_TYPE_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.CUSTOMER_TYPE_VARIABLE, SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex)));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.CUSTOMER_GB_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.MY_ALFRESCO_COM_GB_VARIABLE, SpreadsheetUtil.getNumericValue(customerRow.getCell(columnIndex)));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.FREE_COMMENT_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.OFF_BOARDING_COMMENT_VARIABLE, SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex)));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.OFFBOARDING_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.OFF_BOARDING_DESCRIPTION_VARIABLE, SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex)));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.OFFBOARDING_PATH_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.OFF_BOARDING_PATH_VARIABLE, SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex)).substring("Path ".length()));
columnIndex = SpreadsheetUtil.getColumnIndex(sheet, SpreadsheetUtil.SALESFORCE_CSM_COLUMN_DESCRIPTION);
execution.setVariable(ProcessUtil.CSM_ASSIGNEE, getUserId(SpreadsheetUtil.getStringValue(customerRow.getCell(columnIndex))));
}
private String getUserId(String email) throws Exception {
if (email == null) {
email = myAlfrescoComDecommissionResourceProperties.getProperty(MyAlfrescoComDecommissionResourceProperties.DEFAULT_USER_EMAIL);
}
if (userService == null) {
logger.warn("User service null (not autowired). The email '" + email + "' will be used as User Id instead.");
return email;
}
User user = userService.findActiveUserByEmail(email);
return ((user == null) ? null : user.getId().toString());
}
}
package com.activiti.testutils.resources;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public final class AlfrescoResourceProperties extends Properties {
private static final long serialVersionUID = 1L;
private static final String FILE_NAME = "alfresco-resources.properties";
public static final String ALFRESCO_BASE_URL = "alfresco.baseUrl";
public static final String ALFRESCO_REST_GETROOT = "alfresco.rest.getRoot";
public static final String ALFRESCO_BULK_EXPORT_EXPORT_REST_ENDPOINT = "alfresco.bulkExport.export.endpoint";
public static final String ALFRESCO_BULK_EXPORT_EXPORT_PARAMETER_NODEREF = "alfresco.bulkExport.export.parameter.nodeRef";
public static final String ALFRESCO_BULK_EXPORT_EXPORT_PARAMETER_BASE = "alfresco.bulkExport.export.parameter.base";
public static final String ALFRESCO_USER = "alfresco.username";
public static final String ALFRESCO_PASSWORD = "alfresco.password";
public final void load() {
InputStream input = getClass().getClassLoader().getResourceAsStream(AlfrescoResourceProperties.FILE_NAME);
if (input != null) {
try {
load(input);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
package com.activiti.testutils.resources;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public final class MyAlfrescoComDecommissionResourceProperties extends Properties {
private static final long serialVersionUID = 1L;
private static final String FILE_NAME = "my-alfresco-com-decommission-resources.properties";
public static final String SALESFORCE_SPREADSHEET_FILE_NAME = "salesforce.spreadsheet.fileName";
public static final String DEFAULT_USER_EMAIL = "default.user.email";
public static final String ARCHIVE_PATH = "archive.path";
public final void load() {
InputStream input = getClass().getClassLoader().getResourceAsStream(MyAlfrescoComDecommissionResourceProperties.FILE_NAME);
if (input != null) {
try {
load(input);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}