Set up local workstation development environment
It's easy to start exploring Open Development Framework. Firstly, you need to prepare a workstation. Then you can use Quickstart Archetype for the initial ODF-based project generation. Follow this guide for a quick configuration.
ODF is released for following versions of Intelligent Automation Cloud Enterprise:
- 10.2.x
- 10.1.0
- 10.0.0
- 9.4.2-9.4.3
- 9.3.4
- 9.3.0-9.3.3
- 9.2.2
- 9.2.0-9.2.1
Such version fragmentation is caused by WorkFusion product features availability (for example, Bundle Import API is available in v10.1.0, v9.3.4, v9.2.2). This guide contains steps adjusted for 9.x versions.
Install Java 8 SDK
Download from the Oracle website and install Java 8 SDK.
Install local Nexus
Refer to this guide to download and install the Nexus server on your workstation. Using local Nexus, you will have full control over the repository which works with your local Control Tower. You will use local Nexus for BCBs deployment to local Control Tower. Those BCBs are originated either from your WorkFusion Studio or copied from public WorkFusion Nexus (https://repository.workfusion.com).
Configure local environment
9.3.4
Configure Maven
Configure Maven's settings.xml file (located in the C:/User/[USER_HOME]/.m2 folder):
<settings>
<servers>
<!-- Nexus Credentials for Maven to download WF dependencies to build project. Read only permissions are needed for this user -->
<server>
<id>wf-dependencies</id>
<username>odf-user</username>
<password>********</password>
</server>
<!-- Credentials for Package Import API into local or server Control Tower -->
<server>
<id>control-tower</id>
<username>ctuser</username>
<password>********</password>
</server>
<!-- Credentials to deploy BCB to Nexus (then local or server Control Tower will pull BCB from Nexus). Write permissions are needed for this user -->
<server>
<id>bcb-repository</id>
<username>admin</username>
<password>********</password>
</server>
</servers>
<profiles>
<profile>
<id>wf-repo</id>
<repositories>
<repository>
<id>wf-dependencies</id>
<url>https://repository.workfusion.com/content/groups/dependencies</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>wf-repo</activeProfile>
</activeProfiles>
</settings>
note
If you don't have the .m2 folder and settings.xml in it, create it manually in the C:/Users/[USER_HOME] folder.
If you use custom Nexus (not https://repository.workfusion.com), your default settings.xml file should look like this:
Expand
<settings>
<servers>
<!-- Nexus Credentials for Maven to download WF dependencies to build project. Read only permissions are needed for this user -->
<server>
<id>wf-dependencies</id>
<username>someUser1</username>
<password>********</password>
</server>
<!-- Credentials for Package Import API into local or server Control Tower -->
<server>
<id>control-tower</id>
<username>someUser2</username>
<password>********</password>
</server>
<!-- Credentials to deploy BCB to Nexus (then local or server Control Tower will pull BCB from Nexus). Write permissions are needed for this user -->
<server>
<id>bcb-repository</id>
<username>someUser3</username>
<password>********</password>
</server>
</servers>
<profiles>
<profile>
<id>wf-repo</id>
<repositories>
<repository>
<id>wf-dependencies</id>
<!-- URL to nexus with dependencies, like https://repository.workfusion.com/content/groups/dependencies -->
<url>nexusURL</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>wf-repo</activeProfile>
</activeProfiles>
</settings>
Install RPA Express Developer
RPA Express Developer 9.3.4 is a special version of RPA Express built for developers.
Launch RPA Express Developer and start Server components
Once you launched RPA Express Developer, go to the Code perspective (use the icon in the top right corner).
Now, you are ready to start Server components (local Control Tower, WorkSpace, Minio File Storage, RPA Agent). Switch the toggle into the ON position.

Wait a minute until you see the links to Server Components. Once they appear, go to Control Tower.
Log in into Control Tower using credentials you have created during the RPA Express Developer installation.
Configure local Control Tower with local Nexus
Reconfigure RPA Express Developer to connect it with local Nexus.
- In your browser, go to local Secrets Vault UI:: https://127.0.0.1:18280 (add a security exception)
- Log in using your RPA Express Developer username and password.
- Navigate to secrets > secret > policy > RPA Express Developer > workfusion_WFInternal
- Change the following three items:
- nexus.password
- nexus.url
- nexus.user
To do that, click on each item and modify the XML file.
```json { "alias": "nexus.url", "key": "nexus.url", "lastUpdated": 1568208163552, "value": "http://localhost:8081/nexus/" } ```Click Save.
Use your local Nexus parameters:
nexus.url=http://localhost:8081/nexus/nexus.user=adminnexus.password=********
Restart Server components. Switch the toggle to OFF and wait about one minute. Then, switch the toggle to ON and wait until the links to the Server applications appear below the toggle.
9.x
Configure Maven
Configure Maven's settings.xml file (located in the C:/User/[USER_HOME]/.m2 folder):
<settings>
<servers>
<!-- Nexus Credentials for Maven to download WF dependencies to build project. Read only permissions are needed for this user -->
<server>
<id>wf-dependencies</id>
<username>odf-user</username>
<password>********</password>
</server>
<!-- Credentials for Package Import API into local or server Control Tower -->
<server>
<id>control-tower</id>
<username>ctuser</username>
<password>********</password>
</server>
<!-- Credentials to deploy BCB to Nexus (then local or server Control Tower will pull BCB from Nexus). Write permissions are needed for this user -->
<server>
<id>bcb-repository</id>
<username>admin</username>
<password>********</password>
</server>
</servers>
<profiles>
<profile>
<id>wf-repo</id>
<repositories>
<repository>
<id>wf-dependencies</id>
<url>https://repository.workfusion.com/content/groups/dependencies</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>wf-repo</activeProfile>
</activeProfiles>
</settings>
note
If you don't have the .m2 folder and settings.xml in it, create it manually in the C:/Users/[USER_HOME] folder.
If you use custom Nexus (not https://repository.workfusion.com), your default settings.xml file should look like this:
Expand
<settings>
<servers>
<!-- Nexus Credentials for Maven to download WF dependencies to build project. Read only permissions are needed for this user -->
<server>
<id>wf-dependencies</id>
<username>someUser1</username>
<password>********</password>
</server>
<!-- Credentials for Package Import API into local or server Control Tower -->
<server>
<id>control-tower</id>
<username>someUser2</username>
<password>********</password>
</server>
<!-- Credentials to deploy BCB to Nexus (then local or server Control Tower will pull BCB from Nexus). Write permissions are needed for this user -->
<server>
<id>bcb-repository</id>
<username>someUser3</username>
<password>********</password>
</server>
</servers>
<profiles>
<profile>
<id>wf-repo</id>
<repositories>
<repository>
<id>wf-dependencies</id>
<!-- URL to nexus with dependencies, like https://repository.workfusion.com/content/groups/dependencies -->
<url>nexusURL</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>wf-repo</activeProfile>
</activeProfiles>
</settings>
Install RPA Express Pro
Once you advance in development of your automation project, it's required to start looking at how the solution will work in Control Tower. There are some automation aspects you can handle in Control Tower only:
- Design of Manual Tasks
- Exception handling using Manual Tasks
- Initial troubleshooting of failed transactions
- Execution scheduling of Business Process
- Complex Business Process design (nested Business Process)
- Assembly of all steps into a result Business Process
The easiest way for use-case developers to start testing in Control Tower is to reuse its local workstation version. Since RPA Express Pro 2.2.2, which is recommended to be used as Development Environment, contains Control Tower, we can leverage it for our goals. Additional Configuration is required in order to enable support of ODF.
note
RPA Express Pro should be compatible with server SPA (renamed to Intelligent Automation Cloud Enterprise from v10.0). Thus, download a proper version.
Configure RPA Express Pro for ODF
Replace the RPA Express license (located in
C:/RPAExpress/Workfusion/tomcat/conf/licence.properties) with the SPA Sandbox licence:owner=********@workfusion.com license=********Update
C:/RPAExpress/Workfusion/tomcat/conf/workfusion.propertiesby adding the following lines:webharvest.machine.config.bundle.repo=wf-machine-config-bundle webharvest.machine.config.bundle.release.repo=wf-machine-config-bundle webharvest.machine.config.bundle.dir=C:/RPAExpress/machine-config-bundle/ webharvest.machine.config.bundle.snapshot.repo=SnapshotsC:/RPAExpress/machine-config-bundleis your local folder where WorkFusion Studio keeps unpacked BCBs. Go ahead and manually create this folder.Update
C:/RPAExpress/Workfusion/tomcat/conf/secure.propertiesby adding the following lines.nexus.url=http://localhost:8081/nexus/ nexus.user=admin nexus.password=********tip
Use your local Nexus URL, username and password you have chosen when installing according to this guide.
Patch Control Tower. Skip the patching step if your RPA Express Pro version is 2.2.2 and higher.
- Stop Control Tower.
- Replace
C:/RPAExpress/Workfusion/tomcat/webapps/workfusion/WEB-INF/lib/workfusion-service-9.2.0.3with the patched version:workfusion-service-9.2.0.3.jar.
If you run later version of RPA Express Pro and have
workfusion-service-9.2.0.5.jar, replace it withworkfusion-service-9.2.0.3.- Start Control Tower.
Deploy ODF artifacts into local Control Tower
- Create the ODF required Data Stores as described here.
- Create the ODF required Control Tower Use Cases: Server ODF Environment | Import Required Use Cases
- Deploy
odf-bcb.jarinto your local Nexus:- Download the latest version corresponding to your SPA of
odf-bcb-X.X.X.X.jar. - Create the
wf-machine-config-bundleMaven repository (with Allow Redeploy) in your local Nexus. This repository will be used for all JAR transfers between WorkFusion Studio and Control Tower. - Upload
odf-bcb-X.X.X.X.jarmanually intowf-machine-config-bundle. - Select the
wf-machine-config-bundlerepository > Artifact. - Upload and set the following GAV:
Group: com.workfusion.odf
Artifact: odf-bcb
Version: X.X.X.X (specify the same version as in the downloaded JAR)
- Download the latest version corresponding to your SPA of
- Trigger the odf-bcb import from local Control Tower: Server ODF Environment | Trigger Import from Repository. This step will bring all the pre-packaged ODF components into local Control Tower.
important
You will use local Nexus for wf-machine-config-bundle only. All the other required Maven repositories (archetypes, dependencies) leave per default setting in project's pom.xml - use WorkFusion public Nexus https://repository.workfusion.com.
This will save your time on additional configuration and will let to avoid efforts on dependencies update when upgrading to a newer version of ODF.
You can verify that ODF bot tasks appear in your Control Tower if you can see reusable bot tasks while editing a new business process. On the right panel of reusable Bot components, see the number of bot tasks.
Project setup
Configure Archetypes catalog in WorkFusion Studio
- Launch WorkFusion Studio and navigate to the Code perspective.
- Click Window > Preferences > Maven > Archetypes > Add Remote Catalog.
Catalog File: https://repository.workfusion.com/content/repositories/archetypes
Description: ODF Release Archetypes

- To verify that the catalog contains any archetypes, use the Verify... button. On finishing, click OK.
Generate project from Archetype
Maven archetypes are project templates that can quickly start new projects based on a set of core files. The ODF team has prepared a number of Quickstart Archetypes to help you start.
A new project can be generated from WorkFusion Studio using the wizard.
- In WorkFusion Project Navigator, right-click New > Other > Maven > Maven Project.
- Click Next.

- Select the ODF Release Archetypes catalog. Out of available archetypes for your version of Intelligent Automation Cloud (clear Show the last version of Archetype only checkbox to see archetypes for all previous ODF versions), choose one which fits your project best. Compare using the Archetypes for ODF table below .
- Click Next.
Archetypes for ODF
Choose the archetype version according to the corresponding SPA version. For example, the archetype 9.2.2.1 is compatible with SPA 9.2.2 and so on. For a full compatibility matrix, see here.
# |
Archetype |
Brief description |
|---|---|---|
| 1 | full-bundle-classification-quickstart |
Generates project with 3 modules:
|
| 2 | full-bundle-ie-quickstart |
Generates project with 3 modules:
|
| 3 | minimal-bundle-quickstart |
Generates project with Package (for Import API) module only |
| 4 | rpa-bundle-quickstart | Generates project with 2 modules:
|

Once you have selected an archetype to start from, the wizard will ask to define Maven project initial settings.
- Enter Group Id and Artifact Id
- Keep the version as the release: 0.0.1 or 0.0.0.1 instead of 0.0.1-SNAPSHOT. We are using the Maven repository of the Release type, so if you keep -SNAPSHOT in version, the deployment to Nexus will fail.
- Configure the Control Tower URL. This setting will be used for deployment of project into server Control Tower using Import API.
- Click Finish.
tip
Artifact Id defines the main Maven project name. Use the common to your organization name of Use Case which you start to automate. We suggest to give intuitive names to the project and modules to avoid confusion from your peer developers. Keep names short, use lower case Latin characters and "-" symbol.

Now, your initial project structure has been generated.
Depending on which archetype you've selected, you will get 1-3 Maven modules which you can use to code an automation solution as well as immediately to build and deploy to Control Tower.
In case you need to generate a project from Archetype using the command line, here is the command to do the job:
mvn archetype:generate -DgroupId=com.workfusion.myproject -DartifactId=test-arch-project -Dversion=1.0.0 -DarchetypeGroupId=com.workfusion.odf -DarchetypeArtifactId=minimal-bundle-quickstart -DarchetypeVersion=X.X.X.X -DinteractiveMode=false -Dcontrol-tower-url=http://myenv.com
Before executing this from console, make Maven aware of the WorkFusion public archetypes repository. Add this into your Maven's settings.xml before the <servers> section:
<profiles>
<profile>
<id>all</id>
<repositories>
<repository>
<id>wf-archetypes</id>
<name>WorkFusion Nexus Repository - dependencies</name>
<url>https://repository.workfusion.com/content/repositories/archetypes/</url>
<layout>default</layout>
<releases>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>all</activeProfile>
</activeProfiles>
Build Maven project
To build the project, do as follows.
Right-click the main
pom.xmlfile > Run As > Maven install.
As soon as you see the BUILD SUCCESS message in the Console, create your own components.
After you add or modify the Java code, in order to execute Bot Task with changes, run Maven install again.
important
You can get the "PKIX path building failed" exception during the Maven build. It is a known issue. See more details here. To fix this, add the following JVM parameters:
MAVEN_OPTS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"
Another solution is to open the Nexus or central repo in the browser, download the certificate, and then import it to the Java TrustStore on the local machine.
Run or debug Bot Task
Now, time to test one of the pre-generated Bot Tasks execution from WorkFusion Studio.
- Open
Transaction Supplier Example.xmlfrom the [ARTIFACT]-bcb project. - Execute Run As (or Debug As) > Bot Task.

In case of Debug, make sure you firstly put breakpoints in the Java classes.
As soon as you see the EXECUTION SUCCESS message in the Console, you are ready to test Bot Tasks on the workstation.
Deploy into local Control Tower
9.3.4
Each Archetype provided by ODF generates the [ARTIFACT]-package module.

It contains a pre-configured bundle structure where you can put additional static resources if required.
Deployment on local Control Tower is similar to deployment on server Control Tower and happens using Maven goals.
Call mvn clean install and then mvn bundle:import Maven goals to create Asset Bundle and deploy to local Control Tower.
9.x
You can deploy your BCB project into your local Control Tower for initial testing. Most of automation code will be in the [ARTIFACT]-bcb module which you can deploy as BCB to Control Tower.
Make sure that:
The user specified in
settings.xmlunder server ID bcb-repository exists in local NexusThe local Nexus user has the deployment privilege on the
wf-machine-config-bundlerepository (or you can just use the default admin user with ALL proveleges)In
[ARTIFACT]/pom.xml, you have the setting specifying the Nexus repository where your JARs will be installed. Set it to local Nexus:<bcb.repository.url>http://localhost:8081/nexus/service/local/repositories/wf-machine-config-bundle/content/</bcb.repository.url>
Run
mvn deployon[ARTIFACT]-bcb/pom.xml. This command should build and deploy the project JAR into local Nexus. It can be eye-checked via Nexus UI: http://localhost:8081Go to local Control Tower > Advanced > Bot Configurations and click the Import From Repository button.
Deploy into server Control Tower
9.2.2
You can deploy an automation project using Asset Bundle Import API. Each Archetype provided by ODF generates the [ARTIFACT]-package module.

It contains a pre-configured bundle structure where you can put additional static resources if required.
To publish a bundle, use this guide that helps to understand and start using Maven goal.
9.3.4
You can deploy an automation project using Asset Bundle Import API. Each Archetype provided by ODF generates the [ARTIFACT]-package module.

It contains a pre-configured bundle structure where you can put additional static resources if required.
Use mvn clean install -Premote-deploy and then mvn bundle:import -Premote-deploy to import to server Control Tower.
warning
Known Issue: If your Project contains Business Process Package in a business-process folder, the import may fail with the message "Machine config library XXX is missing". If XXX is the BCB name that is a part of the project, repeat mvn bundle:import -Premote-deploy.
9.3.0-9.3.3, 9.4.2-9.4.3
For SPA 9.3 or SPA 9.4, Bundle Import API is not available. Thus, you can deploy your project solution by pieces. Most of automation code will be in the [ARTIFACT]-bcb module which you can deploy as BCB to Control Tower.
Make sure that:
The user specified in
settings.xmlunder server ID bcb-repository exists in Nexus (for training, we use https://repository.workfusion.com).The Nexus user should have the deployment privilege on the
wf-machine-config-bundlerepository.In
[ARTIFACT]/pom.xml, you have the setting specifying the Nexus repository where your JARs will be installed. Make sure to point it to server Nexus:<bcb.repository.url>https://some.instance.com/nexus/service/local/repositories/wf-machine-config-bundle/content/</bcb.repository.url>
Run
mvn deployon[ARTIFACT]-bcb/pom.xml. This command should build and deploy the project JAR into Nexus. You can check it via the Nexus UI: https://repository.workfusion.com/#view-repositories;wf-machine-config-bundle~browsestorage.Go to server Control Tower > Advanced > Bot Configurations and click Import From Repository.
Study project structure
In the generated boilerplate project, start from exploring the following classes and Bot Tasks.
Intake Engine example comes with AppBuilderExample, which is a class that provides nice building API.
package com.ibank.automation.invoices_usecase.app;
import com.workfusion.intake.core.App;
import com.workfusion.intake.core.Module;
import groovy.lang.Binding;
import java.util.List;
public class AppExample extends App {
protected AppExample(Binding context, List<Module> additionalModules, List<Module> overrideModules, Object injectContext) {
super(context, additionalModules, overrideModules, injectContext);
}
public static AppBuilderExample init(Binding binding) {
return new AppBuilderExample(binding);
}
}
The ModuleExample and CipherModule modules come together and are used in the AppBuilderExample class (as well as SecurityModule is used for the credentials access).
package com.ibank.automation.invoices_usecase.app;
import com.workfusion.intake.core.Module;
import groovy.lang.Binding;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AppBuilderExample {
private Binding context;
private Map<String, String> params = new HashMap<>();
private List<Module> overrideModules;
private Object injectContext;
public AppBuilderExample(Binding context) {
this.context = context;
}
public AppBuilderExample params(Map<String, String> params) {
this.setParams(params);
return this;
}
public AppBuilderExample override(Module... modules) {
overrideModules = Arrays.asList(modules);
return this;
}
public AppBuilderExample injectFields(Object context) {
this.injectContext = context;
return this;
}
public AppExample get() {
Module myModule = new ModuleExample();
Module cipherModule = new CipherModule();
Module securityModule = new SecurityModule(context);
List<Module> modules = Arrays.asList(myModule, cipherModule, securityModule);
return new AppExample(context, modules, overrideModules, injectContext);
}
public Map<String, String> getParams() {
return params;
}
public void setParams(Map<String, String> params) {
this.params = params;
}
}
The Bot Task which shows how to invoke TransactionEncryptionProcessor from XML.
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">
<script></script>
<!-- Nothing additional required to export. All data was saved inside Transaction. -->
<export include-original-data="true">
</export>
</config>
The Bot Task which shows how to invoice TransactionSupplierExample from XML.
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">
<script></script>
<export include-original-data="false">
<multi-column list="${result}" split-results="true">
<put-to-column-getter name="_sys_transaction_id" property="transaction_id"/>
</multi-column>
</export>
</config>
The Unit Testing class example for the TransactionEncryptionProcessor class.
package com.ibank.automation.invoices_usecase.processor;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import lab.lab.app.AppExample;
import com.workfusion.odf.api.domain.Document;
import com.workfusion.odf.api.domain.Transaction;
import com.workfusion.odf.core.Module;
import com.workfusion.rpa.core.plugin.s3.S3PluginAdapter;
import groovy.lang.Binding;
import com.ibank.automation.invoices_usecase.processor.TransactionEncryptionProcessor;
import lab.lab.utils.Cipher;
import org.codejargon.feather.Provides;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.slf4j.Logger;
public class TransactionEncryptionProcessorTest {
@Inject
private TransactionEncryptionProcessor transactionEncryptionProcessor;
private S3PluginAdapter s3PluginAdapter;
private Cipher cipher;
private Logger logger;
private Module testModule = new Module() {
@Provides
public S3PluginAdapter s3PluginAdapter() {
return s3PluginAdapter;
}
@Provides
public Cipher cipher() {
return cipher;
}
@Provides
public Logger logger() {
return logger;
}
};
@BeforeEach
public void init() {
s3PluginAdapter = Mockito.mock(S3PluginAdapter.class);
cipher = Mockito.mock(Cipher.class);
logger = Mockito.mock(Logger.class);
Binding binding = new Binding();
AppExample.init(binding).override(testModule).injectFields(this).get();
}
@Test
public void transform() {
//given
final Transaction transaction = getTransaction();
byte[] content = "link1.txt".getBytes();
//when
Mockito.when(s3PluginAdapter.get(Mockito.any())).thenReturn(content);
Mockito.when(cipher.encode(Mockito.any())).thenReturn(new byte[0]);
final Transaction processedTransaction = transactionEncryptionProcessor.transform(transaction);
//then
Mockito.verify(cipher, Mockito.times(1)).encode(content);
}
private Transaction getTransaction() {
final Transaction transaction = new Transaction();
transaction.setId("1");
final List<Document> docs = new ArrayList<>();
Document doc = new Document();
doc.setId("1");
doc.setTextLink("link1.txt");
docs.add(doc);
transaction.setDocs(docs);
return transaction;
}
}
The TransactionSupplier class example which generates N transactions.
package com.ibank.automation.invoices_usecase.supplier;
import com.workfusion.intake.api.connector.TransactionSupplier;
import com.workfusion.intake.api.domain.Document;
import com.workfusion.intake.api.domain.Transaction;
import com.workfusion.rpa.core.storage.S3Manager;
import org.springframework.http.MediaType;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
public class TransactionSupplierExample implements TransactionSupplier {
private S3Manager s3Manager;
@Inject
public TransactionSupplierExample(S3Manager s3Manager) {
this.s3Manager = s3Manager;
}
@Override
public Collection<Transaction> get() {
Collection<Transaction> transactions = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Transaction transaction = new Transaction();
transaction.setId(uuid());
transaction.setDocs(Arrays.asList(createDocument()));
transactions.add(transaction);
}
return transactions;
}
private Document createDocument() {
Document document = new Document();
document.setId(uuid());
document.setName("Example Document");
document.setTextLink(generateAndUploadDocument());
return document;
}
private String generateAndUploadDocument() {
return s3Manager.putFile(
uuid() + ".txt",
new ByteArrayInputStream("Some very important text".getBytes()),
MediaType.TEXT_PLAIN_VALUE);
}
private String uuid() {
return UUID.randomUUID().toString();
}
}