All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fivefaces.structureclient.domain.StructureSchemaWorkflowScaffold Maven / Gradle / Ivy

The newest version!
package com.fivefaces.structureclient.domain;

import com.fivefaces.structure.schema.StructureFieldType;
import com.fivefaces.structure.schema.StructureDefinition;
import com.fivefaces.structure.schema.StructureFieldDefinition;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class StructureSchemaWorkflowScaffold {

    public Map scaffold(StructureDefinition def) throws Exception {
        String[] roles = new String[]{"UNMANNED", "ADMIN", "PATIENT"};
        String workflowSuffix = def.getType().substring(0, 1).toUpperCase() + def.getType().substring(1);
        String validateCreateMethod = getValidateCreateMethod(workflowSuffix, def.getType(), roles, def.getFields());
        String createMethod = getCreateMethod(workflowSuffix, def.getType(), def.getFields());
        String validateUpdateMethod = getValidateUpdateMethod(workflowSuffix, def.getType(), roles, def.getFields());
        String updateMethod = getUpdateMethod(workflowSuffix, def.getType(), def.getFields());
        String validateDeleteMethod = getValidateDeleteMethod(workflowSuffix, roles);
        String deleteMethod = getDeleteMethod(workflowSuffix, def.getType());
        HashMap functions = new HashMap<>();
        functions.put("validateCreate" + workflowSuffix, validateCreateMethod);
        functions.put("create" + workflowSuffix, createMethod);
        functions.put("validateUpdate" + workflowSuffix, validateUpdateMethod);
        functions.put("update" + workflowSuffix, updateMethod);
        functions.put("validateDelete" + workflowSuffix, validateDeleteMethod);
        functions.put("delete" + workflowSuffix, deleteMethod);
        return functions;
    }

    private String getSubString(String componentString, String identifier) {
        String result = null;
        if (componentString.contains(identifier)) {
            result = componentString.substring(componentString.indexOf(identifier) + identifier.length());
            final String quoteType = identifier.substring(identifier.length() - 1);
            result = result.substring(0, result.indexOf(quoteType));
        }
        return result;
    }

    private String getCreateMethod(final String className,
                                   final String tableName,
                                   final Map fields) {
        final String input = "{\n" +
                "  \"name\": \"create%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "   \"Comment\": \"A description of my state machine\",\n" +
                "   \"StartAt\": \"Validate Create %s\",\n" +
                "   \"States\": {\n" +
                "     \"Validate Create %s\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"Resource\": \"arn:aws:states:::states:startExecution.sync\",\n" +
                "       \"Parameters\": {\n" +
                "         \"StateMachineArn\": \"arn:aws:states:ap-southeast-2:705130463218:stateMachine:${var.environment}_validateCreate%s\",\n" +
                "         \"Input\": {\n" +
                "           \"NeedCallback \": true,\n" +
                "           \"query.$\": \"$.query\",\n" +
                "           \"AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$\": \"$$.Execution.Id\"\n" +
                "         }\n" +
                "       },\n" +
                "       \"Next\": \"Save %s\",\n" +
                "       \"ResultPath\": \"$.input.validateCreate%s\"\n" +
                "     },\n" +
                "     \"Save %s\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"ResultPath\": \"$.input.save%s\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Path\": \"/structure/insert\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"username.$\": \"$.query.authorization.username\",\n" +
                "           \"type\": \"%s\",\n" +
                "           \"workflow\": \"create%s\",\n" +
                "           \"query\": {\n %s \n" +
                "           }\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"End\": true\n" +
                "     }\n" +
                "   }\n" +
                " }\n" +
                "}";

        return String.format(input, className, className, className, className, className, className, className, className,
                tableName, className, getInsertProperties(true, fields));
    }

    private String getInsertProperties(final boolean insert, Map fields) {

        final StringBuilder result = new StringBuilder();

        final StringBuilder associations = new StringBuilder("\t\t\t\"associations\": [");

        final Boolean[] hasAssociations = new Boolean[]{false};
        fields.forEach((key, value) -> {
            if (!value.isAssociation()) {
                result.append("\t\t\t\"").append(key).append(".$\": \"$.query.").append(key).append("\",\n");
            } else {
                hasAssociations[0] = true;
                if (insert) {
                    associations.append("\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"").append(value.getReferencedStructure()).append("\",\n\t\t\t\t\t\"id.$\": \"$.query.").append(key).append("\"\n\t\t\t\t},");
                }
            }
        });

        final String associationsString = associations.substring(0, associations.length() - 1) + "]";

        if (insert && associationsString.length() > 25) {
            result.append(associationsString);
            return result.toString();
        } else {

            if (hasAssociations[0]) {
                result.append("\t\t\t\"embeddedDelete.$\": \"$.query.embeddedDelete\",\n" +
                        "\t\t\t\"embeddedAdd.$\": \"$.query.embeddedAdd\"");
                return result.toString();
            }
            if (result.length() > 0) {
                return result.substring(0, result.length() - 2);
            } else {
                return result.toString();
            }

        }

    }


    private String getValidateCreateMethod(final String workflowSuffixName, final String tableName, final String[] rolesArray,
                                           final Map fields) {

        final String properties = getProperties(fields);
        final String required = getRequiredProperties(fields, false);
        final String unique = getUniqueProperties(fields);
        final String roles = getArrayProperties(rolesArray);
        final String input = "{\n" +
                "  \"name\": \"validateCreate%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "   \"Comment\": \"Check the Users Roles\",\n" +
                "   \"StartAt\": \"Check User Role\",\n" +
                "   \"States\": {\n" +
                "     \"Check User Role\": {\n" +
                "       \"Type\": \"Task\", \"ResultPath\": \"$.input.checkAuthorization\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Path\": \"/structure/hasAnyRole\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"requiredRoles\": [\n" +
                "             %s\n" +
                "           ],\n" +
                "           \"userRoles.$\": \"$.query.authorization.roles\"\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"Next\": \"Validate JSON\"\n" +
                "     },\n" +
                "     \"Validate JSON\": {\n" +
                "       \"Type\": \"Task\", \"ResultPath\": \"$.input.validateJson\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Path\": \"/structure/validate\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"type\": \"%s\",\n" +
                "           \"workflow\": \"validateCreate%s\",\n" +
                "           \"query.$\": \"$.query\",\n" +
                "           \"schema\": {\n" +
                "             \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" +
                "             \"title\": \"validateCreate%s\",\n" +
                "             \"description\": \"validateCreate%s\",\n" +
                "             \"type\": \"object\",\n" +
                "             \"properties\": {\n" +
                "%s" +
                "}\n" +
                "             },\n" +
                "             \"required\": [%s],\n" +
                "             \"unique\": [%s]\n" +
                "           }\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"End\": true\n" +
                "     }\n" +
                "   }\n" +
                " }\n" +
                "}";

        return String.format(input, workflowSuffixName, roles, tableName, workflowSuffixName, workflowSuffixName, workflowSuffixName, properties, required, unique);
    }

    private String getValidateUpdateMethod(final String className, final String tableName, final String[] rolesArray,
                                           final Map fields) {

        final String properties = getProperties(fields);
        final String required = getRequiredProperties(fields, true);
        final String unique = getUniqueProperties(fields);
        final String roles = getArrayProperties(rolesArray);
        final String input = "{\n" +
                "  \"name\": \"validateUpdate%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "  \"Comment\": \"A description of my state machine\",\n" +
                "  \"StartAt\": \"Check User Role\",\n" +
                "  \"States\": {\n" +
                "    \"Check User Role\": {\n" +
                "      \"Type\": \"Task\", \"ResultPath\": \"$.input.checkAuthorization\",\n" +
                "      \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "      \"Parameters\": {\n" +
                "        \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "        \"Path\": \"/structure/hasAnyRole\",\n" +
                "        \"Method\": \"POST\",\n" +
                "        \"Headers\": {\n" +
                "          \"Content-Type\": [\n" +
                "            \"application/json\"\n" +
                "          ]\n" +
                "        },\n" +
                "        \"RequestBody\": {\n" +
                "           \"requiredRoles\": [\n" +
                "             %s\n" +
                "           ],\n" +
                "           \"userRoles.$\": \"$.query.authorization.roles\"\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "      },\n" +
                "      \"Next\": \"Validate JSON\"\n" +
                "    },\n" +
                "    \"Validate JSON\": {\n" +
                "      \"Type\": \"Task\", \"ResultPath\": \"$.input.validateJson\",\n" +
                "      \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "      \"Parameters\": {\n" +
                "        \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "        \"Method\": \"POST\",\n" +
                "        \"Path\": \"/structure/validate\",\n" +
                "        \"Headers\": {\n" +
                "          \"Content-Type\": [\n" +
                "            \"application/json\"\n" +
                "          ]\n" +
                "        },\n" +
                "        \"RequestBody\": {\n" +
                "          \"type\": \"%s\",\n" +
                "          \"updateId.$\": \"$.query.id\",\n" +
                "          \"workflow\": \"validateUpdate%s\",\n" +
                "          \"query.$\": \"$.query\",\n" +
                "          \"schema\": {\n" +
                "            \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" +
                "            \"title\": \"validateUpdate%s\",\n" +
                "            \"description\": \"validateUpdate%s\",\n" +
                "            \"type\": \"object\",\n" +
                "              \"properties\": {\n" +
                "             \"id\": {\n" +
                "                \"description\": \"id\",\n" +
                "                \"type\": \"string\",\"minLength\":1\n" +
                "              },\n" +
                "              \"version\": {\n" +
                "                \"description\": \"version\",\n" +
                "                \"type\": \"integer\"\n" +
                "              },\n" +
                "%s\n" +
                "              }\n" +
                "            },\n" +
                "            \"required\": [%s],\n" +
                "            \"unique\": [%s]\n" +
                "          }\n" +
                "        },\n" +
                "        \"AuthType\": \"IAM_ROLE\"\n" +
                "      },\n" +
                "      \"End\": true\n" +
                "    }\n" +
                "  }\n" +
                "}\n" +
                "}";

        return String.format(input, className, roles, tableName, className, className, className, properties, required, unique);
    }

    private String getUpdateMethod(final String className,
                                   final String tableName,
                                   final Map fields) {
        final String input = "{\n" +
                "  \"name\": \"update%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "  \"Comment\": \"A description of my state machine\",\n" +
                "  \"StartAt\": \"Validate Update %s\",\n" +
                "  \"States\": {\n" +
                "    \"Validate Update %s\": {\n" +
                "      \"Type\": \"Task\",\n" +
                "      \"Resource\": \"arn:aws:states:::states:startExecution.sync\",\n" +
                "      \"Parameters\": {\n" +
                "        \"StateMachineArn\": \"arn:aws:states:ap-southeast-2:705130463218:stateMachine:${var.environment}_validateUpdate%s\",\n" +
                "        \"Input\": {\n" +
                "          \"NeedCallback \": true,\n" +
                "          \"query.$\": \"$.query\",\n" +
                "          \"AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$\": \"$$.Execution.Id\"\n" +
                "        }\n" +
                "      },\n" +
                "      \"Next\": \"Update %s\",\n" +
                "      \"ResultPath\": \"$.input.validateUpdate%s\"\n" +
                "    },\n" +
                "    \"Update %s\": {\n" +
                "      \"Type\": \"Task\",\n" +
                "      \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "      \"Parameters\": {\n" +
                "        \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "        \"Path\": \"/structure/update\",\n" +
                "        \"Method\": \"POST\",\n" +
                "        \"Headers\": {\n" +
                "          \"Content-Type\": [\n" +
                "            \"application/json\"\n" +
                "          ]\n" +
                "        },\n" +
                "        \"RequestBody\": {\n" +
                "          \"username.$\": \"$.query.authorization.username\",\n" +
                "          \"type\": \"%s\",\n" +
                "           \"id.$\": \"$.query.id\",\n" +
                "           \"version.$\": \"$.query.version\",\n" +
                "           \"query\": {\n" +
                "            \"id.$\": \"$.query.id\",\n" +
                "%s\n" +
                "            }\n" +
                "        },\n" +
                "        \"AuthType\": \"IAM_ROLE\"\n" +
                "      },\n" +
                "      \"End\": true\n" +
                "    }\n" +
                "  }\n" +
                "}\n" +
                "}";

        return String.format(input, className, className, className, className, className, className, className,
                tableName,
                getInsertProperties(false, fields));
    }

    private String getValidateDeleteMethod(final String className, final String[] rolesArray) {

        final String roles = getArrayProperties(rolesArray);
        final String input = "{\n" +
                "  \"name\": \"validateDelete%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "   \"Comment\": \"Validate Delete %s\",\n" +
                "   \"StartAt\": \"Check User Role\",\n" +
                "   \"States\": {\n" +
                "     \"Check User Role\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Path\": \"/structure/hasAnyRole\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"requiredRoles\": [\n" +
                "             %s\n" +
                "           ],\n" +
                "           \"userRoles.$\": \"$.query.authorization.roles\"\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"ResultPath\": \"$.input.checkAuthorization\",\n" +
                "       \"Next\": \"Validate JSON\"\n" +
                "     },\n" +
                "     \"Validate JSON\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Path\": \"/structure/validate\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"workflow\": \"validateDelete%s\",\n" +
                "           \"query.$\": \"$.query\",\n" +
                "           \"schema\": {\n" +
                "             \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" +
                "             \"title\": \"validateDelete%s\",\n" +
                "             \"description\": \"validateDelete%s\",\n" +
                "             \"type\": \"object\",\n" +
                "             \"properties\": {\n" +
                "               \"id\": {\n" +
                "                 \"description\": \"id\",\n" +
                "                 \"type\": \"string\",\"minLength\":1\n" +
                "               }\n" +
                "             },\n" +
                "             \"required\": [\n" +
                "               \"id\"\n" +
                "             ]\n" +
                "           }\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"End\": true\n" +
                "     }\n" +
                "   }\n" +
                " }\n" +
                "}";

        return String.format(input, className, className, roles, className, className, className);
    }

    private String getDeleteMethod(final String className,
                                   final String tableName) {

        final String input = "{\n" +
                "  \"name\": \"delete%s\",\n" +
                "  \"functionDefinition\": {\n" +
                "   \"Comment\": \"Delete %s\",\n" +
                "   \"StartAt\": \"Validate Delete %s\",\n" +
                "   \"States\": {\n" +
                "     \"Validate Delete %s\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"Resource\": \"arn:aws:states:::states:startExecution.sync\",\n" +
                "       \"Parameters\": {\n" +
                "         \"StateMachineArn\": \"arn:aws:states:ap-southeast-2:705130463218:stateMachine:${var.environment}_validateDelete%s\",\n" +
                "         \"Input\": {\n" +
                "           \"NeedCallback \": true,\n" +
                "           \"query.$\": \"$.query\",\n" +
                "           \"AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$\": \"$$.Execution.Id\"\n" +
                "         }\n" +
                "       },\n" +
                "       \"Next\": \"Delete %s\",\n" +
                "       \"ResultPath\": \"$.input.validateDelete%s\"\n" +
                "     },\n" +
                "     \"Delete %s\": {\n" +
                "       \"Type\": \"Task\",\n" +
                "       \"Resource\": \"arn:aws:states:::apigateway:invoke\",\n" +
                "       \"Parameters\": {\n" +
                "         \"ApiEndpoint\": \"${var.structureEndpoint}\",\n" +
                "         \"Path\": \"/structure/delete\",\n" +
                "         \"Method\": \"POST\",\n" +
                "         \"Headers\": {\n" +
                "           \"Content-Type\": [\n" +
                "             \"application/json\"\n" +
                "           ]\n" +
                "         },\n" +
                "         \"RequestBody\": {\n" +
                "           \"type\": \"%s\",\n" +
                "           \"id.$\": \"$.query.id\",\n" +
                "           \"criteria\": [\n" +
                "             {\n" +
                "               \"member\": \"$.id\",\n" +
                "               \"type\": \"eq\",\n" +
                "               \"string\": true,\n" +
                "               \"value.$\": \"$.query.id\"\n" +
                "             }\n" +
                "           ]\n" +
                "         },\n" +
                "         \"AuthType\": \"IAM_ROLE\"\n" +
                "       },\n" +
                "       \"End\": true\n" +
                "     }\n" +
                "   }\n" +
                " }\n" +
                "}";

        return String.format(input, className, className, className, className, className, className, className, className, tableName);
    }

    private String getProperties(Map fields) {

        final StringBuilder result = new StringBuilder();

        fields.forEach((key, value) -> {
            if (value.getType().equals(StructureFieldType.STRING)) {
                result.append("\t\t\t\t\"").append(key).append("\": {\n");
                result.append("\t\t\t\t\t\"description\": \"").append(key).append("\",\n");
                result.append("\t\t\t\t\t\"type\": \"").append("string").append("\"");
                if (StringUtils.isNotBlank(value.getMin())) {
                    result.append(",\"minLength\":").append(value.getMin());
                }
                if (StringUtils.isNotBlank(value.getMax())) {
                    result.append(",\"maxLength\":").append(value.getMax());
                }
                result.append("\n\t\t\t\t},\n");
            } else if (List.of(StructureFieldType.DATETIME, StructureFieldType.DATE, StructureFieldType.TIME).contains(value.getType())) {
                result.append("\t\t\t\t\"").append(key).append("\": {\n");
                result.append("\t\t\t\t\t\"description\": \"").append(key).append("\",\n");
                result.append("\t\t\t\t\t\"type\": \"").append(value.getType().getJsonType()).append("\",\"format\": \"").append(value.getType().getJsonFormat()).append("\"");
                result.append("\n\t\t\t\t},\n");
            } else {
                result.append("\t\t\t\t\"").append(key).append("\": {\n");
                result.append("\t\t\t\t\t\"description\": \"").append(key).append("\",\n");
                result.append("\t\t\t\t\t\"type\": \"").append(value.getType().getJsonType()).append("\"");
                result.append("\n\t\t\t\t},\n");
            }
        });

        if (result.indexOf(",") >= 0) {
            return result.substring(0, result.lastIndexOf(",") - 1);
        } else {
            return result.toString();
        }
    }

    private String getRequiredProperties(Map fields,
                                         final boolean update) {

        final StringBuilder result = new StringBuilder();
        fields.forEach((key, value) -> {
            if (value.isRequired()) {
                if (value.getType().equals(StructureFieldType.STRING) && update && value.isAssociation()) {
                    // not adding associations to update as they will be done with embedded
                } else {
                    result.append("\"").append(key).append("\",");
                }
            }
        });
        if (update) {
            result.append("\"id\",");
        }

        if (result.indexOf(",") >= 0) {
            return result.substring(0, result.length() - 1);
        } else {
            return result.toString();
        }
    }

    private String getUniqueProperties(Map fields) {
        final StringBuilder result = new StringBuilder();
        fields.forEach((key, value) -> {
            if (value.isUnique()) {
                result.append("\"").append(key).append("\",");
            }
        });
        if (result.length() > 0) {
            return result.substring(0, result.length() - 1);
        } else {
            return "";
        }
    }

    private String getArrayProperties(final String[] values) {
        if (values.length == 0) {
            return "";
        }
        final StringBuilder result = new StringBuilder();
        for (String role : values) {
            result.append("\"").append(role).append("\",");
        }
        return result.substring(0, result.length() - 1);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy