Search in sources :

Example 1 with Metadata

use of io.automatiko.engine.workflow.process.executable.core.Metadata in project automatiko-engine by automatiko-io.

the class MessageProducerGenerator method generate.

public String generate() {
    String sanitizedName = CodegenUtils.triggerSanitizedName(trigger, process.getVersion());
    String connector = CodegenUtils.getConnector(OUTGOING_PROP_PREFIX + sanitizedName + ".connector", context, (String) trigger.getContext("connector"));
    if (connector != null) {
        context.setApplicationProperty(OUTGOING_PROP_PREFIX + sanitizedName + ".connector", connector);
        appendConnectorSpecificProperties(connector);
    }
    CompilationUnit clazz = parse(this.getClass().getResourceAsStream(producerTemplate(connector)));
    clazz.setPackageDeclaration(process.getPackageName());
    // add functions so they can be easily accessed in message producer classes
    clazz.addImport(new ImportDeclaration(BaseFunctions.class.getCanonicalName(), true, true));
    context.getBuildContext().classThatImplement(Functions.class.getCanonicalName()).forEach(c -> clazz.addImport(new ImportDeclaration(c, true, true)));
    ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).get();
    template.setName(resourceClazzName);
    template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, trigger.getDataType()));
    template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateEventTypes(cls, messageDataEventClassName));
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("produce")).forEach(md -> {
        md.getParameters().stream().filter(p -> p.getNameAsString().equals(EVENT_DATA_VAR)).forEach(p -> p.setType(trigger.getDataType()));
        if (context.getBuildContext().hasClassAvailable("org.eclipse.microprofile.opentracing.Traced")) {
            md.addAnnotation("org.eclipse.microprofile.opentracing.Traced");
        }
    });
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("configure")).forEach(md -> md.addAnnotation("javax.annotation.PostConstruct"));
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("marshall")).forEach(md -> {
        md.getParameters().stream().filter(p -> p.getNameAsString().equals(EVENT_DATA_VAR)).forEach(p -> p.setType(trigger.getDataType()));
        md.findAll(ClassOrInterfaceType.class).forEach(t -> t.setName(t.getNameAsString().replace("$DataEventType$", messageDataEventClassName)));
    });
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("convert")).forEach(md -> {
        md.setType(md.getTypeAsString().replace("$DataType$", trigger.getDataType()));
        md.findAll(CastExpr.class).forEach(c -> c.setType(c.getTypeAsString().replace("$DataType$", trigger.getDataType())));
        md.findAll(ClassOrInterfaceType.class).forEach(t -> t.setName(t.getNameAsString().replace("$DataType$", trigger.getDataType())));
    });
    // used by MQTT to get topic name based on expression
    String topicExpression = (String) trigger.getContext("topicExpression");
    if (topicExpression != null) {
        template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("topic")).forEach(md -> {
            BlockStmt body = new BlockStmt();
            ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName());
            if (topicExpression.contains("id")) {
                VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "id");
                body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getId"), AssignExpr.Operator.ASSIGN));
            }
            if (topicExpression.contains("businessKey")) {
                VariableDeclarationExpr businessKeyField = new VariableDeclarationExpr(stringType, "businessKey");
                body.addStatement(new AssignExpr(businessKeyField, new MethodCallExpr(new NameExpr("pi"), "getCorrelationKey"), AssignExpr.Operator.ASSIGN));
            }
            VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
            for (Variable var : variableScope.getVariables()) {
                if (topicExpression.contains(var.getSanitizedName())) {
                    ClassOrInterfaceType varType = new ClassOrInterfaceType(null, var.getType().getStringType());
                    VariableDeclarationExpr v = new VariableDeclarationExpr(varType, var.getSanitizedName());
                    body.addStatement(new AssignExpr(v, new CastExpr(varType, new MethodCallExpr(new MethodCallExpr(new NameExpr("pi"), "getVariables"), "get").addArgument(new StringLiteralExpr(var.getName()))), AssignExpr.Operator.ASSIGN));
                }
            }
            body.addStatement(new ReturnStmt(new NameExpr(topicExpression)));
            md.setBody(body);
        });
    }
    // used by AMQP to get address name based on expression
    String addressExpression = (String) trigger.getContext("addressExpression");
    if (addressExpression != null) {
        template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("address")).forEach(md -> {
            BlockStmt body = new BlockStmt();
            ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName());
            if (addressExpression.contains("id")) {
                VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "id");
                body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getId"), AssignExpr.Operator.ASSIGN));
            }
            if (addressExpression.contains("businessKey")) {
                VariableDeclarationExpr businessKeyField = new VariableDeclarationExpr(stringType, "businessKey");
                body.addStatement(new AssignExpr(businessKeyField, new MethodCallExpr(new NameExpr("pi"), "getCorrelationKey"), AssignExpr.Operator.ASSIGN));
            }
            VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
            for (Variable var : variableScope.getVariables()) {
                if (addressExpression.contains(var.getSanitizedName())) {
                    ClassOrInterfaceType varType = new ClassOrInterfaceType(null, var.getType().getStringType());
                    VariableDeclarationExpr v = new VariableDeclarationExpr(varType, var.getSanitizedName());
                    body.addStatement(new AssignExpr(v, new CastExpr(varType, new MethodCallExpr(new MethodCallExpr(new NameExpr("pi"), "getVariables"), "get").addArgument(new StringLiteralExpr(var.getName()))), AssignExpr.Operator.ASSIGN));
                }
            }
            body.addStatement(new ReturnStmt(new NameExpr(addressExpression)));
            md.setBody(body);
        });
    }
    // used by FunctionFlow to set subject (used by reply to)
    String subjectExpression = (String) trigger.getContext("subjectExpression");
    if (subjectExpression != null) {
        template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("subject")).forEach(md -> {
            BlockStmt body = new BlockStmt();
            ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName());
            if (subjectExpression.contains("id")) {
                VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "id");
                body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getId"), AssignExpr.Operator.ASSIGN));
            }
            if (subjectExpression.contains("businessKey")) {
                VariableDeclarationExpr businessKeyField = new VariableDeclarationExpr(stringType, "businessKey");
                body.addStatement(new AssignExpr(businessKeyField, new MethodCallExpr(new NameExpr("pi"), "getCorrelationKey"), AssignExpr.Operator.ASSIGN));
            }
            if (subjectExpression.contains("referenceId")) {
                VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "referenceId");
                body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getReferenceId"), AssignExpr.Operator.ASSIGN));
            }
            VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
            for (Variable var : variableScope.getVariables()) {
                if (subjectExpression.contains(var.getSanitizedName())) {
                    ClassOrInterfaceType varType = new ClassOrInterfaceType(null, var.getType().getStringType());
                    VariableDeclarationExpr v = new VariableDeclarationExpr(varType, var.getSanitizedName());
                    body.addStatement(new AssignExpr(v, new CastExpr(varType, new MethodCallExpr(new MethodCallExpr(new NameExpr("pi"), "getVariables"), "get").addArgument(new StringLiteralExpr(var.getName()))), AssignExpr.Operator.ASSIGN));
                }
            }
            body.addStatement(new ReturnStmt(new NameExpr(subjectExpression)));
            md.setBody(body);
        });
    }
    // Camal or HTTP headers
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("headers")).forEach(md -> {
        StringBuilder allHeaderValues = new StringBuilder();
        for (Entry<String, Object> entry : trigger.getContext().entrySet()) {
            if (entry.getKey().startsWith("Camel") || entry.getKey().startsWith("HTTP")) {
                allHeaderValues.append(entry.getValue().toString()).append(" ");
            }
        }
        String allHeaderValuesStr = allHeaderValues.toString();
        BlockStmt body = new BlockStmt();
        ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName());
        if (allHeaderValuesStr.contains("id")) {
            VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "id");
            body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getId"), AssignExpr.Operator.ASSIGN));
        }
        if (allHeaderValuesStr.contains("businessKey")) {
            VariableDeclarationExpr businessKeyField = new VariableDeclarationExpr(stringType, "businessKey");
            body.addStatement(new AssignExpr(businessKeyField, new MethodCallExpr(new NameExpr("pi"), "getCorrelationKey"), AssignExpr.Operator.ASSIGN));
        }
        VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
        for (Variable var : variableScope.getVariables()) {
            if (allHeaderValuesStr.contains(var.getSanitizedName())) {
                ClassOrInterfaceType varType = new ClassOrInterfaceType(null, var.getType().getStringType());
                VariableDeclarationExpr v = new VariableDeclarationExpr(varType, var.getSanitizedName());
                body.addStatement(new AssignExpr(v, new CastExpr(varType, new MethodCallExpr(new MethodCallExpr(new NameExpr("pi"), "getVariables"), "get").addArgument(new StringLiteralExpr(var.getName()))), AssignExpr.Operator.ASSIGN));
            }
        }
        for (Entry<String, Object> entry : trigger.getContext().entrySet()) {
            if (entry.getKey().startsWith("Camel")) {
                body.addStatement(new MethodCallExpr(new NameExpr("metadata"), "putHeader").addArgument(new StringLiteralExpr(entry.getKey())).addArgument(new NameExpr(entry.getValue().toString())));
            } else if (entry.getKey().startsWith("HTTP")) {
                body.addStatement(new MethodCallExpr(new NameExpr("builder"), "addHeader").addArgument(new StringLiteralExpr(entry.getKey().replaceFirst("HTTP", ""))).addArgument(new NameExpr(entry.getValue().toString())));
            }
        }
        if (!md.getTypeAsString().equalsIgnoreCase("void")) {
            body.addStatement(new ReturnStmt(new NameExpr("metadata")));
        }
        md.setBody(body);
    });
    // JMS properties
    template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("properties")).forEach(md -> {
        StringBuilder allHeaderValues = new StringBuilder();
        for (Entry<String, Object> entry : trigger.getContext().entrySet()) {
            if (entry.getKey().startsWith("JMS")) {
                allHeaderValues.append(entry.getValue().toString()).append(" ");
            }
        }
        String allHeaderValuesStr = allHeaderValues.toString();
        BlockStmt body = new BlockStmt();
        ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName());
        if (allHeaderValuesStr.contains("id")) {
            VariableDeclarationExpr idField = new VariableDeclarationExpr(stringType, "id");
            body.addStatement(new AssignExpr(idField, new MethodCallExpr(new NameExpr("pi"), "getId"), AssignExpr.Operator.ASSIGN));
        }
        if (allHeaderValuesStr.contains("businessKey")) {
            VariableDeclarationExpr businessKeyField = new VariableDeclarationExpr(stringType, "businessKey");
            body.addStatement(new AssignExpr(businessKeyField, new MethodCallExpr(new NameExpr("pi"), "getCorrelationKey"), AssignExpr.Operator.ASSIGN));
        }
        VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
        for (Variable var : variableScope.getVariables()) {
            if (allHeaderValuesStr.contains(var.getSanitizedName())) {
                ClassOrInterfaceType varType = new ClassOrInterfaceType(null, var.getType().getStringType());
                VariableDeclarationExpr v = new VariableDeclarationExpr(varType, var.getSanitizedName());
                body.addStatement(new AssignExpr(v, new CastExpr(varType, new MethodCallExpr(new MethodCallExpr(new NameExpr("pi"), "getVariables"), "get").addArgument(new StringLiteralExpr(var.getName()))), AssignExpr.Operator.ASSIGN));
            }
        }
        for (Entry<String, Object> entry : trigger.getContext().entrySet()) {
            if (entry.getKey().startsWith("JMS")) {
                body.addStatement(new MethodCallExpr(new NameExpr("builder"), "with").addArgument(new StringLiteralExpr(entry.getKey().replaceFirst("JMS", ""))).addArgument(new NameExpr(entry.getValue().toString())));
            }
        }
        body.addStatement(new ReturnStmt(new NameExpr("builder")));
        md.setBody(body);
    });
    template.findAll(MethodDeclaration.class).forEach(md -> {
        md.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$Trigger$", trigger.getName())));
    });
    template.findAll(MethodDeclaration.class).forEach(md -> {
        md.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$TriggerType$", (String) trigger.getContext(Metadata.TRIGGER_TYPE_ATTR, trigger.getName()))));
    });
    if (useInjection()) {
        annotator.withApplicationComponent(template);
        template.findAll(FieldDeclaration.class, fd -> fd.getVariable(0).getNameAsString().equals("emitter")).forEach(emitterField -> {
            annotator.withInjection(emitterField);
            annotator.withOutgoingMessage(emitterField, sanitizedName);
        });
        template.findAll(FieldDeclaration.class, fd -> fd.getVariables().get(0).getNameAsString().equals("converter")).forEach(fd -> {
            annotator.withInjection(fd);
            fd.getVariable(0).setType(fd.getVariable(0).getTypeAsString().replace("$DataType$", trigger.getDataType()));
        });
        template.findAll(FieldDeclaration.class, fd -> fd.getVariable(0).getNameAsString().equals("useCloudEvents")).forEach(fd -> annotator.withConfigInjection(fd, "quarkus.automatiko.messaging.as-cloudevents"));
        template.findAll(FieldDeclaration.class, fd -> fd.getVariable(0).getNameAsString().equals("useCloudEventsBinary")).forEach(fd -> annotator.withConfigInjection(fd, "quarkus.automatiko.messaging.as-cloudevents-binary"));
    }
    // add connector and message name as static fields of the class
    FieldDeclaration connectorField = new FieldDeclaration().setStatic(true).setFinal(true).addVariable(new VariableDeclarator(new ClassOrInterfaceType(null, "String"), "CONNECTOR", new StringLiteralExpr(connector)));
    template.addMember(connectorField);
    FieldDeclaration messageNameField = new FieldDeclaration().setStatic(true).setFinal(true).addVariable(new VariableDeclarator(new ClassOrInterfaceType(null, "String"), "MESSAGE", new StringLiteralExpr(trigger.getName())));
    template.addMember(messageNameField);
    if (workflowType.equals(Process.FUNCTION_FLOW_TYPE)) {
        String destination = (String) trigger.getContext("functionType", sanitizedName);
        String sourcePrefix = process.getPackageName() + "." + processId + "." + sanitizedName;
        template.findAll(StringLiteralExpr.class).forEach(vv -> {
            String s = vv.getValue();
            String interpolated = s.replace("$destination$", destination);
            interpolated = interpolated.replace("$sourcePrefix$", sourcePrefix);
            vv.setString(interpolated);
        });
    }
    template.getMembers().sort(new BodyDeclarationComparator());
    ImportsOrganizer.organize(clazz);
    return clazz.toString();
}
Also used : ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) ReturnStmt(com.github.javaparser.ast.stmt.ReturnStmt) StaticJavaParser.parse(com.github.javaparser.StaticJavaParser.parse) Metadata(io.automatiko.engine.workflow.process.executable.core.Metadata) CAMEL_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.CAMEL_CONNECTOR) GeneratorContext(io.automatiko.engine.codegen.GeneratorContext) CastExpr(com.github.javaparser.ast.expr.CastExpr) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) ImportDeclaration(com.github.javaparser.ast.ImportDeclaration) AMQP_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.AMQP_CONNECTOR) MQTT_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.MQTT_CONNECTOR) CodegenUtils.interpolateTypes(io.automatiko.engine.codegen.CodegenUtils.interpolateTypes) StringUtils(io.automatiko.engine.services.utils.StringUtils) CompilationUnit(com.github.javaparser.ast.CompilationUnit) TriggerMetaData(io.automatiko.engine.workflow.compiler.canonical.TriggerMetaData) HTTP_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.HTTP_CONNECTOR) KAFKA_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.KAFKA_CONNECTOR) DependencyInjectionAnnotator(io.automatiko.engine.codegen.di.DependencyInjectionAnnotator) FUNCTION_FLOW_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.FUNCTION_FLOW_CONNECTOR) Process(io.automatiko.engine.api.definition.process.Process) OUTGOING_PROP_PREFIX(io.automatiko.engine.codegen.CodeGenConstants.OUTGOING_PROP_PREFIX) CodegenUtils(io.automatiko.engine.codegen.CodegenUtils) BaseFunctions(io.automatiko.engine.services.execution.BaseFunctions) JMS_CONNECTOR(io.automatiko.engine.codegen.CodeGenConstants.JMS_CONNECTOR) MethodCallExpr(com.github.javaparser.ast.expr.MethodCallExpr) WorkflowProcess(io.automatiko.engine.api.definition.process.WorkflowProcess) AssignExpr(com.github.javaparser.ast.expr.AssignExpr) BodyDeclarationComparator(io.automatiko.engine.codegen.BodyDeclarationComparator) CodegenUtils.interpolateEventTypes(io.automatiko.engine.codegen.CodegenUtils.interpolateEventTypes) NameExpr(com.github.javaparser.ast.expr.NameExpr) VariableScope(io.automatiko.engine.workflow.base.core.context.variable.VariableScope) StringLiteralExpr(com.github.javaparser.ast.expr.StringLiteralExpr) VariableDeclarationExpr(com.github.javaparser.ast.expr.VariableDeclarationExpr) FieldDeclaration(com.github.javaparser.ast.body.FieldDeclaration) MethodDeclaration(com.github.javaparser.ast.body.MethodDeclaration) Entry(java.util.Map.Entry) Functions(io.automatiko.engine.api.Functions) Variable(io.automatiko.engine.workflow.base.core.context.variable.Variable) BlockStmt(com.github.javaparser.ast.stmt.BlockStmt) ClassOrInterfaceDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) ImportsOrganizer(io.automatiko.engine.codegen.ImportsOrganizer) Variable(io.automatiko.engine.workflow.base.core.context.variable.Variable) ClassOrInterfaceDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) NameExpr(com.github.javaparser.ast.expr.NameExpr) StringLiteralExpr(com.github.javaparser.ast.expr.StringLiteralExpr) ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) FieldDeclaration(com.github.javaparser.ast.body.FieldDeclaration) AssignExpr(com.github.javaparser.ast.expr.AssignExpr) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) CastExpr(com.github.javaparser.ast.expr.CastExpr) BodyDeclarationComparator(io.automatiko.engine.codegen.BodyDeclarationComparator) CompilationUnit(com.github.javaparser.ast.CompilationUnit) VariableDeclarationExpr(com.github.javaparser.ast.expr.VariableDeclarationExpr) MethodDeclaration(com.github.javaparser.ast.body.MethodDeclaration) BlockStmt(com.github.javaparser.ast.stmt.BlockStmt) ImportDeclaration(com.github.javaparser.ast.ImportDeclaration) ReturnStmt(com.github.javaparser.ast.stmt.ReturnStmt) VariableScope(io.automatiko.engine.workflow.base.core.context.variable.VariableScope) MethodCallExpr(com.github.javaparser.ast.expr.MethodCallExpr)

Aggregations

StaticJavaParser.parse (com.github.javaparser.StaticJavaParser.parse)1 CompilationUnit (com.github.javaparser.ast.CompilationUnit)1 ImportDeclaration (com.github.javaparser.ast.ImportDeclaration)1 ClassOrInterfaceDeclaration (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)1 FieldDeclaration (com.github.javaparser.ast.body.FieldDeclaration)1 MethodDeclaration (com.github.javaparser.ast.body.MethodDeclaration)1 VariableDeclarator (com.github.javaparser.ast.body.VariableDeclarator)1 AssignExpr (com.github.javaparser.ast.expr.AssignExpr)1 CastExpr (com.github.javaparser.ast.expr.CastExpr)1 MethodCallExpr (com.github.javaparser.ast.expr.MethodCallExpr)1 NameExpr (com.github.javaparser.ast.expr.NameExpr)1 StringLiteralExpr (com.github.javaparser.ast.expr.StringLiteralExpr)1 VariableDeclarationExpr (com.github.javaparser.ast.expr.VariableDeclarationExpr)1 BlockStmt (com.github.javaparser.ast.stmt.BlockStmt)1 ReturnStmt (com.github.javaparser.ast.stmt.ReturnStmt)1 ClassOrInterfaceType (com.github.javaparser.ast.type.ClassOrInterfaceType)1 Functions (io.automatiko.engine.api.Functions)1 Process (io.automatiko.engine.api.definition.process.Process)1 WorkflowProcess (io.automatiko.engine.api.definition.process.WorkflowProcess)1 BodyDeclarationComparator (io.automatiko.engine.codegen.BodyDeclarationComparator)1