Skip to content

Commit

Permalink
v1.8.7 (#42)
Browse files Browse the repository at this point in the history
* Added addPdfDetectedCharactersAsText option to /ocr API

* #36 - Update Console Install Lambda to remove Console on delete

* #29 - Add list of installed Modules to /versions

* #39 - Add OpenAPI spec to Release Zip

* updated aws-cognito library to 1.4.2

* Added ActionStatus 'RUNNING'

* Fixed bug resetting document actions when document is updated
  • Loading branch information
mfriesen committed Sep 18, 2022
1 parent 58e5ed6 commit 909a8e0
Show file tree
Hide file tree
Showing 106 changed files with 2,379 additions and 2,119 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ The following are AWS CloudFormation scripts that can be used to install FormKiQ

| AWS Region | Install Link |
| ------------- | -------------|
| us-east-1 | [Install FormKiQ Core in US-EAST-1 region](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-us-east-1.s3.amazonaws.com/1.8.6/template.yaml)
| us-east-2 | [Install FormKiQ Core in US-EAST-2 region](https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-us-east-2.s3.amazonaws.com/1.8.6/template.yaml)
| ca-central-1| [Install FormKiQ Core in CA-CENTRAL-1 region](https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-ca-central-1.s3.amazonaws.com/1.8.6/template.yaml)
| eu-central-1| [Install FormKiQ Core in EU-CENTRAL-1 region](https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-eu-central-1.s3.amazonaws.com/1.8.6/template.yaml)
| us-east-1 | [Install FormKiQ Core in US-EAST-1 region](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-us-east-1.s3.amazonaws.com/1.8.7/template.yaml)
| us-east-2 | [Install FormKiQ Core in US-EAST-2 region](https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-us-east-2.s3.amazonaws.com/1.8.7/template.yaml)
| ca-central-1| [Install FormKiQ Core in CA-CENTRAL-1 region](https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-ca-central-1.s3.amazonaws.com/1.8.7/template.yaml)
| eu-central-1| [Install FormKiQ Core in EU-CENTRAL-1 region](https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?stackName=formkiq-core-prod&templateURL=https://formkiq-core-distribution-eu-central-1.s3.amazonaws.com/1.8.7/template.yaml)

## Architecture

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public enum ActionStatus {
FAILED,
/** Pending. */
PENDING,
/** Running. */
RUNNING,
/** Skipped. */
SKIPPED;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@
*/
public interface ActionsService {

/**
* Delete Document Actions.
*
* @param siteId {@link String}
* @param documentId {@link String}
*/
void deleteActions(String siteId, String documentId);

/**
* Get Action Parameters.
*
* @param siteId {@link String}
* @param documentId {@link String}
* @param type {@link ActionType}
* @return {@link Map}
*/
Map<String, String> getActionParameters(String siteId, String documentId, ActionType type);

/**
* Get {@link List} {@link Action} for a document.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,27 @@

import static com.formkiq.aws.dynamodb.SiteIdKeyGenerator.createDatabaseKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.formkiq.aws.dynamodb.DbKeys;
import com.formkiq.aws.dynamodb.DynamoDbConnectionBuilder;
import com.formkiq.aws.dynamodb.objects.Objects;
import com.formkiq.module.actions.Action;
import com.formkiq.module.actions.ActionStatus;
import com.formkiq.module.actions.ActionType;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate;
import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemRequest;
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest.Builder;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.WriteRequest;
Expand All @@ -52,28 +57,60 @@
*/
public class ActionsServiceDynamoDb implements ActionsService, DbKeys {

/** {@link DynamoDbClient}. */
private DynamoDbClient dbClient;
/** Document Table Name. */
private String documentTableName;
/** {@link DynamoDbClient}. */
private DynamoDbClient dynamoDB;

/**
* constructor.
*
* @param builder {@link DynamoDbConnectionBuilder}
* @param connection {@link DynamoDbConnectionBuilder}
* @param documentsTable {@link String}
*/
public ActionsServiceDynamoDb(final DynamoDbConnectionBuilder builder,
public ActionsServiceDynamoDb(final DynamoDbConnectionBuilder connection,
final String documentsTable) {

if (documentsTable == null) {
throw new IllegalArgumentException("Table name is null");
}

this.dynamoDB = builder.build();
this.dbClient = connection.build();
this.documentTableName = documentsTable;
}

@Override
public void deleteActions(final String siteId, final String documentId) {

List<Action> actions = queryActions(siteId, documentId, Arrays.asList(PK, SK, "type"), null);

int index = 0;
for (Action action : actions) {

String pk = getPk(siteId, documentId);
String sk = getSk(action, index);

Map<String, AttributeValue> key = Map.of(PK, AttributeValue.builder().s(pk).build(), SK,
AttributeValue.builder().s(sk).build());

this.dbClient.deleteItem(
DeleteItemRequest.builder().tableName(this.documentTableName).key(key).build());

index++;
}
}

@Override
public Map<String, String> getActionParameters(final String siteId, final String documentId,
final ActionType type) {

List<Action> actions = Objects
.notNull(queryActions(siteId, documentId, Arrays.asList("type", "parameters"), null));

Optional<Action> op = actions.stream().filter(a -> a.type().equals(type)).findFirst();
return op.isPresent() ? op.get().parameters() : null;
}

@Override
public List<Action> getActions(final String siteId, final String documentId) {
return queryActions(siteId, documentId, null, null);
Expand Down Expand Up @@ -103,7 +140,7 @@ private String getSk(final Action action, final int idx) {

@Override
public boolean hasActions(final String siteId, final String documentId) {
List<Action> actions = queryActions(siteId, documentId, PK, null);
List<Action> actions = queryActions(siteId, documentId, Arrays.asList(PK), null);
return !actions.isEmpty();
}

Expand All @@ -112,12 +149,12 @@ public boolean hasActions(final String siteId, final String documentId) {
*
* @param siteId {@link String}
* @param documentId {@link String}
* @param projectionExpression {@link String}
* @param projectionExpression {@link List} {@link String}
* @param limit {@link Integer}
* @return {@link List} {@link Action}
*/
private List<Action> queryActions(final String siteId, final String documentId,
final String projectionExpression, final Integer limit) {
final List<String> projectionExpression, final Integer limit) {

String pk = getPk(siteId, documentId);
String sk = "action" + TAG_DELIMINATOR;
Expand All @@ -126,11 +163,22 @@ private List<Action> queryActions(final String siteId, final String documentId,
Map<String, AttributeValue> values = Map.of(":pk", AttributeValue.builder().s(pk).build(),
":sk", AttributeValue.builder().s(sk).build());

QueryRequest q = QueryRequest.builder().tableName(this.documentTableName)
.keyConditionExpression(expression).expressionAttributeValues(values)
.projectionExpression(projectionExpression).limit(limit).build();
Builder q = QueryRequest.builder().tableName(this.documentTableName)
.keyConditionExpression(expression).expressionAttributeValues(values).limit(limit);

if (!Objects.notNull(projectionExpression).isEmpty()) {

QueryResponse result = this.dynamoDB.query(q);
Map<String, String> names = new HashMap<>();
int i = 1;
for (String p : projectionExpression) {
names.put("#" + i, p);
i++;
}

q = q.projectionExpression(String.join(",", names.keySet())).expressionAttributeNames(names);
}

QueryResponse result = this.dbClient.query(q.build());

AttributeValueToAction transform = new AttributeValueToAction();
return result.items().stream().map(r -> transform.apply(r)).collect(Collectors.toList());
Expand Down Expand Up @@ -173,7 +221,7 @@ public List<Map<String, AttributeValue>> saveActions(final String siteId, final
Map<String, Collection<WriteRequest>> items = Map.of(this.documentTableName, list);

BatchWriteItemRequest batch = BatchWriteItemRequest.builder().requestItems(items).build();
this.dynamoDB.batchWriteItem(batch);
this.dbClient.batchWriteItem(batch);

return values;
}
Expand All @@ -192,7 +240,7 @@ public void updateActionStatus(final String siteId, final String documentId, fin
values.put("status", AttributeValueUpdate.builder()
.value(AttributeValue.builder().s(action.status().name()).build()).build());

this.dynamoDB.updateItem(UpdateItemRequest.builder().tableName(this.documentTableName).key(key)
this.dbClient.updateItem(UpdateItemRequest.builder().tableName(this.documentTableName).key(key)
.attributeUpdates(values).build());
}

Expand All @@ -201,10 +249,12 @@ public List<Action> updateActionStatus(final String siteId, final String documen
final ActionType type, final ActionStatus status) {

int idx = 0;
NextActionPredicate pred = new NextActionPredicate();

List<Action> actionlist = getActions(siteId, documentId);

for (Action action : actionlist) {
if (pred.test(action) && action.type().equals(type)) {

if (!ActionStatus.COMPLETE.equals(action.status()) && action.type().equals(type)) {
action.status(status);
updateActionStatus(siteId, documentId, action, idx);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ public ActionsServiceExtension() {
public ActionsService loadService(final AwsServiceCache awsServiceCache) {

if (this.service == null) {
DynamoDbConnectionBuilder db = awsServiceCache.getExtension(DynamoDbConnectionBuilder.class);
this.service = new ActionsServiceDynamoDb(db, awsServiceCache.environment("DOCUMENTS_TABLE"));
DynamoDbConnectionBuilder connection =
awsServiceCache.getExtension(DynamoDbConnectionBuilder.class);
this.service =
new ActionsServiceDynamoDb(connection, awsServiceCache.environment("DOCUMENTS_TABLE"));
}

return this.service;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@
@ExtendWith(DynamoDbExtension.class)
public class ActionsServiceDynamoDbTest {

/** {@link ActionsService}. */
private static ActionsService service;
/** {@link DocumentService}. */
private static DocumentService documentService;
/** {@link ActionsService}. */
private static ActionsService service;

/**
* BeforeAll.
Expand Down Expand Up @@ -91,6 +91,54 @@ public void hasActions01() {
}
}

/**
* Test Delete Document & Document Actions.
*/
@Test
public void testDeleteDocument() {
for (String siteId : Arrays.asList(null, UUID.randomUUID().toString())) {
// given
String documentId = UUID.randomUUID().toString();
DocumentItem item = new DocumentItemDynamoDb(documentId, new Date(), "joe");
documentService.saveDocument(siteId, item, null);

Action action0 =
new Action().type(ActionType.OCR).userId("joe").parameters(Map.of("test", "1234"));
service.saveActions(siteId, documentId, Arrays.asList(action0));

// when
documentService.deleteDocument(siteId, documentId);

// then
List<Action> actions = service.getActions(siteId, documentId);
assertEquals(0, actions.size());
}
}

/**
* Test Document Actions.
*/
@Test
public void testDeleteDocumentActions() {
for (String siteId : Arrays.asList(null, UUID.randomUUID().toString())) {
// given
String documentId = UUID.randomUUID().toString();
DocumentItem item = new DocumentItemDynamoDb(documentId, new Date(), "joe");
documentService.saveDocument(siteId, item, null);

Action action0 =
new Action().type(ActionType.OCR).userId("joe").parameters(Map.of("test", "1234"));
service.saveActions(siteId, documentId, Arrays.asList(action0));

// when
service.deleteActions(siteId, documentId);

// then
List<Action> actions = service.getActions(siteId, documentId);
assertEquals(0, actions.size());
}
}

/**
* Test Action.
*
Expand All @@ -111,11 +159,15 @@ public void testSave01() throws Exception {
new Action().type(ActionType.OCR).userId(userId1).status(ActionStatus.COMPLETE);

// when
List<Map<String, AttributeValue>> list =
final List<Map<String, AttributeValue>> list =
service.saveActions(siteId, documentId0, Arrays.asList(action0));
service.saveActions(siteId, documentId1, Arrays.asList(action1));

// then
assertEquals("{test=1234}",
service.getActionParameters(siteId, documentId0, ActionType.OCR).toString());
assertNull(service.getActionParameters(siteId, documentId1, ActionType.OCR));

assertEquals(1, list.size());
if (siteId != null) {
assertEquals(siteId + "/docs#" + documentId0, list.get(0).get("PK").s());
Expand Down Expand Up @@ -171,28 +223,4 @@ public void testUpdateActionStatus01() {
assertEquals(ActionStatus.COMPLETE, service.getActions(siteId, documentId).get(0).status());
}
}

/**
* Test Delete Document & Document Actions.
*/
@Test
public void testDeleteDocument() {
for (String siteId : Arrays.asList(null, UUID.randomUUID().toString())) {
// given
String documentId = UUID.randomUUID().toString();
DocumentItem item = new DocumentItemDynamoDb(documentId, new Date(), "joe");
documentService.saveDocument(siteId, item, null);

Action action0 =
new Action().type(ActionType.OCR).userId("joe").parameters(Map.of("test", "1234"));
service.saveActions(siteId, documentId, Arrays.asList(action0));

// when
documentService.deleteDocument(siteId, documentId);

// then
List<Action> actions = service.getActions(siteId, documentId);
assertEquals(0, actions.size());
}
}
}
Loading

0 comments on commit 909a8e0

Please sign in to comment.