From 035929fd51daed60b92bf47f41544fcb702189a3 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Wed, 20 Mar 2024 22:12:35 +0100 Subject: [PATCH 1/6] update 'next' to 2.0.0-SNAPSHOT --- e2e/pom.xml | 2 +- plugins/asyncapi-jsonschema2pojo/pom.xml | 2 +- plugins/asyncapi-spring-cloud-streams3/pom.xml | 2 +- plugins/backend-application-default/pom.xml | 2 +- plugins/java-to-jdl/pom.xml | 2 +- plugins/jdl-to-asyncapi/pom.xml | 2 +- plugins/openapi-controllers/pom.xml | 2 +- plugins/openapi-rest-assured/pom.xml | 2 +- plugins/openapi-spring-webtestclient/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/zdl-to-asyncapi/pom.xml | 2 +- plugins/zdl-to-markdown/pom.xml | 2 +- plugins/zdl-to-openapi/pom.xml | 2 +- pom.xml | 4 ++-- zenwave-sdk-cli/pom.xml | 2 +- zenwave-sdk-maven-plugin/pom.xml | 2 +- zenwave-sdk-test-resources/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/e2e/pom.xml b/e2e/pom.xml index 59c20fbc..8484912e 100644 --- a/e2e/pom.xml +++ b/e2e/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} e2e diff --git a/plugins/asyncapi-jsonschema2pojo/pom.xml b/plugins/asyncapi-jsonschema2pojo/pom.xml index 0c2e7f25..bb72b8cc 100644 --- a/plugins/asyncapi-jsonschema2pojo/pom.xml +++ b/plugins/asyncapi-jsonschema2pojo/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/asyncapi-spring-cloud-streams3/pom.xml b/plugins/asyncapi-spring-cloud-streams3/pom.xml index 2710f28c..6767132c 100644 --- a/plugins/asyncapi-spring-cloud-streams3/pom.xml +++ b/plugins/asyncapi-spring-cloud-streams3/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/backend-application-default/pom.xml b/plugins/backend-application-default/pom.xml index e293ac90..9827c189 100644 --- a/plugins/backend-application-default/pom.xml +++ b/plugins/backend-application-default/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/java-to-jdl/pom.xml b/plugins/java-to-jdl/pom.xml index 21379899..ba2a0aab 100644 --- a/plugins/java-to-jdl/pom.xml +++ b/plugins/java-to-jdl/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/jdl-to-asyncapi/pom.xml b/plugins/jdl-to-asyncapi/pom.xml index a5a4b26e..438b08a2 100644 --- a/plugins/jdl-to-asyncapi/pom.xml +++ b/plugins/jdl-to-asyncapi/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/openapi-controllers/pom.xml b/plugins/openapi-controllers/pom.xml index ac66ebe5..84f67ffb 100644 --- a/plugins/openapi-controllers/pom.xml +++ b/plugins/openapi-controllers/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/openapi-rest-assured/pom.xml b/plugins/openapi-rest-assured/pom.xml index 52900886..de04d04c 100644 --- a/plugins/openapi-rest-assured/pom.xml +++ b/plugins/openapi-rest-assured/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/openapi-spring-webtestclient/pom.xml b/plugins/openapi-spring-webtestclient/pom.xml index e0b00b8e..c61def1c 100644 --- a/plugins/openapi-spring-webtestclient/pom.xml +++ b/plugins/openapi-spring-webtestclient/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/pom.xml b/plugins/pom.xml index e0f9b467..40aaad26 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} plugins-parent diff --git a/plugins/zdl-to-asyncapi/pom.xml b/plugins/zdl-to-asyncapi/pom.xml index 61065e7b..36eaf5db 100644 --- a/plugins/zdl-to-asyncapi/pom.xml +++ b/plugins/zdl-to-asyncapi/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/zdl-to-markdown/pom.xml b/plugins/zdl-to-markdown/pom.xml index a300d543..5efe2d42 100644 --- a/plugins/zdl-to-markdown/pom.xml +++ b/plugins/zdl-to-markdown/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/plugins/zdl-to-openapi/pom.xml b/plugins/zdl-to-openapi/pom.xml index a6d420aa..5a665027 100644 --- a/plugins/zdl-to-openapi/pom.xml +++ b/plugins/zdl-to-openapi/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk plugins-parent - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} io.github.zenwave360.zenwave-sdk.plugins diff --git a/pom.xml b/pom.xml index fb7dacea..92e81c0b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.github.zenwave360.zenwave-sdk zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT pom ${project.groupId}:${project.artifactId} @@ -69,7 +69,7 @@ 0.10.2 4.3.1 0.8.4 - 1.0.1 + 1.2.0-SNAPSHOT 19.2 1.7 2.38.0 diff --git a/zenwave-sdk-cli/pom.xml b/zenwave-sdk-cli/pom.xml index a42f14d7..c6d93ca8 100644 --- a/zenwave-sdk-cli/pom.xml +++ b/zenwave-sdk-cli/pom.xml @@ -4,7 +4,7 @@ zenwave-sdk io.github.zenwave360.zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT zenwave-sdk-cli ${project.groupId}:${project.artifactId} diff --git a/zenwave-sdk-maven-plugin/pom.xml b/zenwave-sdk-maven-plugin/pom.xml index e80ac534..d7358407 100644 --- a/zenwave-sdk-maven-plugin/pom.xml +++ b/zenwave-sdk-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.github.zenwave360.zenwave-sdk zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} diff --git a/zenwave-sdk-test-resources/pom.xml b/zenwave-sdk-test-resources/pom.xml index f4c83e37..645896c2 100644 --- a/zenwave-sdk-test-resources/pom.xml +++ b/zenwave-sdk-test-resources/pom.xml @@ -4,7 +4,7 @@ zenwave-sdk io.github.zenwave360.zenwave-sdk - 1.5.0-SNAPSHOT + 2.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} zenwave-sdk-test-resources From d8619a3c3d52549717ae13a150db6593fb24b132 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Sun, 24 Mar 2024 08:31:45 +0100 Subject: [PATCH 2/6] adds support for rich 'aggregate' modeling --- .../BackendApplicationDefaultHelpers.java | 45 +++- .../BackendDefaultApplicationGenerator.java | 9 +- ...ackendMultiModuleApplicationGenerator.java | 5 + .../core/domain/common/Aggregate.java.hbs | 61 +++++ .../core/domain/common/DomainEvent.java.hbs | 51 +++++ .../jpa/imperative/ServiceImpl.java.hbs | 34 ++- .../mappers/ServiceMapper.java.hbs | 4 +- .../mongodb/imperative/ServiceImpl.java.hbs | 34 ++- .../partials/mongodbMethodBody.hbs | 4 +- .../imperative/EntityRepository.java.hbs | 19 +- .../config/ServicesInMemoryConfig.java.hbs | 20 +- ...plicationMongoImperativeGeneratorTest.java | 22 ++ pom.xml | 2 +- .../AbstractZDLProjectGenerator.java | 31 ++- .../sdk/generators/ZDLProjectTemplates.java | 3 + .../sdk/processors/ZDL2JDLProcessor.java | 3 + .../sdk/processors/ZDLProcessor.java | 7 +- .../io/zenwave360/sdk/zdl/ZDLFindUtils.java | 14 ++ .../zenwave360/sdk/zdl/ZDLFindUtilsTest.java | 17 ++ .../resources/zdl/orders-with-aggregate.zdl | 208 ++++++++++++++++++ 20 files changed, 570 insertions(+), 23 deletions(-) create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/Aggregate.java.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs create mode 100644 zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java index c9be63e6..8e624a3e 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java @@ -5,9 +5,7 @@ import io.zenwave360.sdk.utils.NamingUtils; import io.zenwave360.sdk.zdl.ZDLFindUtils; -import io.zenwave360.sdk.zdl.ZDLHttpUtils; import io.zenwave360.sdk.zdl.ZDLJavaSignatureUtils; -import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import com.github.jknack.handlebars.Options; @@ -42,9 +40,38 @@ public boolean isCrudMethod(String crudMethodPrefix, Options options) { return isCrudMethod; } + public List serviceAggregates(Map service, Options options) { + var zdl = options.get("zdl"); + var aggregateNames = JSONPath.get(service, "aggregates", Collections.emptyList()); + return aggregateNames.stream() + .map(aggregateName -> JSONPath.get(zdl, "$.allEntitiesAndEnums." + aggregateName, Map.of())) + .filter(aggregate -> "aggregates".equals(aggregate.get("type"))) + .collect(Collectors.toList()); + } + + public boolean includeDomainEvents(Map service, Options options) { + var zdl = options.get("zdl"); + return !JSONPath.get(zdl, "$.aggregates[*].commands[*].withEvents", List.of()).isEmpty(); + } + + public List aggregateEvents(Map aggregate, Options options) { + var zdl = options.get("zdl"); + return ZDLFindUtils.aggregateEvents(aggregate).stream().map(event -> (Map) JSONPath.get(zdl, "$.events." + event)).toList(); + } + public Collection findAggregateInputs(Map aggregate, Options options) { + return new HashSet<>(JSONPath.get(aggregate, "$.commands[*].parameter", List.of())); + } + + public String findEntityAggregate(String entityName, Options options) { var zdl = options.get("zdl"); - var aggregateName = (String) aggregate.get("name"); + var aggregateNames = JSONPath.get(zdl, "$.aggregates[*][?(@.aggregateRoot == '" + entityName + "')].name", List.of()); + return aggregateNames.isEmpty()? null : (String) aggregateNames.get(0); + } + + public Collection findServiceInputs(Map entity, Options options) { + var zdl = options.get("zdl"); + var aggregateName = (String) entity.get("name"); var inputDTOSuffix = (String) options.get("inputDTOSuffix"); Set inputs = new HashSet(); inputs.addAll(JSONPath.get(zdl, "$.services[*][?('" + aggregateName + "' in @.aggregates)].methods[*].parameter")); @@ -305,14 +332,14 @@ public String validationPatternJava(String pattern, Options options) { return pattern.replace("\\", "").replace("\\", "\\\\"); } - public Object skipEntityRepository(Object context, Options options) { - Map entity = (Map) context; - return generator.skipEntityRepository.apply(Map.of("entity", entity)); + public Object skipEntityRepository(Map entity, Options options) { + var zdl = options.get("zdl"); + return generator.skipEntityRepository.apply(Map.of("zdl", zdl, "entity", entity)); }; - public Object skipEntityId(Object context, Options options) { - Map entity = (Map) context; - return generator.skipEntityId.apply(Map.of("entity", entity)); + public Object skipEntityId(Map entity, Options options) { + var zdl = options.get("zdl"); + return generator.skipEntityId.apply(Map.of("zdl", zdl, "entity", entity)); }; public Object addExtends(Object entity, Options options) { diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java index 19426b3c..4b78c485 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java @@ -13,6 +13,7 @@ import io.zenwave360.sdk.options.PersistenceType; import io.zenwave360.sdk.options.ProgrammingStyle; import io.zenwave360.sdk.utils.JSONPath; +import io.zenwave360.sdk.zdl.ZDLFindUtils; /** * Generates a backend application with the following structure: @@ -48,6 +49,7 @@ public class BackendDefaultApplicationGenerator extends AbstractZDLProjectGenera public String configPackage = "{{basePackage}}.config"; public String entitiesPackage = "{{basePackage}}.core.domain"; + public String domainEventsPackage = "{{basePackage}}.core.domain.events"; public String inboundPackage = "{{basePackage}}.core.inbound"; public String inboundDtosPackage = "{{basePackage}}.core.inbound.dtos"; public String outboundPackage = "{{basePackage}}.core.outbound"; @@ -91,7 +93,7 @@ protected boolean is(Map model, String... annotations) { return !(JSONPath.get(model, "$.entity.options[?(" + annotationsFilter + ")]", List.of())).isEmpty(); } - protected Function, Boolean> skipEntityRepository = (model) -> !is(model, "aggregate"); + protected Function, Boolean> skipEntityRepository = (model) -> !(is(model, "aggregate") || ZDLFindUtils.isAggregateRoot(JSONPath.get(model, "zdl"), JSONPath.get(model, "$.entity.name"))); protected Function, Boolean> skipEntityId = (model) -> is(model, "embedded", "vo", "input", "abstract"); protected Function, Boolean> skipEntity = (model) -> is(model, "vo", "input"); protected Function, Boolean> skipEntityInput = (model) -> inputDTOSuffix == null || inputDTOSuffix.isEmpty(); @@ -102,6 +104,11 @@ protected boolean is(Map model, String... annotations) { protected ZDLProjectTemplates configureProjectTemplates() { var ts = new ZDLProjectTemplates("io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator"); + ts.addTemplate(ts.aggregateTemplates, "src/main/java","core/domain/common/Aggregate.java", + "{{asPackageFolder entitiesPackage}}/{{aggregate.name}}.java", JAVA, null, true); + ts.addTemplate(ts.domainEventsTemplates, "src/main/java","core/domain/common/DomainEvent.java", + "{{asPackageFolder domainEventsPackage}}/{{event.name}}.java", JAVA, null, true); + ts.addTemplate(ts.entityTemplates, "src/main/java","core/domain/{{persistence}}/Entity.java", "{{asPackageFolder entitiesPackage}}/{{entity.name}}.java", JAVA, skipEntity, false); ts.addTemplate(ts.entityTemplates, "src/main/java","core/outbound/{{persistence}}/{{style}}/EntityRepository.java", diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java index 69c35ecb..a8c5779d 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java @@ -11,6 +11,11 @@ public class BackendMultiModuleApplicationGenerator extends BackendDefaultApplic protected ZDLProjectTemplates configureProjectTemplates() { var ts = new ZDLProjectTemplates("io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator"); + ts.addTemplate(ts.aggregateTemplates, "src/main/java","core/domain/common/Aggregate.java","{{mavenModulesPrefix}}-domain", + "{{asPackageFolder entitiesPackage}}/{{aggregate.name}}.java", JAVA, null, true); + ts.addTemplate(ts.domainEventsTemplates, "src/main/java","core/domain/common/DomainEvent.java","{{mavenModulesPrefix}}-domain", + "{{asPackageFolder domainEventsPackage}}/{{event.name}}.java", JAVA, null, true); + ts.addTemplate(ts.entityTemplates, "src/main/java","core/domain/{{persistence}}/Entity.java", "{{mavenModulesPrefix}}-domain", "{{asPackageFolder entitiesPackage}}/{{entity.name}}.java", JAVA, skipEntity, false); ts.addTemplate(ts.entityTemplates, "src/main/java","core/outbound/{{persistence}}/{{style}}/EntityRepository.java", "{{mavenModulesPrefix}}-domain", diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/Aggregate.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/Aggregate.java.hbs new file mode 100644 index 00000000..4fa352ee --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/Aggregate.java.hbs @@ -0,0 +1,61 @@ +package {{entitiesPackage}}; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import {{domainEventsPackage}}.*; +import {{inboundDtosPackage}}.*; + +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + + +public class {{aggregate.name}} { + private static final Mapper mapper = Mappers.getMapper(Mapper.class); + + private final {{aggregate.aggregateRoot}} rootEntity; + + private final List events = new ArrayList<>(); + + public {{aggregate.name}}() { + this(new {{aggregate.aggregateRoot}}()); + } + public {{aggregate.name}}({{aggregate.aggregateRoot}} rootEntity) { + this.rootEntity = rootEntity; + } + + public String getId() { + return rootEntity.getId(); + } + + public {{aggregate.aggregateRoot}} getRootEntity() { + return rootEntity; + } + + public List getEvents() { + return Collections.unmodifiableList(events); + } + +{{#each aggregate.commands as |method|}} + {{~> (partial '../../implementation/partials/serviceMethodJavadoc')}} + public void {{method.name}}({{method.parameter}} input) { + // TODO: implement this command + mapper.update(rootEntity, input); + {{~#each (methodEvents method) as |event|}} + events.add(mapper.as{{event.name}}(rootEntity)); + {{~/each}} + } +{{/each}} + + @org.mapstruct.Mapper + interface Mapper { + {{~#each (findAggregateInputs aggregate) as |input|}} + {{aggregate.aggregateRoot}} update(@MappingTarget {{aggregate.aggregateRoot}} entity, {{input}} input); + {{~/each}} + + {{~#each (aggregateEvents aggregate) as |event|}} + {{event.className}} as{{event.name}}({{aggregate.aggregateRoot}} entity); + {{~/each}} + } +} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs new file mode 100644 index 00000000..501f7ed5 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs @@ -0,0 +1,51 @@ +package {{domainEventsPackage}}; + +import java.io.Serializable; +import java.math.*; +import java.time.*; +import java.util.*; +import jakarta.validation.constraints.*; + +import {{entitiesPackage}}.*; + +/** +* {{event.comment}} +*/ +{{~#if useLombok}} +@lombok.Getter @lombok.Setter +{{~/if}} +public {{abstractClass event}} class {{event.className}} {{addExtends event}} implements Serializable { + + @java.io.Serial + private static final long serialVersionUID = 1L; + +{{#each event.fields as |field|}} + {{#each field.validations as |validation|~}} + // @{{validation.name}}("{{validation.value}}") + {{~/each}} + private {{{fieldType field}}} {{field.name}}; +{{/each}} + + +{{#each event.fields as |field|}} + {{~#if field.isArray}} + public {{event.className}} add{{capitalize field.name}}({{javaType field}} {{field.name}}) { + this.{{field.name}}.add({{field.name}}); + return this; + } + {{~/if}} +{{/each}} + +{{~#unless useLombok}} +{{#each event.fields as |field|}} + public {{{fieldType field}}} get{{capitalize field.name}}() { + return {{field.name}}; + } + + public {{event.className}} set{{capitalize field.name}}({{{fieldType field}}} {{field.name}}) { + this.{{field.name}} = {{field.name}}; + return this; + } +{{/each}} +{{~/unless}} +} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs index cf4b2d77..a3465def 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs @@ -8,7 +8,9 @@ import {{outboundPackage}}.jpa.*; {{#if includeEmitEventsImplementation}} import {{outboundEventsPackage}}.*; {{/if}} - +{{#if (includeDomainEvents service)}} +import {{domainEventsPackage}}.*; +{{/if}} import java.math.*; import java.time.*; @@ -22,6 +24,9 @@ import org.springframework.data.domain.Pageable; import java.util.concurrent.CompletableFuture; import org.springframework.scheduling.annotation.Async; {{~/if}} +{{~#if (includeEmitEventsImplementation service)}} +import org.springframework.context.ApplicationEventPublisher; +{{~/if}} import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -48,6 +53,7 @@ public class {{service.name}}Impl implements {{service.name}} { {{#if (includeEmitEventsImplementation service)}} private final EventsMapper eventsMapper = EventsMapper.INSTANCE; private final {{eventsProducerInterface service.name}} eventsProducer; + private final ApplicationEventPublisher applicationEventPublisher; {{/if}} {{#unless useLombok~}} @@ -55,12 +61,14 @@ public class {{service.name}}Impl implements {{service.name}} { * Constructor. */ public {{service.name}}Impl({{#joinWithTemplate service.entities delimiter=", "}}{{#unless (skipEntityRepository this)}}{{className}}Repository {{instanceName}}Repository{{/unless}}{{/joinWithTemplate}} - {{#if (includeEmitEventsImplementation service)}}, {{eventsProducerInterface service.name}} eventsProducer{{/if}}) { + {{#if (includeEmitEventsImplementation service)}}, {{eventsProducerInterface service.name}} eventsProducer, ApplicationEventPublisher applicationEventPublisher{{/if}} + ) { {{~#joinWithTemplate service.entities ~}} {{#unless (skipEntityRepository this)}}this.{{instanceName}}Repository = {{instanceName}}Repository;{{/unless}} {{~/joinWithTemplate~}} {{~#if (includeEmitEventsImplementation service)}} this.eventsProducer = eventsProducer; + this.applicationEventPublisher = applicationEventPublisher; {{~/if}} } {{/unless~}} @@ -72,4 +80,26 @@ public class {{service.name}}Impl implements {{service.name}} { } {{/each}} +{{#each (serviceAggregates service) as |aggregate|}} + private {{aggregate.name}} persistAndEmitEvents({{aggregate.name}} {{asInstanceName aggregate.name}}) { + var {{asInstanceName aggregate.aggregateRoot}} = {{asInstanceName aggregate.aggregateRoot}}Repository.save({{asInstanceName aggregate.name}}.getRootEntity()); + {{asInstanceName aggregate.name}}.getEvents().forEach(event -> { + {{#each (aggregateEvents aggregate) as |event|}} + if (event instanceof {{event.className}}) { + {{~#if event.options.asyncapi }} + {{~#if includeEmitEventsImplementation }} + eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + {{~else}} + // TODO: set 'includeEmitEventsImplementation' to generate this + // eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + {{~/if}} + {{~else}} + applicationEventPublisher.publishEvent(event); + {{~/if}} + } + {{/each}} + }); + return {{asInstanceName aggregate.name}}; + } +{{/each}} } diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs index d9196d6b..b50efc5c 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs @@ -15,10 +15,10 @@ import org.springframework.data.domain.Page; public interface {{service.name}}Mapper { {{service.name}}Mapper INSTANCE = Mappers.getMapper({{service.name}}Mapper.class); -{{~#each service.aggregates as |entityName|}} +{{~#each service.entityNames as |entityName|}} {{~assign "entity" (findEntity entityName)}} - {{~#each (findAggregateInputs entity) as |input|}} + {{~#each (findServiceInputs entity) as |input|}} {{~#if (not (eq entity.className input))}} // {{entity.className}} as{{entity.className}}({{mapperInputSignature input}}); {{~/if}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs index 68a9c9ba..29659b6c 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs @@ -8,6 +8,9 @@ import {{outboundPackage}}.mongodb.*; {{#if includeEmitEventsImplementation}} import {{outboundEventsPackage}}.*; {{/if}} +{{#if (includeDomainEvents service)}} +import {{domainEventsPackage}}.*; +{{/if}} import java.math.*; import java.time.*; @@ -21,6 +24,9 @@ import org.springframework.data.domain.Pageable; import java.util.concurrent.CompletableFuture; import org.springframework.scheduling.annotation.Async; {{~/if}} +{{~#if (includeEmitEventsImplementation service)}} +import org.springframework.context.ApplicationEventPublisher; +{{~/if}} import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -47,6 +53,7 @@ public class {{service.name}}Impl implements {{service.name}} { {{#if (includeEmitEventsImplementation service)}} private final EventsMapper eventsMapper = EventsMapper.INSTANCE; private final {{eventsProducerInterface service.name}} eventsProducer; + private final ApplicationEventPublisher applicationEventPublisher; {{/if}} {{#unless useLombok~}} @@ -54,12 +61,14 @@ public class {{service.name}}Impl implements {{service.name}} { * Constructor. */ public {{service.name}}Impl({{#joinWithTemplate service.entities delimiter=", "}}{{#unless (skipEntityRepository this)}}{{className}}Repository {{instanceName}}Repository{{/unless}}{{/joinWithTemplate}} - {{#if (includeEmitEventsImplementation service)}}, {{eventsProducerInterface service.name}} eventsProducer{{/if}}) { + {{#if (includeEmitEventsImplementation service)}}, {{eventsProducerInterface service.name}} eventsProducer, ApplicationEventPublisher applicationEventPublisher{{/if}} + ) { {{~#joinWithTemplate service.entities ~}} {{#unless (skipEntityRepository this)}}this.{{instanceName}}Repository = {{instanceName}}Repository;{{/unless}} {{~/joinWithTemplate~}} {{~#if (includeEmitEventsImplementation service)}} this.eventsProducer = eventsProducer; + this.applicationEventPublisher = applicationEventPublisher; {{~/if}} } {{/unless~}} @@ -70,4 +79,27 @@ public class {{service.name}}Impl implements {{service.name}} { {{~> (partial '../../partials/mongodbMethodBody')~}} } {{/each}} + +{{#each (serviceAggregates service) as |aggregate|}} + private {{aggregate.name}} persistAndEmitEvents({{aggregate.name}} {{asInstanceName aggregate.name}}) { + var {{asInstanceName aggregate.aggregateRoot}} = {{asInstanceName aggregate.aggregateRoot}}Repository.save({{asInstanceName aggregate.name}}.getRootEntity()); + {{asInstanceName aggregate.name}}.getEvents().forEach(event -> { + {{#each (aggregateEvents aggregate) as |event|}} + if (event instanceof {{event.className}}) { + {{~#if event.options.asyncapi }} + {{~#if includeEmitEventsImplementation }} + eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + {{~else}} + // TODO: set 'includeEmitEventsImplementation' to generate this + // eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + {{~/if}} + {{~else}} + applicationEventPublisher.publishEvent(event); + {{~/if}} + } + {{/each}} + }); + return {{asInstanceName aggregate.name}}; + } +{{/each}} } diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs index 527922ca..8ebbd762 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs @@ -75,8 +75,9 @@ {{~/if}} {{~else}} log.debug("Request {{method.name}}"); - // var {{entity.instanceName}} = new {{entity.className}}(); + var {{entity.instanceName}}; // = new {{entity.className}}(); {{~/if}} + // TODO: implement this method {{~#if method.returnType}} {{~#if (eq entity.name returnEntity.name)}} @@ -89,6 +90,7 @@ {{~/if}} {{~/if}} {{~else~}} + // TODO: implement this method {{~> (partial 'withEvents')}} {{~#if method.returnType}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/outbound/mongodb/imperative/EntityRepository.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/outbound/mongodb/imperative/EntityRepository.java.hbs index 74115288..bf03ea91 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/outbound/mongodb/imperative/EntityRepository.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/outbound/mongodb/imperative/EntityRepository.java.hbs @@ -1,13 +1,26 @@ -package {{basePackage}}.core.outbound.mongodb; +package {{outboundPackage}}.mongodb; +{{~assign 'aggregate' (findEntityAggregate entity.name)}} -import {{basePackage}}.core.domain.{{entity.className}}; +import {{entitiesPackage}}.{{entity.className}}; +{{~#if aggregate}} +import {{entitiesPackage}}.{{aggregate}}; +{{~/if}} import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; import org.springframework.stereotype.Repository; +import java.util.Optional; + /** * Spring Data MongoDB repository for the {{entity.className}} entity. */ @SuppressWarnings("unused") @Repository -public interface {{entity.className}}Repository extends MongoRepository<{{entity.className}}, String> {} +public interface {{entity.className}}Repository extends MongoRepository<{{entity.className}}, String> { + +{{~#if aggregate}} + default Optional<{{aggregate}}> find{{aggregate}}ById({{idJavaType}} id) { + return findById(id).map({{aggregate}}::new); + } +{{~/if}} +} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs index 06887834..2c90b839 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs @@ -9,6 +9,9 @@ import {{coreImplementationPackage}}.*; {{#if includeEmitEventsImplementation}} import {{outboundEventsPackage}}.*; {{/if}} +{{~#if (includeEmitEventsImplementation service)}} +import org.springframework.context.ApplicationEventPublisher; +{{~/if}} import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @@ -32,7 +35,7 @@ public class ServicesInMemoryConfig extends RepositoriesInMemoryConfig { {{#unless (skipEntityRepository entity)}}{{entity.instanceName}}Repository(){{/unless}} {{~/joinWithTemplate~}} {{#if (includeEmitEventsImplementation service)}} - , eventsProducerInMemoryContext.{{eventsProducerInstance service.name}}() + , eventsProducerInMemoryContext.{{eventsProducerInstance service.name}}(), applicationEventPublisher {{/if}} ); {{~/each}} @@ -56,4 +59,19 @@ public class ServicesInMemoryConfig extends RepositoriesInMemoryConfig { {{entity.className}}Repository().saveAll({{entity.instanceNamePlural}}); {{~/each}} } + +{{~#if (includeEmitEventsImplementation service)}} + private List publishedEvents = new ArrayList<>(); + + public List getPublishedEvents() { + return publishedEvents; + } + + private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() { + @Override + public void publishEvent(Object event) { + publishedEvents.add(event); + } + }; +{{~/if}} } diff --git a/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java b/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java index d0f0feba..514a8d13 100644 --- a/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java +++ b/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java @@ -79,4 +79,26 @@ public void test_generator_hexagonal_mongodb_order_faults_attachments() throws E Assertions.assertEquals(0, exitCode); } + @Test + public void test_generator_hexagonal_mongodb_orders_with_aggregate() throws Exception { + String targetFolder = "target/zdl/test_generator_hexagonal_mongodb_orders_with_aggregate"; + Plugin plugin = new BackendApplicationDefaultPlugin() + .withSpecFile("classpath:io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl") + .withTargetFolder(targetFolder) + .withOption("basePackage", "io.zenwave360.example") + .withOption("persistence", PersistenceType.mongodb) + .withOption("style", ProgrammingStyle.imperative) + .withOption("forceOverwrite", true) + .withOption("haltOnFailFormatting", false); + + new MainGenerator().generate(plugin); + + List logs = logCaptor.getLogs(); + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductConsumer.java")); + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductService.java")); + + int exitCode = MavenCompiler.copyPomAndCompile("src/test/resources/mongodb-elasticsearch-scs3-pom.xml", targetFolder); + Assertions.assertEquals(0, exitCode); + } + } diff --git a/pom.xml b/pom.xml index 92e81c0b..cf5ebb6a 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 1.7 2.38.0 0.0.39 - 4.13.2 + 5.10.1 2.6.7 0.10.2 5.8.2 diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/AbstractZDLProjectGenerator.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/AbstractZDLProjectGenerator.java index 78aa22c8..58f0aa25 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/AbstractZDLProjectGenerator.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/AbstractZDLProjectGenerator.java @@ -5,6 +5,7 @@ import io.zenwave360.sdk.templating.*; import io.zenwave360.sdk.utils.JSONPath; +import io.zenwave360.sdk.zdl.ZDLFindUtils; public abstract class AbstractZDLProjectGenerator extends AbstractZDLGenerator { @@ -31,6 +32,33 @@ public List generate(Map contextModel) { var templateOutputList = new ArrayList(); var apiModel = getZDLModel(contextModel); + Map> aggregates = (Map) apiModel.get("aggregates"); + Set> domainEvents = new HashSet<>(); + for (Map aggregate : aggregates.values()) { + for (TemplateInput template : templates.aggregateTemplates) { + templateOutputList.addAll(generateTemplateOutput(contextModel, template, Map.of("aggregate", aggregate))); + } + var events = ZDLFindUtils.aggregateEvents(aggregate); + for (String eventName : events) { + var event = JSONPath.get(apiModel, "$.events." + eventName); + if(event != null) { + domainEvents.add((Map) event); + } + } + } + + // include all events not annotated with @asyncapi + domainEvents.addAll((List) JSONPath.get(apiModel, "$.events[*][?(!@.options.asyncapi && !@.options.embedded)]", List.of())); + // include all events referenced by fields + JSONPath.get(domainEvents, "$..fields[*].type", List.of()).stream().map(type -> (Map) JSONPath.get(apiModel, "$.events." + type)).filter(Objects::nonNull).forEach(domainEvents::add); + + for (Map domainEvent : domainEvents) { + for (TemplateInput template : templates.domainEventsTemplates) { + templateOutputList.addAll(generateTemplateOutput(contextModel, template, Map.of("event", domainEvent))); + } + } + + Map> entities = (Map) apiModel.get("entities"); for (Map entity : entities.values()) { if (!isGenerateEntity(entity)) { @@ -106,7 +134,8 @@ protected List> getEntitiesByService(Map ser if (entityNames.size() == 1 && "*".equals(entityNames.get(0))) { entityNames = JSONPath.get(apiModel, "$.entities[*].name"); } - List> entitiesByService = (List>) entityNames.stream().map(e -> JSONPath.get(apiModel, "$.entities." + e)).collect(Collectors.toList()); + entityNames = entityNames.stream().map(entity -> JSONPath.get(apiModel, "$.aggregates." + entity + ".aggregateRoot", entity)).toList(); + List> entitiesByService = (List>) entityNames.stream().map(e -> JSONPath.get(apiModel, "$.entities." + e)).toList(); List excludedNames = ((List) service.get("excludedNames")); if (excludedNames != null && excludedNames.size() > 0) { entitiesByService = entitiesByService.stream().filter(e -> !excludedNames.contains(e.get("name"))).collect(Collectors.toList()); diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/ZDLProjectTemplates.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/ZDLProjectTemplates.java index c4be39d5..3b636f4e 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/ZDLProjectTemplates.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/ZDLProjectTemplates.java @@ -17,6 +17,9 @@ public ZDLProjectTemplates(String templatesFolder) { this.templatesFolder = templatesFolder; } + public List aggregateTemplates = new ArrayList<>(); + + public List domainEventsTemplates = new ArrayList<>(); public List entityTemplates = new ArrayList<>(); public List enumTemplates = new ArrayList<>(); diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDL2JDLProcessor.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDL2JDLProcessor.java index 81a5881a..e60140e9 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDL2JDLProcessor.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDL2JDLProcessor.java @@ -26,6 +26,9 @@ public Map process(Map contextModel) { var entityNames = (List) service.get("aggregates"); for (Object entityName : entityNames) { var entity = JSONPath.get(model, "$.entities['" + entityName + "']"); + if(entity == null) { + continue; + } var options = JSONPath.get(entity, "$.options", new HashMap<>()); options.put("service", service.get("name")); JSONPath.set(entity, "$.options", options); diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDLProcessor.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDLProcessor.java index d83a887b..d21cbc6e 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDLProcessor.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/processors/ZDLProcessor.java @@ -51,7 +51,12 @@ public void processServiceName(Map zdlModel) { for (Map.Entry service : services.entrySet()) { var aggregates = JSONPath.get(service.getValue(), "$.aggregates", List.of()); for (Object aggregate : aggregates) { - JSONPath.set(zdlModel, "$.entities." + aggregate + ".options.service", service.getKey()); + if(JSONPath.get(zdlModel, "$.entities." + aggregate) != null) { + JSONPath.set(zdlModel, "$.entities." + aggregate + ".options.service", service.getKey()); + } +// if(JSONPath.get(zdlModel, "$.aggregates." + aggregate) != null) { +// JSONPath.set(zdlModel, "$.aggregates." + aggregate + ".options.service", service.getKey()); +// } } } } diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java index 4cb6ebb4..f63d3835 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java @@ -94,6 +94,20 @@ public static Map findServiceMethod(String operationId, Map aggregateEvents(Map aggregate) { + var allEvents = new HashSet(); + var methods = JSONPath.get(aggregate, "$.commands[*]", List.of()); + for (var method : methods) { + allEvents.addAll(methodEventsFlatList(method)); + } + return allEvents; + } + public static List methodEventsFlatList(Map method) { var events = (List) method.getOrDefault("withEvents", List.of()); List allEvents = new ArrayList<>(); diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java index 52371081..f81c1851 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java @@ -4,7 +4,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; +import io.zenwave360.sdk.utils.JSONPath; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -89,6 +91,21 @@ public void testFindServiceMethod() throws Exception { Assertions.assertEquals("AttachmentService", method.get("serviceName")); } + @Test + public void isAggregateRoot() throws Exception { + var model = loadZDL("classpath:io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl"); + Assertions.assertTrue(ZDLFindUtils.isAggregateRoot(model, "CustomerOrder")); + Assertions.assertFalse(ZDLFindUtils.isAggregateRoot(model, "Restaurant")); + } + + @Test + public void aggregateEvents() throws Exception { + var model = loadZDL("classpath:io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl"); + var aggregate = JSONPath.get(model, "$.aggregates.CustomerOrderAggregate", Map.of()); + var events = ZDLFindUtils.aggregateEvents(aggregate); + Assertions.assertEquals(Set.of("OrderEvent", "OrderStatusUpdated"), events); + } + @Test public void methodEventsFlatList() throws Exception { var model = loadZDL("classpath:io/zenwave360/sdk/resources/zdl/customer-address.zdl"); diff --git a/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl new file mode 100644 index 00000000..da377f4e --- /dev/null +++ b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl @@ -0,0 +1,208 @@ +/** + * ZenWave Online Food Delivery - Orders Module. + */ +config { + title "ZenWave Online Food Delivery - Orders Module" + basePackage "io.zenwave360.example.orders" + targetFolder "modules/orders" + persistence mongodb + + // these are code generation plugins for ZenWave IntelliJ Plugin, for models you can skip to 'entities' section + plugins { + + ZDLToOpenAPIPlugin { + idType string + targetFile "{{targetFolder}}/src/main/resources/apis/openapi.yml" + } + + ZDLToAsyncAPIPlugin { + asyncapiVersion v3 + idType string + targetFile "{{targetFolder}}/src/main/resources/apis/asyncapi.yml" + } + + BackendApplicationDefaultPlugin { + useLombok true + includeEmitEventsImplementation true + // --force // overwite all files + } + + OpenAPIControllersPlugin { + formatter google // comments in one line are better for demos + // TODO fix this: specFile "{{targetFolder}}/src/main/resources/apis/openapi.yml" + specFile "modules/orders/src/main/resources/apis/openapi.yml" + zdlFile "models/orders.zdl" + + // these should match the values of openapi-generator-maven-plugin + openApiApiPackage "{{basePackage}}.adapters.web" + openApiModelPackage "{{basePackage}}.adapters.web.model" + openApiModelNameSuffix DTO + } + + SpringCloudStreams3AdaptersPlugin { + apiId "restaurants" + role client + specFile "modules/restaurants/src/main/resources/apis/asyncapi.yml" + modelPackage "{{basePackage}}.client.{{apiId}}.events.dtos" + consumerApiPackage "{{basePackage}}.client.{{apiId}}.events.consumer" + } + SpringCloudStreams3AdaptersPlugin { + apiId "delivery" + role client + specFile "modules/delivery/src/main/resources/apis/asyncapi.yml" + modelPackage "{{basePackage}}.client.{{apiId}}.events.dtos" + consumerApiPackage "{{basePackage}}.client.{{apiId}}.events.consumer" + } + + } +} + +apis { + asyncapi(provider) default { + uri "orders/src/main/resources/apis/asyncapi.yml" + } + asyncapi(client) RestaurantsAsyncAPI { + uri "restaurants/src/main/resources/apis/asyncapi.yml" + } + asyncapi(client) DeliveryAsyncAPI { + uri "delivery/src/main/resources/apis/asyncapi.yml" + } +} + + +aggregate CustomerOrderAggregate(CustomerOrder) { + createOrder(CustomerOrderInput) withEvents OrderEvent + updateOrder(CustomerOrderInput) withEvents OrderEvent OrderStatusUpdated + updateKitchenStatus(KitchenStatusInput) withEvents OrderEvent OrderStatusUpdated + updateDeliveryStatus(DeliveryStatusInput) withEvents OrderEvent OrderStatusUpdated + cancelOrder(CancelOrderInput) withEvents OrderEvent OrderStatusUpdated +} + +// == Entities ============================= +// @aggregate +entity CustomerOrder { + orderTime Instant + status OrderStatus + customerDetails Customer { + customerId String required + firstName String required + lastName String required + email String required + phone String required + address Address { + street String required + city String + state String + zip String + } + } + restaurantDetails Restaurant { + restaurantId String required + name String required + phone String required + addresses Address { + street String required + city String + state String + zip String + } + } + orderItems OrderItemInput[] { + menuItemId String required + name String required + description String + price BigDecimal required + quantity Integer required + } +} + +enum OrderStatus { + RECEIVED, KITCHEN_ACCEPTED, DELIVERY_ACCEPTED, CONFIRMED, + KITCHEN_IN_PROGRESS, KITCHEN_READY, KITCHEN_DELIVERED, + ON_DELIVERY, DELIVERED, CANCELLED +} + +// == Serices ============================= + +input CustomerOrderInput { + orderTime Instant + status OrderStatus + customerId String required + restaurantId String required + addressIdentifier String required + orderItems OrderItem[] { + menuItemId String required + name String required + description String + price BigDecimal required + quantity Integer required + } +} + +input OrdersFilter { + status OrderStatus + customerName String + restaurantName String +} + +input KitchenStatusInput { + kitchenOrderId String + kitchenStatus KitchenStatus +} + +input DeliveryStatusInput { + deliveryOrderId String + deliveryStatus DeliveryStatus +} + +input CancelOrderInput { + id String + reason String +} + +@input +enum KitchenStatus { + REJECTED, ACCEPTED, IN_PROGRESS, READY, DELIVERED, CANCELLED +} + +@input +enum DeliveryStatus { + REJECTED, ACCEPTED, IN_PROGRESS, DELIVERED, CANCELLED +} + +@rest("/orders") +service OrdersService for (CustomerOrderAggregate) { + @get("/{orderId}") + getCustomerOrder(id) CustomerOrder? + @post + createOrder(CustomerOrderInput) CustomerOrder withEvents OrderEvent + @put("/{orderId}") + updateOrder(id, CustomerOrderInput) CustomerOrder withEvents OrderEvent OrderStatusUpdated + + @asyncapi({api: RestaurantsAsyncAPI, channel: "KitchenOrdersStatusChannel"}) + updateKitchenStatus(id, KitchenStatusInput) CustomerOrder withEvents OrderEvent OrderStatusUpdated + @asyncapi({api: DeliveryAsyncAPI, channel: "DeliveryStatusChannel"}) + updateDeliveryStatus(id, DeliveryStatusInput) CustomerOrder withEvents OrderEvent OrderStatusUpdated + + @asyncapi({channel: "CancelOrdersChannel", topic: "orders.cancel_orders"}) + @put("/{orderId}/cancel") + cancelOrder(id, CancelOrderInput) CustomerOrder withEvents OrderEvent OrderStatusUpdated + + @post("/search") + searchOrders(OrdersFilter) CustomerOrder[] +} + +@copy(CustomerOrder) +@asyncapi({channel: "OrdersChannel", topic: "orders.orders"}) +event OrderEvent { + id String + // + all fields from CustomerOrder (carried state transfer) +} + +@asyncapi({channel: "OrderUpdatesChannel", topic: "orders.order_updates"}) +event OrderStatusUpdated { + id String + dateTime Instant + status OrderStatus + previousStatus OrderStatus +} From 65e555cb599356d3d94d5ee435f6222caa62063a Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Tue, 26 Mar 2024 18:19:48 +0100 Subject: [PATCH 3/6] adds support for rich 'aggregate' modeling (refactoring) --- .../BackendApplicationDefaultHelpers.java | 80 ++++++++++--- .../BackendDefaultApplicationGenerator.java | 2 +- ...ackendMultiModuleApplicationGenerator.java | 2 +- .../{jpa => }/imperative/ServiceImpl.java.hbs | 8 +- .../mappers/ServiceMapper.java.hbs | 6 +- .../mongodb/imperative/ServiceImpl.java.hbs | 105 ------------------ .../jpa/aggregates-commands-methodBody.hbs | 1 + .../jpa/aggregates-void-methodBody.hbs | 1 + .../partials/jpa/entities-crud-methodBody.hbs | 40 +++++++ .../partials/jpa/entities-methodBody.hbs | 75 +++++++++++++ .../methodAnnotations.hbs} | 0 .../partials/jpa/methodBody.hbs | 2 + .../implementation/partials/jpaMethodBody.hbs | 89 --------------- .../aggregates-commands-methodBody.hbs | 1 + .../mongodb/aggregates-void-methodBody.hbs | 1 + .../mongodb/entities-crud-methodBody.hbs | 32 ++++++ .../partials/mongodb/entities-methodBody.hbs | 71 ++++++++++++ .../partials/mongodb/methodAnnotations.hbs | 7 ++ .../partials/mongodb/methodBody.hbs | 2 + .../partials/mongodbMethodAnnotations.hbs | 16 --- .../partials/mongodbMethodBody.hbs | 100 ----------------- .../implementation/partials/withEvents.hbs | 3 +- .../config/ServicesInMemoryConfig.java.hbs | 14 +-- .../io/zenwave360/sdk/zdl/ZDLFindUtils.java | 89 +++++++++++++++ .../sdk/zdl/ZDLJavaSignatureUtils.java | 2 +- .../zdl/ZDLFindUtilsMethodAggregatesTest.java | 97 ++++++++++++++++ .../zenwave360/sdk/zdl/ZDLFindUtilsTest.java | 3 +- .../sdk/zdl/aggregate-service-methods.zdl | 51 +++++++++ .../resources/zdl/orders-with-aggregate.zdl | 3 + 29 files changed, 560 insertions(+), 343 deletions(-) rename plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/{jpa => }/imperative/ServiceImpl.java.hbs (94%) delete mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs rename plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/{jpaMethodAnnotations.hbs => jpa/methodAnnotations.hbs} (100%) create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs delete mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-crud-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodAnnotations.hbs create mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs delete mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodAnnotations.hbs delete mode 100644 plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs create mode 100644 zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsMethodAggregatesTest.java create mode 100644 zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/zdl/aggregate-service-methods.zdl diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java index 8e624a3e..af882b39 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java @@ -24,6 +24,50 @@ public class BackendApplicationDefaultHelpers { this.generator = generator; } + public String logMethodCall(Map method, Options options) { + var zdl = options.get("zdl"); + var methodName = (String) method.get("name"); + var parameters = ZDLJavaSignatureUtils.methodParametersCallSignature(method, (Map) zdl, generator.inputDTOSuffix); + var parameterPlaceHolders = Arrays.stream(parameters.split(", ")).map(p -> "{}").collect(Collectors.joining(" ")); + if(parameters.isEmpty()) { + return String.format("log.debug(\"Request %s\");", methodName); + } + return String.format("log.debug(\"Request %s: %s\", %s);", methodName, parameterPlaceHolders, parameters); + } + + public Map findAggregateCommandsForMethod(Map method, Options options) { + var zdl = options.get("zdl"); + var aggregatesCommandsForMethod = ZDLFindUtils.findAggregateCommandsForMethod((Map) zdl, method); + if(aggregatesCommandsForMethod.isEmpty()) { + return Map.of("templateFile", "aggregates-void-methodBody"); + } + if(aggregatesCommandsForMethod.size() == 1) { + var aggregate = JSONPath.get(aggregatesCommandsForMethod, "$[0].aggregate"); + var entity = JSONPath.get(aggregatesCommandsForMethod, "$[0].entity"); + var command = JSONPath.get(aggregatesCommandsForMethod, "$[0].command"); + var crudMethod = JSONPath.get(aggregatesCommandsForMethod, "$[0].crudMethod"); + if(aggregate != null && command != null) { + return Map.of("templateFile", "aggregates-commands-methodBody", "aggregatesCommandsForMethod", aggregatesCommandsForMethod); + } + if(aggregate != null && crudMethod != null) { + return Map.of("templateFile", "aggregates-crud-methodBody", "aggregatesCommandsForMethod", aggregatesCommandsForMethod); + } + if(entity != null && crudMethod != null) { + return Map.of("templateFile", "entities-crud-methodBody", "entity", entity, "crudMethod", crudMethod); + } + if(entity != null) { + return Map.of("templateFile", "entities-methodBody", "entity", entity); + } + } + return Map.of("templateFile", "aggregates-commands-methodBody", "aggregatesCommandsForMethod", aggregatesCommandsForMethod); + } + public boolean isWriteMethod(Map method, Options options) { + var methodName = (String) method.get("name"); + var hasId = method.get("paramId") != null; + return hasId || methodName.startsWith("create") || methodName.startsWith("update") || methodName.startsWith("delete"); + } + + @Deprecated public boolean isCrudMethod(String crudMethodPrefix, Options options) { var entity = (Map) options.hash("entity"); var entityName = (String) entity.get("name"); @@ -69,12 +113,11 @@ public String findEntityAggregate(String entityName, Options options) { return aggregateNames.isEmpty()? null : (String) aggregateNames.get(0); } - public Collection findServiceInputs(Map entity, Options options) { + public Collection findServiceInputs(Map service, Options options) { var zdl = options.get("zdl"); - var aggregateName = (String) entity.get("name"); var inputDTOSuffix = (String) options.get("inputDTOSuffix"); Set inputs = new HashSet(); - inputs.addAll(JSONPath.get(zdl, "$.services[*][?('" + aggregateName + "' in @.aggregates)].methods[*].parameter")); + inputs.addAll(JSONPath.get(service, "$.methods[*].parameter")); // inputs.addAll(JSONPath.get(zdl, "$.services[*][?('" + aggregateName + "' in @.aggregates)].methods[*].returnType")); // inputs.add(aggregateName + inputDTOSuffix); inputs = inputs.stream().filter(Objects::nonNull).collect(Collectors.toSet()); @@ -86,12 +129,12 @@ public Collection findServiceInputs(Map entity, Options options) { return inputs; } - public Collection findAggregateOutputs(Map aggregate, Options options) { + public Collection findServiceOutputs(Map service, Options options) { var zdl = options.get("zdl"); - var aggregateName = (String) aggregate.get("name"); + var aggregates = (List) service.get("aggregates"); Set outputs = new HashSet(); - outputs.addAll(JSONPath.get(zdl, "$.services[*][?('" + aggregateName + "' in @.aggregates)].methods[*].returnType")); - outputs = outputs.stream().filter(input -> input != null && !aggregateName.equals(input)).collect(Collectors.toSet()); + outputs.addAll(JSONPath.get(service, "$.methods[*].returnType")); + outputs = outputs.stream().filter(input -> input != null && !aggregates.contains(input)).collect(Collectors.toSet()); return outputs; } @@ -209,20 +252,22 @@ public String wrapWithMapper(Map entity, Options options) { return ""; } var returnTypeIsArray = (Boolean) method.getOrDefault("returnTypeIsArray", false); + var isReturnTypeOptional = (Boolean) method.getOrDefault("returnTypeIsOptional", false); var instanceName = returnTypeIsArray? entity.get("instanceNamePlural") : entity.get("instanceName"); + var serviceInstanceName = NamingUtils.asInstanceName((String) method.get("serviceName")); if (Objects.equals(entity.get("name"), returnType.get("name"))) { - if(JSONPath.get(method, "options.paginated", false)) { - return "page"; - } +// if(JSONPath.get(method, "options.paginated", false)) { +// return (String) instanceName; +// } return (String) instanceName; } else { if(returnTypeIsArray) { if(JSONPath.get(method, "options.paginated", false)) { - return String.format("%sMapper.as%sPage(%s)", instanceName, returnType.get("className"), "page"); + return String.format("%sMapper.as%sPage(%s)", serviceInstanceName, returnType.get("className"), instanceName); } - return String.format("%sMapper.as%sList(%s)", instanceName, returnType.get("className"), instanceName); + return String.format("%sMapper.as%sList(%s)", serviceInstanceName, returnType.get("className"), instanceName); } else { - return String.format("%sMapper.as%s(%s)", instanceName, returnType.get("className"), instanceName); + return String.format("%sMapper.as%s(%s)", serviceInstanceName, returnType.get("className"), instanceName); } } } @@ -247,7 +292,14 @@ public String javaType(Map field, Options options) { public Object findEntity(String entityName, Options options) { var zdl = options.get("zdl"); - return JSONPath.get(zdl, "entities." + entityName); + var entity = JSONPath.get(zdl, "$.allEntitiesAndEnums." + entityName); + if("entities".equals(JSONPath.get(entity, "type"))) { + return entity; + } + if("aggregates".equals(JSONPath.get(entity, "type"))) { + return findEntity(JSONPath.get(entity, "$.aggregateRoot"), options); + } + return null; } public String inputDTOSuffix(Object entity, Options options) { diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java index 4b78c485..6933ea4d 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java @@ -138,7 +138,7 @@ protected ZDLProjectTemplates configureProjectTemplates() { ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/inbound/Service.java", "{{asPackageFolder inboundPackage}}/{{service.name}}.java", JAVA, null, false); - ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/implementation/{{persistence}}/{{style}}/ServiceImpl.java", + ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/implementation/{{style}}/ServiceImpl.java", "{{asPackageFolder coreImplementationPackage}}/{{service.name}}Impl.java", JAVA, null, true); ts.addTemplate(ts.singleTemplates, "src/main/java", "core/implementation/mappers/BaseMapper.java", "{{asPackageFolder coreImplementationPackage}}/mappers/BaseMapper.java", JAVA, null, true); diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java index a8c5779d..0873ce54 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendMultiModuleApplicationGenerator.java @@ -45,7 +45,7 @@ protected ZDLProjectTemplates configureProjectTemplates() { ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/inbound/Service.java", "{{mavenModulesPrefix}}-domain", "{{asPackageFolder inboundPackage}}/{{service.name}}.java", JAVA, null, false); - ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/implementation/{{persistence}}/{{style}}/ServiceImpl.java", "{{mavenModulesPrefix}}-impl", + ts.addTemplate(ts.serviceTemplates, "src/main/java", "core/implementation/{{style}}/ServiceImpl.java", "{{mavenModulesPrefix}}-impl", "{{asPackageFolder coreImplementationPackage}}/{{service.name}}Impl.java", JAVA, null, true); ts.addTemplate(ts.serviceTemplates, "src/main/java","core/implementation/mappers/ServiceMapper.java", "{{mavenModulesPrefix}}-impl", "{{asPackageFolder coreImplementationPackage}}/mappers/{{service.name}}Mapper.java", JAVA, null, true); diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs similarity index 94% rename from plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs rename to plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs index a3465def..429680c1 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs @@ -4,7 +4,7 @@ import {{entitiesPackage}}.*; import {{inboundPackage}}.*; import {{inboundDtosPackage}}.*; import {{coreImplementationPackage}}.mappers.*; -import {{outboundPackage}}.jpa.*; +import {{outboundPackage}}.{{persistence}}.*; {{#if includeEmitEventsImplementation}} import {{outboundEventsPackage}}.*; {{/if}} @@ -74,9 +74,9 @@ public class {{service.name}}Impl implements {{service.name}} { {{/unless~}} {{#each service.methods as |method|}} - {{~> (partial '../../partials/jpaMethodAnnotations')~}} - {{~> (partial '../../partials/serviceMethodSignature')}} { - {{~> (partial '../../partials/jpaMethodBody')~}} + {{~> (partial '../partials/' persistence '/methodAnnotations')~}} + {{~> (partial '../partials/serviceMethodSignature')}} { + {{~> (partial '../partials/' persistence '/methodBody')~}} } {{/each}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs index b50efc5c..a39e5f24 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/ServiceMapper.java.hbs @@ -15,10 +15,10 @@ import org.springframework.data.domain.Page; public interface {{service.name}}Mapper { {{service.name}}Mapper INSTANCE = Mappers.getMapper({{service.name}}Mapper.class); -{{~#each service.entityNames as |entityName|}} +{{~#each service.aggregates as |entityName|}} {{~assign "entity" (findEntity entityName)}} - {{~#each (findServiceInputs entity) as |input|}} + {{~#each (findServiceInputs service) as |input|}} {{~#if (not (eq entity.className input))}} // {{entity.className}} as{{entity.className}}({{mapperInputSignature input}}); {{~/if}} @@ -27,7 +27,7 @@ public interface {{service.name}}Mapper { {{entity.className}} update(@MappingTarget {{entity.className}} entity, {{mapperInputSignature input}}); {{~/each}} - {{~#each (findAggregateOutputs entity) as |output|}} + {{~#each (findServiceOutputs service) as |output|}} {{output}} as{{output}}({{entity.className}} entity); List<{{output}}> as{{output}}List(List<{{entity.className}}> entity); default Page<{{output}}> as{{output}}Page(Page<{{entity.className}}> page) { diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs deleted file mode 100644 index 29659b6c..00000000 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs +++ /dev/null @@ -1,105 +0,0 @@ -package {{coreImplementationPackage}}; - -import {{entitiesPackage}}.*; -import {{inboundPackage}}.*; -import {{inboundDtosPackage}}.*; -import {{coreImplementationPackage}}.mappers.*; -import {{outboundPackage}}.mongodb.*; -{{#if includeEmitEventsImplementation}} -import {{outboundEventsPackage}}.*; -{{/if}} -{{#if (includeDomainEvents service)}} -import {{domainEventsPackage}}.*; -{{/if}} - -import java.math.*; -import java.time.*; -import java.util.*; -import org.mapstruct.factory.Mappers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -{{~#if (jsonPath service 'methods[*][?(@.options.async)]')}} -import java.util.concurrent.CompletableFuture; -import org.springframework.scheduling.annotation.Async; -{{~/if}} -{{~#if (includeEmitEventsImplementation service)}} -import org.springframework.context.ApplicationEventPublisher; -{{~/if}} -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {{service.entityNames}}. - */ -@Service -@Transactional(readOnly = true) -{{~#if useLombok}} -@lombok.AllArgsConstructor -{{~/if}} -public class {{service.name}}Impl implements {{service.name}} { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - private final {{service.name}}Mapper {{asInstanceName service.name}}Mapper = {{service.name}}Mapper.INSTANCE; - -{{#each entities as |entity|}} - {{~#unless (skipEntityRepository this)}} - private final {{entity.className}}Repository {{entity.instanceName}}Repository; - {{~/unless}} -{{/each}} - -{{#if (includeEmitEventsImplementation service)}} - private final EventsMapper eventsMapper = EventsMapper.INSTANCE; - private final {{eventsProducerInterface service.name}} eventsProducer; - private final ApplicationEventPublisher applicationEventPublisher; -{{/if}} - -{{#unless useLombok~}} - /** - * Constructor. - */ - public {{service.name}}Impl({{#joinWithTemplate service.entities delimiter=", "}}{{#unless (skipEntityRepository this)}}{{className}}Repository {{instanceName}}Repository{{/unless}}{{/joinWithTemplate}} - {{#if (includeEmitEventsImplementation service)}}, {{eventsProducerInterface service.name}} eventsProducer, ApplicationEventPublisher applicationEventPublisher{{/if}} - ) { - {{~#joinWithTemplate service.entities ~}} - {{#unless (skipEntityRepository this)}}this.{{instanceName}}Repository = {{instanceName}}Repository;{{/unless}} - {{~/joinWithTemplate~}} - {{~#if (includeEmitEventsImplementation service)}} - this.eventsProducer = eventsProducer; - this.applicationEventPublisher = applicationEventPublisher; - {{~/if}} - } -{{/unless~}} - -{{#each service.methods as |method|}} - {{~> (partial '../../partials/mongodbMethodAnnotations')~}} - {{~> (partial '../../partials/serviceMethodSignature')}} { - {{~> (partial '../../partials/mongodbMethodBody')~}} - } -{{/each}} - -{{#each (serviceAggregates service) as |aggregate|}} - private {{aggregate.name}} persistAndEmitEvents({{aggregate.name}} {{asInstanceName aggregate.name}}) { - var {{asInstanceName aggregate.aggregateRoot}} = {{asInstanceName aggregate.aggregateRoot}}Repository.save({{asInstanceName aggregate.name}}.getRootEntity()); - {{asInstanceName aggregate.name}}.getEvents().forEach(event -> { - {{#each (aggregateEvents aggregate) as |event|}} - if (event instanceof {{event.className}}) { - {{~#if event.options.asyncapi }} - {{~#if includeEmitEventsImplementation }} - eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); - {{~else}} - // TODO: set 'includeEmitEventsImplementation' to generate this - // eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); - {{~/if}} - {{~else}} - applicationEventPublisher.publishEvent(event); - {{~/if}} - } - {{/each}} - }); - return {{asInstanceName aggregate.name}}; - } -{{/each}} -} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs new file mode 100644 index 00000000..5661d1f5 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs @@ -0,0 +1 @@ +// aggregates commands diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs new file mode 100644 index 00000000..0aaa635f --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs @@ -0,0 +1 @@ +// void diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs new file mode 100644 index 00000000..ee5153d9 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs @@ -0,0 +1,40 @@ +{{assign 'entity' aggregateCommandsForMethod.entity }} +{{~#if (isCrudMethod 'create' method=method entity=entity )}} + log.debug("[CRUD] Request to save {{entity.className}}: {}", input); + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); + // TODO: you may need to reload the entity here to fetch relationships 'mapped by id' + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'update' method=method entity=entity )}} + log.debug("[CRUD] Request to update {{entity.className}}: {}", input); + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); + // saving is unnecessary: https://vladmihalcea.com/best-spring-data-jparepository/ + {{entity.instanceName}} = {{entity.instanceName}}.map(existing{{entity.instanceName}} -> {{asInstanceName service.name}}Mapper.update(existing{{entity.instanceName}}, {{{mapperInputCallSignature method.parameter}}})); + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'list' method=method entity=entity )}} + {{~#if method.options.paginated}} + log.debug("[CRUD] Request list of {{entity.classNamePlural}}: {}", pageable); + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(pageable); + return {{wrapWithMapper entity}}; + {{~else}} + log.debug("Request list of {{entity.classNamePlural}}"); + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(); + return {{wrapWithMapper entity}}; + {{~/if}} +{{~else if (isCrudMethod 'search' method=method entity=entity )}} + log.debug("[CRUD] Request to search {{entity.classNamePlural}}: {} - {}", input, pageable); + // TODO implement this search by criteria + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(pageable); + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'get' method=method entity=entity )}} + log.debug("[CRUD] Request to get {{entity.className}} : {}", id); + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'delete' method=method entity=entity )}} + log.debug("[CRUD] Request to delete {{entity.className}} : {}", id); + {{entity.instanceName}}Repository.deleteById(id); + {{~> (partial '../withEvents')}} +{{~/if}} + diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs new file mode 100644 index 00000000..7e07a346 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs @@ -0,0 +1,75 @@ +{{~assign "entity" aggregateCommandsForMethod.entity}} +{{~assign "returnEntity" (methodReturnEntity method)}} + {{{logMethodCall method}}} +{{!-- @Async --}} +{{~#if method.options.async}} + {{#if method.returnType}}return CompletableFuture.completedFuture({{/if}} {{method.name}}Sync({{methodParametersCallSignature method}}){{#if method.returnType}}){{/if}}; +{{!-- list search --}} +{{~else if (and entity method.returnType method.returnTypeIsArray)}} + {{~#if (eq entity.name returnEntity)}} + return {{entity.instanceName}}Repository.findAll({{#if method.options.paginated}}pageable{{/if}}); + {{~else}} + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll({{#if method.options.paginated}}pageable{{/if}}); + return {{wrapWithMapper entity}}; + {{~/if}} +{{!-- Optional update(id, Entity) --}} +{{~else if (and entity method.paramId method.parameter method.returnType method.returnTypeIsOptional)}} + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { + return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); + }) + // saving is unnecessary https://vladmihalcea.com/best-spring-data-jparepository/ + // .map({{entity.instanceName}}Repository::save) + {{~#unless (eq entity.name method.returnType)}} + .map({{asInstanceName service.name}}Mapper::as{{returnType}}) + {{~/unless}} + ; + {{~> (partial '../withEvents')}} + return {{entity.instanceName}}; +{{!-- Entity update(id, Entity) --}} +{{~else if (and entity method.paramId method.parameter method.returnType)}} + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { + return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); + }) + // saving is unnecessary https://vladmihalcea.com/best-spring-data-jparepository/ + // .map({{entity.instanceName}}Repository::save) + .orElseThrow(); + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- Optional get(id) --}} +{{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} + return {{entity.instanceName}}Repository.findById(id).map({{asInstanceName service.name}}Mapper::as{{method.returnType}}); +{{!-- Entity get(id) --}} +{{~else if (and entity method.paramId method.returnType)}} + return {{entity.instanceName}}Repository.findById(id); +{{!-- Optional get(MyEntity) --}} +{{~else if (and entity method.parameter method.returnType method.returnTypeIsOptional)}} + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return Optional.ofNullable({{wrapWithMapper entity}}); +{{!-- Optional get(MyEntity) --}} +{{~else if (and entity method.parameter method.returnType)}} + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- Optional get() --}} +{{~else if (and entity method.returnType)}} + var {{entity.instanceName}} = new {{entity.className}}(); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- void get() --}} +{{~else if (and entity)}} + var {{entity.instanceName}} = new {{entity.className}}(); + // TODO: implement this method + {{~> (partial '../withEvents')}} + +{{!-- we know nothing (???) --}} +{{~else~}} + // TODO: implement this method + {{~> (partial '../withEvents')}} + {{~#if method.returnType}} + return null; + {{~/if}} +{{~/if}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodAnnotations.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodAnnotations.hbs similarity index 100% rename from plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodAnnotations.hbs rename to plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodAnnotations.hbs diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs new file mode 100644 index 00000000..522db148 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs @@ -0,0 +1,2 @@ +{{assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} +{{~> (partial aggregateCommandsForMethod.templateFile)}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodBody.hbs deleted file mode 100644 index 83f77d6d..00000000 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpaMethodBody.hbs +++ /dev/null @@ -1,89 +0,0 @@ -{{~#each entities as |entity|}} - {{~#if (isCrudMethod 'create' method=method entity=entity )}} - log.debug("Request to save {{entity.className}}: {}", input); - var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); - {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); - // TODO: you may need to reload the entity here to fetch all the relationships - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'update' method=method entity=entity )}} - log.debug("Request to update {{entity.className}}: {}", input); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); - // saving is unnecessary: https://vladmihalcea.com/best-spring-data-jparepository/ - {{entity.instanceName}} = {{entity.instanceName}}.map(existing{{entity.instanceName}} -> {{asInstanceName service.name}}Mapper.update(existing{{entity.instanceName}}, {{{mapperInputCallSignature method.parameter}}})); - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'list' method=method entity=entity )}} - {{~#if method.options.paginated}} - log.debug("Request list of {{entity.classNamePlural}}: {}", pageable); - var page = {{entity.instanceName}}Repository.findAll(pageable); - return {{wrapWithMapper entity}}; - {{~else}} - log.debug("Request list of {{entity.classNamePlural}}"); - var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(); - return {{wrapWithMapper entity}}; - {{~/if}} - {{~else if (isCrudMethod 'search' method=method entity=entity )}} - log.debug("Request to search {{entity.classNamePlural}}: {} - {}", input, pageable); - // TODO implement this search by criteria - var page = {{entity.instanceName}}Repository.findAll(pageable); - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'get' method=method entity=entity )}} - log.debug("Request to get {{entity.className}} : {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'delete' method=method entity=entity )}} - log.debug("Request to delete {{entity.className}} : {}", id); - {{entity.instanceName}}Repository.deleteById(id); - {{~> (partial 'withEvents')}} - {{~else~}} - {{~/if}} -{{~/each}} -{{~#unless method.isCrudMethod}} {{!-- comes from helper isCrudMethod --}} - {{~assign "entity" (methodEntity method)}} - {{~assign "returnEntity" (methodReturnEntity method)}} - {{~#if method.options.async}} - log.debug("Request {{method.name}}: {}", input); - {{#if method.returnType}}return CompletableFuture.completedFuture({{/if}} {{method.name}}Sync({{methodParametersCallSignature method}}){{#if method.returnType}}){{/if}}; - {{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} - log.debug("Request {{method.name}}: {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { - return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); - }).map({{entity.instanceName}}Repository::save); - {{~> (partial 'withEvents')}} - return {{entity.instanceName}}; - {{~else if entity}} - {{~#if method.paramId }} - log.debug("Request {{method.name}}: {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).orElseThrow(); - {{~#if method.parameter}} - {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update({{entity.instanceName}}, {{{mapperInputCallSignature method.parameter}}}); - {{~/if}} - {{~else if method.parameter }} - log.debug("Request {{method.name}}: {}", input); - {{~#if (eq entity.name returnEntity.name)}} - var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); - {{~/if}} - {{~else}} - log.debug("Request {{method.name}}"); - var {{entity.instanceName}}; // = new {{entity.className}}(); - {{~/if}} - // TODO: implement this method - {{~#if method.returnType}} - {{~#if (eq entity.name returnEntity.name)}} - {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else}} - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~/if}} - {{~/if}} - {{~else~}} - // TODO: implement this method - {{~> (partial 'withEvents')}} - {{~#if method.returnType}} - return null; - {{~/if}} - {{~/if}} -{{~/unless}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs new file mode 100644 index 00000000..5661d1f5 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs @@ -0,0 +1 @@ +// aggregates commands diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs new file mode 100644 index 00000000..0aaa635f --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs @@ -0,0 +1 @@ +// void diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-crud-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-crud-methodBody.hbs new file mode 100644 index 00000000..ed8d0c4f --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-crud-methodBody.hbs @@ -0,0 +1,32 @@ +{{assign 'entity' aggregateCommandsForMethod.entity }} +{{~#if (isCrudMethod 'create' method=method entity=entity )}} + log.debug("[CRUD] Request to save {{entity.className}}: {}", input); + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'list' method=method entity=entity )}} + {{~#if method.options.paginated}} + log.debug("[CRUD] Request list of {{entity.classNamePlural}}: {}", pageable); + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(pageable); + return {{wrapWithMapper entity}}; + {{~else}} + log.debug("Request list of {{entity.classNamePlural}}"); + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(); + return {{wrapWithMapper entity}}; + {{~/if}} +{{~else if (isCrudMethod 'search' method=method entity=entity )}} + log.debug("[CRUD] Request to search {{entity.classNamePlural}}: {} - {}", input, pageable); + // TODO implement this search by criteria + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(pageable); + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'get' method=method entity=entity )}} + log.debug("[CRUD] Request to get {{entity.className}} : {}", id); + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); + return {{wrapWithMapper entity}}; +{{~else if (isCrudMethod 'delete' method=method entity=entity )}} + log.debug("[CRUD] Request to delete {{entity.className}} : {}", id); + {{entity.instanceName}}Repository.deleteById(id); + {{~> (partial '../withEvents')}} +{{~/if}} + diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs new file mode 100644 index 00000000..017261e3 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs @@ -0,0 +1,71 @@ +{{~assign "entity" aggregateCommandsForMethod.entity}} +{{~assign "returnEntity" (methodReturnEntity method)}} + {{{logMethodCall method}}} +{{!-- @Async --}} +{{~#if method.options.async}} + {{#if method.returnType}}return CompletableFuture.completedFuture({{/if}} {{method.name}}Sync({{methodParametersCallSignature method}}){{#if method.returnType}}){{/if}}; +{{!-- list search --}} +{{~else if (and entity method.returnType method.returnTypeIsArray)}} + {{~#if (eq entity.name returnEntity)}} + return {{entity.instanceName}}Repository.findAll({{#if method.options.paginated}}pageable{{/if}}); + {{~else}} + var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll({{#if method.options.paginated}}pageable{{/if}}); + return {{wrapWithMapper entity}}; + {{~/if}} +{{!-- Optional update(id, Entity) --}} +{{~else if (and entity method.paramId method.parameter method.returnType method.returnTypeIsOptional)}} + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { + return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); + }) + .map({{entity.instanceName}}Repository::save) + {{~#unless (eq entity.name method.returnType)}} + .map({{asInstanceName service.name}}Mapper::as{{returnType}}) + {{~/unless}} + ; + {{~> (partial '../withEvents')}} + return {{entity.instanceName}}; +{{!-- Entity update(id, Entity) --}} +{{~else if (and entity method.paramId method.parameter method.returnType)}} + var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { + return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); + }).map({{entity.instanceName}}Repository::save).orElseThrow(); + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- Optional get(id) --}} +{{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} + return {{entity.instanceName}}Repository.findById(id).map({{asInstanceName service.name}}Mapper::as{{method.returnType}}); +{{!-- Entity get(id) --}} +{{~else if (and entity method.paramId method.returnType)}} + return {{entity.instanceName}}Repository.findById(id); +{{!-- Optional get(MyEntity) --}} +{{~else if (and entity method.parameter method.returnType method.returnTypeIsOptional)}} + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return Optional.ofNullable({{wrapWithMapper entity}}); +{{!-- Optional get(MyEntity) --}} +{{~else if (and entity method.parameter method.returnType)}} + var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- Optional get() --}} +{{~else if (and entity method.returnType)}} + var {{entity.instanceName}} = new {{entity.className}}(); + // TODO: implement this method + {{~> (partial '../withEvents')}} + return {{wrapWithMapper entity}}; +{{!-- void get() --}} +{{~else if (and entity)}} + var {{entity.instanceName}} = new {{entity.className}}(); + // TODO: implement this method + {{~> (partial '../withEvents')}} + +{{!-- we know nothing (???) --}} +{{~else~}} + // TODO: implement this method + {{~> (partial '../withEvents')}} + {{~#if method.returnType}} + return null; + {{~/if}} +{{~/if}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodAnnotations.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodAnnotations.hbs new file mode 100644 index 00000000..668e5527 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodAnnotations.hbs @@ -0,0 +1,7 @@ +{{~#if (isWriteMethod method)}} + @Transactional +{{~/if}} +{{~#if method.options.async}} + @Async{{#if (not (eq method.options.async true))}}("{{method.options.async}}"){{/if}} +{{~/if}} + diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs new file mode 100644 index 00000000..522db148 --- /dev/null +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs @@ -0,0 +1,2 @@ +{{assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} +{{~> (partial aggregateCommandsForMethod.templateFile)}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodAnnotations.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodAnnotations.hbs deleted file mode 100644 index 003daa2c..00000000 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodAnnotations.hbs +++ /dev/null @@ -1,16 +0,0 @@ -{{~#each entities as |entity|}} - {{~#if (isCrudMethod 'create' method=method entity=entity )}} - @Transactional - {{~else if (isCrudMethod 'update' method=method entity=entity )}} - @Transactional - {{~else if (isCrudMethod 'list' method=method entity=entity )}} - {{~else if (isCrudMethod 'search' method=method entity=entity )}} - {{~else if (isCrudMethod 'get' method=method entity=entity )}} - {{~else if (isCrudMethod 'delete' method=method entity=entity )}} - @Transactional - {{~/if}} -{{~/each}} -{{~#if method.options.async}} - @Async{{#if (not (eq method.options.async true))}}("{{method.options.async}}"){{/if}} -{{~/if}} - diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs deleted file mode 100644 index 8ebbd762..00000000 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodbMethodBody.hbs +++ /dev/null @@ -1,100 +0,0 @@ -{{~#each entities as |entity|}} - {{~#if (isCrudMethod 'create' method=method entity=entity )}} - log.debug("Request to save {{entity.className}}: {}", input); - var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); - {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'update' method=method entity=entity )}} - log.debug("Request to update {{entity.className}} : {}", input); - var {{entity.instanceName}} = {{entity.instanceName}}Repository - .findById(id) - .map(existing{{entity.className}} -> { - return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); - }) - .map({{entity.instanceName}}Repository::save); - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'list' method=method entity=entity )}} - {{~#if method.options.paginated}} - log.debug("Request list of {{entity.classNamePlural}}: {}", pageable); - var page = {{entity.instanceName}}Repository.findAll(pageable); - return {{wrapWithMapper entity}}; - {{~else}} - log.debug("Request list of {{entity.classNamePlural}}"); - var {{entity.instanceNamePlural}} = {{entity.instanceName}}Repository.findAll(); - return {{wrapWithMapper entity}}; - {{~/if}} - {{~else if (isCrudMethod 'search' method=method entity=entity )}} - log.debug("Request to search {{entity.classNamePlural}}: {} - {}", input, pageable); - // TODO implement this search by criteria - var page = {{entity.instanceName}}Repository.findAll(pageable); - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'get' method=method entity=entity )}} - log.debug("Request to get {{entity.className}} : {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); - return {{wrapWithMapper entity}}; - {{~else if (isCrudMethod 'delete' method=method entity=entity )}} - log.debug("Request to delete {{entity.className}} : {}", id); - {{entity.instanceName}}Repository.deleteById(id); - {{~> (partial 'withEvents')}} - {{~else}} - {{~/if}} -{{~/each}} -{{~#unless method.isCrudMethod}} {{!-- comes from helper isCrudMethod --}} - {{~assign "entity" (methodEntity method)}} - {{~assign "returnEntity" (methodReturnEntity method)}} - {{~#if method.options.async}} - log.debug("Request {{method.name}}: {}", input); - {{#if method.returnType}}return CompletableFuture.completedFuture({{/if}} {{method.name}}Sync({{methodParametersCallSignature method}}){{#if method.returnType}}){{/if}}; - {{~else if (and entity method.returnType method.returnTypeIsArray)}} - {{~#if method.parameter}} - log.debug("Request {{method.name}}: {}", input); - {{~else}} - log.debug("Request {{method.name}}"); - {{~/if}} - return {{entity.instanceName}}Repository.findAll({{#if method.options.paginated}}pageable{{/if}}); - {{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} - log.debug("Request {{method.name}}: {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).map(existing{{entity.className}} -> { - return {{asInstanceName service.name}}Mapper.update(existing{{entity.className}}, {{{mapperInputCallSignature method.parameter}}}); - }).map({{entity.instanceName}}Repository::save); - {{~> (partial 'withEvents')}} - return {{entity.instanceName}}; - {{~else if entity}} - {{~#if method.paramId }} - log.debug("Request {{method.name}}: {}", id); - var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id).orElseThrow(); - {{~#if method.parameter}} - {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update({{entity.instanceName}}, {{{mapperInputCallSignature method.parameter}}}); - {{~/if}} - {{~else if method.parameter }} - log.debug("Request {{method.name}}: {}", input); - {{~#if (eq entity.name returnEntity.name)}} - var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); - {{~/if}} - {{~else}} - log.debug("Request {{method.name}}"); - var {{entity.instanceName}}; // = new {{entity.className}}(); - {{~/if}} - - // TODO: implement this method - {{~#if method.returnType}} - {{~#if (eq entity.name returnEntity.name)}} - {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~else}} - {{~> (partial 'withEvents')}} - return {{wrapWithMapper entity}}; - {{~/if}} - {{~/if}} - {{~else~}} - - // TODO: implement this method - {{~> (partial 'withEvents')}} - {{~#if method.returnType}} - return null; - {{~/if}} - {{~/if}} -{{~/unless}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/withEvents.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/withEvents.hbs index 8af750db..5e3e7d06 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/withEvents.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/withEvents.hbs @@ -13,6 +13,7 @@ {{~#if method.returnTypeIsOptional}} } {{~/if}} {{~else}} // TODO emit events: {{method.withEvents}} -// set 'includeEmitEventsImplementation' to generate an skeleton of this (and remember to set --force to overwrite this existing file) +// set 'includeEmitEventsImplementation' to generate this +// set --force to overwrite existing files {{~/if}} {{~/if~}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs index 2c90b839..b3517854 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs @@ -17,6 +17,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import java.util.List; +import java.util.ArrayList; /** * Services InMemory Config. It can be used standalone or with @SpringBootTest. @@ -27,6 +28,12 @@ public class ServicesInMemoryConfig extends RepositoriesInMemoryConfig { {{#if (includeEmitEventsImplementation service)}} protected final EventsProducerInMemoryContext eventsProducerInMemoryContext = new EventsProducerInMemoryContext(); + private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() { + @Override + public void publishEvent(Object event) { + publishedEvents.add(event); + } + }; {{/if}} {{~#each services as |service|}} @@ -66,12 +73,5 @@ public class ServicesInMemoryConfig extends RepositoriesInMemoryConfig { public List getPublishedEvents() { return publishedEvents; } - - private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() { - @Override - public void publishEvent(Object event) { - publishedEvents.add(event); - } - }; {{~/if}} } diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java index f63d3835..032e79ed 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java @@ -1,6 +1,7 @@ package io.zenwave360.sdk.zdl; import io.zenwave360.sdk.utils.JSONPath; +import io.zenwave360.sdk.utils.Maps; import org.apache.commons.lang3.ObjectUtils; import java.util.*; @@ -120,4 +121,92 @@ public static List methodEventsFlatList(Map method) { } return allEvents; } + + + public static List> findAggregateCommandsForMethod(Map zdl, Map method) { + var serviceAggregateNames = JSONPath.get(zdl, "$.services." + method.get("serviceName") + ".aggregates", List.of()); + var methodAnnotatedAggregates = JSONPath.get(method, "$.options.aggregates", List.of()); + var returnType = JSONPath.get(method, "$.returnType"); + if (methodAnnotatedAggregates.isEmpty()) { + String aggregateName = null; + String entityName = null; + String crudMethod = null; + String commandName = null; + if(serviceAggregateNames.size() == 1) { + aggregateName = serviceAggregateNames.get(0); + entityName = JSONPath.get(zdl, "$.allEntitiesAndEnums." + aggregateName + ".aggregateRoot"); + if (entityName == null) { + // if entityName is null we need to swap entityName and aggregateName b/c the 'aggregateName' is actually just an entity + entityName = aggregateName; + aggregateName = null; + } + crudMethod = findCrudMethod(zdl, method, entityName); + if (crudMethod != null) { + aggregateName = null; + } + } else { + for (String serviceAggregate : serviceAggregateNames) { + aggregateName = serviceAggregate; + entityName = JSONPath.get(zdl, "$.allEntitiesAndEnums." + serviceAggregate + ".aggregateRoot"); + if (entityName == null) { + // if entityName is null we need to swap entityName and aggregateName b/c the 'aggregateName' is actually just an entity + entityName = aggregateName; + aggregateName = null; + } + if(Objects.equals(returnType, entityName) || Objects.equals(returnType, aggregateName)) { + commandName = findAggregateCommand(zdl, method, aggregateName); + if(commandName != null) { + break; + } + } + crudMethod = findCrudMethod(zdl, method, entityName); + if(crudMethod != null || Objects.equals(returnType, entityName)) { + aggregateName = null; + break; + } + } + } + + if(commandName == null && Objects.equals(returnType, entityName)) { + aggregateName = null; // if we didn't find an aggregate's command, we don't want to return an aggregate + } + + return List.of(methodAggregateCommand(zdl, aggregateName, commandName, entityName, crudMethod)); + } + return null; + } + + private static Map methodAggregateCommand(Map zdl, String aggregateName, String commandName, String entityName, String crudMethod) { + var aggregate = JSONPath.get(zdl, "$.allEntitiesAndEnums." + aggregateName); + var entity = JSONPath.get(zdl, "$.allEntitiesAndEnums." + entityName); + var command = JSONPath.get(aggregate, "$.commands." + commandName); + return Maps.of("aggregate", aggregate, "entity", entity, "command", command, "crudMethod", crudMethod); + } + + private static String findAggregateCommand(Map zdl, Map method, String aggregate) { + return JSONPath.get(zdl, "$.allEntitiesAndEnums." + aggregate + ".commands." + method.get("name") + ".name"); + } + + private static String findCrudMethod(Map zdl, Map method, String entityName) { + var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + entityName, Map.of()); + return findCrudMethod(method, entity); + } + + private static String findCrudMethod(Map method, Map entity) { + var entityName = (String) entity.get("name"); + var entityNamePlural = (String) entity.get("classNamePlural"); + var methodName = (String) method.get("name"); + var isArray = "true".equals(String.valueOf(method.get("returnTypeIsArray"))); + var isOptional = "true".equals(String.valueOf(method.get("returnTypeIsOptional"))); + var entityMethodSuffix = isArray ? entityNamePlural : entityName; + + for (String crudPrefix : List.of("create", "delete", "get")) { + var isCrudMethod = methodName.equals(crudPrefix + entityMethodSuffix); + if (isCrudMethod) { + return crudPrefix + entityMethodSuffix; + } + } + + return null; + } } diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLJavaSignatureUtils.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLJavaSignatureUtils.java index 03401c82..0b754ca5 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLJavaSignatureUtils.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLJavaSignatureUtils.java @@ -35,7 +35,7 @@ public static String methodParametersSignature(String idJavaType, Map method, Ma public static String methodParametersCallSignature(Map method, Map zdl, String inputDTOSuffix) { return Arrays.stream(methodParametersSignature("not-used", method, zdl, inputDTOSuffix).split(", ")) - .map(p -> p.split(" ")[1]) + .map(p -> p.contains(" ")? p.split(" ")[1] : "") .collect(Collectors.joining(", ")); } diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsMethodAggregatesTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsMethodAggregatesTest.java new file mode 100644 index 00000000..e024a7ce --- /dev/null +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsMethodAggregatesTest.java @@ -0,0 +1,97 @@ +package io.zenwave360.sdk.zdl; + +import io.zenwave360.sdk.utils.JSONPath; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static io.zenwave360.sdk.zdl.ZDLFindUtilsTest.loadZDL; + +public class ZDLFindUtilsMethodAggregatesTest { + + @Test + public void should_return_single_service_entity() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForEntity", "someMethod"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate", aggregatesMapForMethod); + assertEquals("MyEntity", "$[0].entity.name", aggregatesMapForMethod); + } + + @Test + public void should_return_single_service_entity_crud() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForEntity", "createMyEntity"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate", aggregatesMapForMethod); + assertEquals("MyEntity", "$[0].entity.name", aggregatesMapForMethod); + assertEquals("createMyEntity", "$[0].crudMethod", aggregatesMapForMethod); + } + + @Test + public void should_return_command_returnType() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForEntities", "shouldResolveByReturnType"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate", aggregatesMapForMethod); + assertEquals("MyEntity2", "$[0].entity.name", aggregatesMapForMethod); + } + + @Test + public void should_return_command_returnType_entity_crud() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForAggregate", "createMyEntity"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate", aggregatesMapForMethod); + assertEquals("MyEntity", "$[0].entity.name", aggregatesMapForMethod); + assertEquals("createMyEntity", "$[0].crudMethod", aggregatesMapForMethod); + } + + @Test + public void should_return_command_returnType_aggregate_crud() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForAggregate", "createMyAggregate"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate.name", aggregatesMapForMethod); + assertEquals(null, "$[0].crudMethod", aggregatesMapForMethod); + assertEquals("MyEntity", "$[0].entity.name", aggregatesMapForMethod); + } + + @Test + public void should_return_command_returnType_aggregate() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForAggregates", "shouldResolveByReturnType"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals(null, "$[0].aggregate", aggregatesMapForMethod); + assertEquals("MyEntity2", "$[0].entity.name", aggregatesMapForMethod); + } + + @Test + public void should_return_command_returnType_aggregate_with_command() throws Exception { + var aggregatesMapForMethod = aggregateCommandsForMethod("MyServiceForAggregates", "shouldResolveByReturnTypeWithCommand"); + + Assertions.assertEquals(1, aggregatesMapForMethod.size()); + assertEquals("MyAggregate2", "$[0].aggregate.name", aggregatesMapForMethod); + assertEquals("aggregates", "$[0].aggregate.type", aggregatesMapForMethod); + assertEquals("shouldResolveByReturnTypeWithCommand", "$[0].command.name", aggregatesMapForMethod); + } + + + List> aggregateCommandsForMethod(String service, String methodName) throws IOException { + var model = loadZDL("classpath:io/zenwave360/sdk/zdl/aggregate-service-methods.zdl"); + + var jsonPath = String.format("$.services.%s.methods.%s", service, methodName); + var createMyEntityMethod = JSONPath.get(model, jsonPath, Map.of()); + + var aggregatesMapForMethod = ZDLFindUtils.findAggregateCommandsForMethod(model, createMyEntityMethod); + Assertions.assertNotNull(aggregatesMapForMethod); + return aggregatesMapForMethod; + } + + void assertEquals(Object expected, String jsonpath, Object object) { + Assertions.assertEquals(expected, JSONPath.get(object, jsonpath)); + } +} diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java index f81c1851..3eb0f67b 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/zdl/ZDLFindUtilsTest.java @@ -15,7 +15,7 @@ public class ZDLFindUtilsTest { - private Map loadZDL(String resource) throws IOException { + public static Map loadZDL(String resource) throws IOException { Map model = new ZDLParser().withSpecFile(resource).parse(); return (Map) new ZDLProcessor().process(model).get("zdl"); } @@ -113,4 +113,5 @@ public void methodEventsFlatList() throws Exception { var events = ZDLFindUtils.methodEventsFlatList(method); Assertions.assertEquals(List.of("CustomerEvent", "CustomerCreated", "CustomerCreatedFailed"), events); } + } diff --git a/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/zdl/aggregate-service-methods.zdl b/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/zdl/aggregate-service-methods.zdl new file mode 100644 index 00000000..7e51a380 --- /dev/null +++ b/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/zdl/aggregate-service-methods.zdl @@ -0,0 +1,51 @@ + +aggregate MyAggregate(MyEntity) { + updateMyEntity(MyEntityInput) +} + +aggregate MyAggregate2(MyEntity2) { + shouldResolveByReturnTypeWithCommand(MyEntity2) +} + +@aggregate +entity MyEntity { + someField String +} + +@aggregate +entity MyEntity2 { + someField String +} + +input MyEntityInput { + someField String +} + +output MyEntityOutput { + someField String +} + +service MyServiceForEntity for (MyEntity) { + createMyEntity(MyEntityInput) MyEntityOutput + updateMyEntity(id, MyEntityInput) MyEntityOutput? + someMethod(MyEntityInput) MyEntityOutput +} + + +service MyServiceForEntities for (MyEntity, MyEntity2) { + shouldResolveByReturnType(MyEntity2) MyEntity2 +} + +service MyServiceForAggregate for (MyAggregate) { + createMyEntity(MyEntityInput) MyEntity + createMyAggregate(MyEntityInput) MyEntity +} + +service MyServiceForAggregates for (MyAggregate, MyAggregate2) { + shouldResolveByReturnType(MyEntity2) MyEntity2 + shouldResolveByReturnTypeWithCommand(MyEntity2) MyEntity2 +} + +service MyServiceForAggregatesAndEntities for (MyAggregate, MyEntity2) { + +} diff --git a/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl index da377f4e..65e54bf8 100644 --- a/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl +++ b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl @@ -174,6 +174,9 @@ enum DeliveryStatus { service OrdersService for (CustomerOrderAggregate) { @get("/{orderId}") getCustomerOrder(id) CustomerOrder? + @get("/CustomerOrderAggregate/{orderId}") + getCustomerOrderAggregate(id) CustomerOrder? + @post createOrder(CustomerOrderInput) CustomerOrder withEvents OrderEvent @put("/{orderId}") From b87d3fb5d671a1f325da4043060aed47f895e258 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Wed, 27 Mar 2024 14:59:24 +0100 Subject: [PATCH 4/6] adds support for rich 'aggregate' modeling (working) --- .../customer-address-relational/pom.xml | 4 +- .../models/delivery.zdl | 20 +++++++++- .../online-food-delivery-mongo/pom.xml | 4 +- .../BackendApplicationDefaultHelpers.java | 18 +++++++-- .../BackendDefaultApplicationGenerator.java | 2 +- .../imperative/ServiceImpl.java.hbs | 4 +- .../mappers/EventsMapper.java.hbs | 7 ++++ .../partials/jpa/entities-methodBody.hbs | 3 +- .../aggregates-commands-methodBody.hbs | 40 ++++++++++++++++++- .../mongodb/aggregates-void-methodBody.hbs | 3 ++ .../partials/mongodb/entities-methodBody.hbs | 3 +- ...plicationMongoImperativeGeneratorTest.java | 1 + .../io/zenwave360/sdk/zdl/ZDLFindUtils.java | 9 +++-- .../resources/zdl/orders-with-aggregate.zdl | 17 +++++++- 14 files changed, 116 insertions(+), 19 deletions(-) diff --git a/e2e/src/test/resources/projects/customer-address-relational/pom.xml b/e2e/src/test/resources/projects/customer-address-relational/pom.xml index ea36ca86..7a41624d 100644 --- a/e2e/src/test/resources/projects/customer-address-relational/pom.xml +++ b/e2e/src/test/resources/projects/customer-address-relational/pom.xml @@ -194,7 +194,7 @@ jsonschema2pojo - io.zenwave360.example.core.domain.events + io.zenwave360.example.core.outbound.events.dtos true true @@ -214,7 +214,7 @@ provider - io.zenwave360.example.core.domain.events + io.zenwave360.example.core.outbound.events.dtos io.zenwave360.example.core.outbound.events io.zenwave360.example.adapters.commands diff --git a/e2e/src/test/resources/projects/online-food-delivery-mongo/models/delivery.zdl b/e2e/src/test/resources/projects/online-food-delivery-mongo/models/delivery.zdl index d2471f40..147db4b1 100644 --- a/e2e/src/test/resources/projects/online-food-delivery-mongo/models/delivery.zdl +++ b/e2e/src/test/resources/projects/online-food-delivery-mongo/models/delivery.zdl @@ -61,9 +61,25 @@ apis { } } +// == Aggregates ============================= + +/** + * Delivery Aggregate + */ +aggregate DeliveryAggregate (Delivery) { + + createDelivery(DeliveryInput) withEvents DeliveryStatusUpdated + + onOrderStatusUpdated(OrderStatusUpdated) withEvents DeliveryStatusUpdated + + updateDeliveryStatus(DeliveryStatusInput) withEvents DeliveryStatusUpdated + +} + + // == Entities ============================= -@aggregate +//@aggregate entity Delivery { orderId String required customer Customer { @@ -120,7 +136,7 @@ input DeliveryStatusInput { } @rest("/delivery") -service DeliveryService for (Delivery) { +service DeliveryService for (DeliveryAggregate) { @asyncapi({api: OrdersAsyncAPI, channel: "OrderCreatedChannel"}) createDelivery(DeliveryInput) Delivery withEvents DeliveryStatusUpdated diff --git a/e2e/src/test/resources/projects/online-food-delivery-mongo/pom.xml b/e2e/src/test/resources/projects/online-food-delivery-mongo/pom.xml index 6920bea0..64317650 100644 --- a/e2e/src/test/resources/projects/online-food-delivery-mongo/pom.xml +++ b/e2e/src/test/resources/projects/online-food-delivery-mongo/pom.xml @@ -80,7 +80,7 @@ ${project.basedir}/src/main/resources/apis/asyncapi.yml jsonschema2pojo - ${basePackage}.core.domain.events + ${basePackage}.core.outbound.events.dtos true true @@ -97,7 +97,7 @@ ${project.basedir}/src/main/resources/apis/asyncapi.yml provider - ${basePackage}.core.domain.events + ${basePackage}.core.outbound.events.dtos ${basePackage}.core.outbound.events ${basePackage}.adapters.commands diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java index af882b39..5db1fada 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendApplicationDefaultHelpers.java @@ -2,6 +2,7 @@ import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; import io.zenwave360.sdk.utils.NamingUtils; import io.zenwave360.sdk.zdl.ZDLFindUtils; @@ -93,7 +94,7 @@ public List serviceAggregates(Map service, Options options) { .collect(Collectors.toList()); } - public boolean includeDomainEvents(Map service, Options options) { + public boolean includeDomainEvents(Object service, Options options) { var zdl = options.get("zdl"); return !JSONPath.get(zdl, "$.aggregates[*].commands[*].withEvents", List.of()).isEmpty(); } @@ -131,10 +132,12 @@ public Collection findServiceInputs(Map service, Options options) { public Collection findServiceOutputs(Map service, Options options) { var zdl = options.get("zdl"); - var aggregates = (List) service.get("aggregates"); + var serviceAggregates = (List) service.get("aggregates"); + var aggregatesAndEntities = new HashSet<>(serviceAggregates); + serviceAggregates.stream().map(aggregate -> (String) JSONPath.get(zdl, "$.aggregates." + aggregate + ".aggregateRoot")).filter(Objects::nonNull).forEach(aggregatesAndEntities::add); Set outputs = new HashSet(); outputs.addAll(JSONPath.get(service, "$.methods[*].returnType")); - outputs = outputs.stream().filter(input -> input != null && !aggregates.contains(input)).collect(Collectors.toSet()); + outputs = outputs.stream().filter(input -> input != null && !aggregatesAndEntities.contains(input)).collect(Collectors.toSet()); return outputs; } @@ -170,6 +173,15 @@ public List> methodsWithEvents(Map zdl, Opti return ZDLFindUtils.methodsWithEvents(zdl); // TODO review usages } + public Collection domainEventsWithAsyncapiAnnotation(Map zdl, Options options) { + var domainEventNames = JSONPath.get(zdl, "$.aggregates[*].commands[*].withEvents", List.of()).stream() + .flatMap(e -> e instanceof List? ((List) e).stream() : Stream.of(e)) + .collect(Collectors.toSet()); + return domainEventNames.stream().map(eventName -> (Map) JSONPath.get(zdl, "$.events." + eventName)) + .filter(event -> JSONPath.get(event, "options.asyncapi") != null) + .toList(); + } + public Collection> listOfPairEventEntity(Map zdl, Options options) { var result = new HashMap(); var methods = ZDLFindUtils.methodsWithEvents(zdl); diff --git a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java index 6933ea4d..cddf3dbf 100644 --- a/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java +++ b/plugins/backend-application-default/src/main/java/io/zenwave360/sdk/plugins/BackendDefaultApplicationGenerator.java @@ -57,7 +57,7 @@ public class BackendDefaultApplicationGenerator extends AbstractZDLProjectGenera public String infrastructurePackage = "{{basePackage}}.infrastructure"; public String adaptersPackage = "{{basePackage}}.adapters"; - public String outboundEventsModelPackage = "{{basePackage}}.core.domain.events"; + public String outboundEventsModelPackage = "{{basePackage}}.core.outbound.events.dtos"; public String outboundEventsPackage = "{{basePackage}}.core.outbound.events"; diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs index 429680c1..91444527 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/imperative/ServiceImpl.java.hbs @@ -88,10 +88,10 @@ public class {{service.name}}Impl implements {{service.name}} { if (event instanceof {{event.className}}) { {{~#if event.options.asyncapi }} {{~#if includeEmitEventsImplementation }} - eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + eventsProducer.{{operationNameForEvent event.name}}(eventsMapper.as{{event.name}}(({{event.className}}) event)); {{~else}} // TODO: set 'includeEmitEventsImplementation' to generate this - // eventsProducer.{{operationNameForEvent event.name}}({{asInstanceName event.name}}); + // eventsProducer.{{operationNameForEvent event.name}}(eventsMapper.as{{event.name}}(({{event.className}}) event)); {{~/if}} {{~else}} applicationEventPublisher.publishEvent(event); diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/EventsMapper.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/EventsMapper.java.hbs index f144dfdf..67e929bc 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/EventsMapper.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/mappers/EventsMapper.java.hbs @@ -1,6 +1,9 @@ package {{coreImplementationPackage}}.mappers; import {{entitiesPackage}}.*; +{{~#if (includeDomainEvents zdl)}} +import {{domainEventsPackage}}.*; +{{~/if}} import {{inboundDtosPackage}}.*; import java.util.List; @@ -22,4 +25,8 @@ public interface EventsMapper { {{outboundEventsModelPackage}}.{{pair.event.name}} as{{{pair.event.name}}}({{{methodParametersSignature method}}}); {{~/if}} {{~/each}} + +{{~#each (domainEventsWithAsyncapiAnnotation zdl) as |event|}} + {{outboundEventsModelPackage}}.{{event.name}} as{{{event.name}}}({{event.className}} event); +{{~/each}} } diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs index 7e07a346..2d94f98e 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-methodBody.hbs @@ -37,7 +37,8 @@ return {{wrapWithMapper entity}}; {{!-- Optional get(id) --}} {{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} - return {{entity.instanceName}}Repository.findById(id).map({{asInstanceName service.name}}Mapper::as{{method.returnType}}); + {{~assign 'needMapping' (not (eq entity.name method.returnType))}} + return {{entity.instanceName}}Repository.findById(id){{#if needMapping}}.map({{asInstanceName service.name}}Mapper::as{{method.returnType}}){{/if}}; {{!-- Entity get(id) --}} {{~else if (and entity method.paramId method.returnType)}} return {{entity.instanceName}}Repository.findById(id); diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs index 5661d1f5..c878a265 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs @@ -1 +1,39 @@ -// aggregates commands +{{#if (eq (size aggregateCommandsForMethod.aggregatesCommandsForMethod) 1)}} + {{~assign 'aggregateCommand' aggregateCommandsForMethod.aggregatesCommandsForMethod.0}} + {{~#if method.paramId}} + var {{asInstanceName aggregateCommand.aggregate.className}} = {{aggregateCommand.entity.instanceName}}Repository.find{{aggregateCommand.aggregate.className}}ById({{method.paramId}}).orElseThrow(); + {{~else}} + var {{asInstanceName aggregateCommand.aggregate.className}} = new {{aggregateCommand.aggregate.className}}(); + {{~/if}} + {{asInstanceName aggregateCommand.aggregate.className}}.{{aggregateCommand.command.name}}({{#if method.parameter}}input{{/if}}); + persistAndEmitEvents({{asInstanceName aggregateCommand.aggregate.className}}); + {{~#if method.returnType}} + {{~#if (eq aggregateCommand.aggregate.className method.returnType)}} + return {{asInstanceName aggregateCommand.aggregate.className}}; + {{~else if (eq aggregateCommand.aggregate.aggregateRoot method.returnType)}} + return {{asInstanceName aggregateCommand.aggregate.className}}.getRootEntity(); + {{~else}} + return {{asInstanceName service.name}}Mapper.as{{returnType}}({{asInstanceName aggregateCommand.aggregate.className}}.getRootEntity()); + {{~/if}} + {{~/if}} +{{~else}} +{{~#each aggregateCommandsForMethod.aggregatesCommandsForMethod as |aggregateCommand| }} + {{~#if method.paramId}} + var {{asInstanceName aggregate.className}} = {{entity.instanceName}}Repository.find{{aggregate.className}}ById({{method.paramId}}).orElseThrow(); + {{~else}} + var {{asInstanceName aggregate.className}} = new {{aggregate.className}}(); + {{~/if}} + {{asInstanceName aggregate.className}}.{{command.name}}({{#if method.parameter}}input{{/if}}); + persistAndEmitEvents({{asInstanceName aggregate.className}}); +{{~/each}} +{{~#if method.returnType}} + {{~#if (eq aggregate.className method.returnType)}} + return {{asInstanceName aggregate.className}}; + {{~else if (eq aggregate.aggregateRoot method.returnType)}} + return {{asInstanceName aggregate.className}}.getRootEntity(); + {{~else}} + return null; + {{~/if}} +{{~/if}} +{{~/if}} + diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs index 0aaa635f..1550915e 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-void-methodBody.hbs @@ -1 +1,4 @@ // void +{{~#if method.returnType}} + return null; +{{~/if}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs index 017261e3..46fff1c8 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/entities-methodBody.hbs @@ -33,7 +33,8 @@ return {{wrapWithMapper entity}}; {{!-- Optional get(id) --}} {{~else if (and entity method.paramId method.returnType method.returnTypeIsOptional)}} - return {{entity.instanceName}}Repository.findById(id).map({{asInstanceName service.name}}Mapper::as{{method.returnType}}); + {{~assign 'needMapping' (not (eq entity.name method.returnType))}} + return {{entity.instanceName}}Repository.findById(id){{#if needMapping}}.map({{asInstanceName service.name}}Mapper::as{{method.returnType}}){{/if}}; {{!-- Entity get(id) --}} {{~else if (and entity method.paramId method.returnType)}} return {{entity.instanceName}}Repository.findById(id); diff --git a/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java b/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java index 514a8d13..fa188a3e 100644 --- a/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java +++ b/plugins/backend-application-default/src/test/java/io/zenwave360/sdk/plugins/BackendApplicationMongoImperativeGeneratorTest.java @@ -89,6 +89,7 @@ public void test_generator_hexagonal_mongodb_orders_with_aggregate() throws Exce .withOption("persistence", PersistenceType.mongodb) .withOption("style", ProgrammingStyle.imperative) .withOption("forceOverwrite", true) +// .withOption("includeEmitEventsImplementation", true) .withOption("haltOnFailFormatting", false); new MainGenerator().generate(plugin); diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java index 032e79ed..fcb5fe0b 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/zdl/ZDLFindUtils.java @@ -140,9 +140,12 @@ public static List> findAggregateCommandsForMethod(Map zdl, entityName = aggregateName; aggregateName = null; } - crudMethod = findCrudMethod(zdl, method, entityName); - if (crudMethod != null) { - aggregateName = null; + commandName = findAggregateCommand(zdl, method, aggregateName); + if (commandName == null) { + crudMethod = findCrudMethod(zdl, method, entityName); + if (crudMethod != null) { + aggregateName = null; + } } } else { for (String serviceAggregate : serviceAggregateNames) { diff --git a/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl index 65e54bf8..94f1f2d1 100644 --- a/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl +++ b/zenwave-sdk-test-resources/src/main/resources/io/zenwave360/sdk/resources/zdl/orders-with-aggregate.zdl @@ -170,6 +170,21 @@ enum DeliveryStatus { REJECTED, ACCEPTED, IN_PROGRESS, DELIVERED, CANCELLED } +output CustomerOrderOutput { + orderTime Instant + status OrderStatus + customerId String required + restaurantId String required + addressIdentifier String required + orderItems OrderItem[] { + menuItemId String required + name String required + description String + price BigDecimal required + quantity Integer required + } +} + @rest("/orders") service OrdersService for (CustomerOrderAggregate) { @get("/{orderId}") @@ -178,7 +193,7 @@ service OrdersService for (CustomerOrderAggregate) { getCustomerOrderAggregate(id) CustomerOrder? @post - createOrder(CustomerOrderInput) CustomerOrder withEvents OrderEvent + createOrder(CustomerOrderInput) CustomerOrderOutput withEvents OrderEvent @put("/{orderId}") updateOrder(id, CustomerOrderInput) CustomerOrder withEvents OrderEvent OrderStatusUpdated From cdeb2ad6597d7e47b39ca68aa051c5509d32e910 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Sat, 30 Mar 2024 10:11:39 +0100 Subject: [PATCH 5/6] adds support for rich 'aggregate' modeling (working) --- .../EventsProducerInMemoryContext.java.hbs | 4 +- .../core/domain/common/DomainEvent.java.hbs | 4 +- .../jpa/aggregates-commands-methodBody.hbs | 40 ++++++++++++++++++- .../jpa/aggregates-void-methodBody.hbs | 5 +++ .../partials/jpa/entities-crud-methodBody.hbs | 2 +- .../partials/jpa/methodBody.hbs | 2 +- .../aggregates-commands-methodBody.hbs | 3 +- .../partials/mongodb/methodBody.hbs | 2 +- .../config/ServicesInMemoryConfig.java.hbs | 4 ++ .../config/TestDataLoader-mongodb.java.hbs | 3 +- 10 files changed, 58 insertions(+), 11 deletions(-) diff --git a/plugins/asyncapi-spring-cloud-streams3/src/main/resources/io/zenwave360/sdk/plugins/SpringCloudStream3Generator/producer/mocks/EventsProducerInMemoryContext.java.hbs b/plugins/asyncapi-spring-cloud-streams3/src/main/resources/io/zenwave360/sdk/plugins/SpringCloudStream3Generator/producer/mocks/EventsProducerInMemoryContext.java.hbs index fb38c8ed..3d4a71ee 100644 --- a/plugins/asyncapi-spring-cloud-streams3/src/main/resources/io/zenwave360/sdk/plugins/SpringCloudStream3Generator/producer/mocks/EventsProducerInMemoryContext.java.hbs +++ b/plugins/asyncapi-spring-cloud-streams3/src/main/resources/io/zenwave360/sdk/plugins/SpringCloudStream3Generator/producer/mocks/EventsProducerInMemoryContext.java.hbs @@ -6,8 +6,8 @@ public class EventsProducerInMemoryContext { {{#each services as |service|}} private {{service.apiClassName}}Captor {{asInstanceName service.apiClassName}}Captor = new {{service.apiClassName}}Captor(); - public T {{asInstanceName service.apiClassName}}() { - return (T) {{asInstanceName service.apiClassName}}Captor; + public {{service.apiClassName}}Captor {{asInstanceName service.apiClassName}}() { + return {{asInstanceName service.apiClassName}}Captor; } {{/each}} } diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs index 501f7ed5..2f0319c7 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/domain/common/DomainEvent.java.hbs @@ -20,9 +20,7 @@ public {{abstractClass event}} class {{event.className}} {{addExtends event}} im private static final long serialVersionUID = 1L; {{#each event.fields as |field|}} - {{#each field.validations as |validation|~}} - // @{{validation.name}}("{{validation.value}}") - {{~/each}} + {{{fieldValidationAnnotations field}}} private {{{fieldType field}}} {{field.name}}; {{/each}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs index 5661d1f5..fed0e97f 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-commands-methodBody.hbs @@ -1 +1,39 @@ -// aggregates commands + {{{logMethodCall method}}} +{{~#if (eq (size aggregateCommandsForMethod.aggregatesCommandsForMethod) 1)}} + {{~assign 'aggregateCommand' aggregateCommandsForMethod.aggregatesCommandsForMethod.0}} + {{~#if method.paramId}} + var {{asInstanceName aggregateCommand.aggregate.className}} = {{aggregateCommand.entity.instanceName}}Repository.find{{aggregateCommand.aggregate.className}}ById({{method.paramId}}).orElseThrow(); + {{~else}} + var {{asInstanceName aggregateCommand.aggregate.className}} = new {{aggregateCommand.aggregate.className}}(); + {{~/if}} + {{asInstanceName aggregateCommand.aggregate.className}}.{{aggregateCommand.command.name}}({{#if method.parameter}}input{{/if}}); + persistAndEmitEvents({{asInstanceName aggregateCommand.aggregate.className}}); + {{~#if method.returnType}} + {{~#if (eq aggregateCommand.aggregate.className method.returnType)}} + return {{asInstanceName aggregateCommand.aggregate.className}}; + {{~else if (eq aggregateCommand.aggregate.aggregateRoot method.returnType)}} + return {{asInstanceName aggregateCommand.aggregate.className}}.getRootEntity(); + {{~else}} + return {{asInstanceName service.name}}Mapper.as{{returnType}}({{asInstanceName aggregateCommand.aggregate.className}}.getRootEntity()); + {{~/if}} + {{~/if}} +{{~else}} +{{~#each aggregateCommandsForMethod.aggregatesCommandsForMethod as |aggregateCommand| }} + {{~#if method.paramId}} + var {{asInstanceName aggregate.className}} = {{entity.instanceName}}Repository.find{{aggregate.className}}ById({{method.paramId}}).orElseThrow(); + {{~else}} + var {{asInstanceName aggregate.className}} = new {{aggregate.className}}(); + {{~/if}} + {{asInstanceName aggregate.className}}.{{command.name}}({{#if method.parameter}}input{{/if}}); + persistAndEmitEvents({{asInstanceName aggregate.className}}); +{{~/each}} +{{~#if method.returnType}} + {{~#if (eq aggregate.className method.returnType)}} + return {{asInstanceName aggregate.className}}; + {{~else if (eq aggregate.aggregateRoot method.returnType)}} + return {{asInstanceName aggregate.className}}.getRootEntity(); + {{~else}} + return null; + {{~/if}} +{{~/if}} +{{~/if}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs index 0aaa635f..1920e2bc 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/aggregates-void-methodBody.hbs @@ -1 +1,6 @@ + {{{logMethodCall method}}} // void +{{~#if method.returnType}} + return null; +{{~/if}} + diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs index ee5153d9..6b8cf897 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/entities-crud-methodBody.hbs @@ -1,4 +1,4 @@ -{{assign 'entity' aggregateCommandsForMethod.entity }} +{{~assign 'entity' aggregateCommandsForMethod.entity }} {{~#if (isCrudMethod 'create' method=method entity=entity )}} log.debug("[CRUD] Request to save {{entity.className}}: {}", input); var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}}); diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs index 522db148..136aa10d 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/jpa/methodBody.hbs @@ -1,2 +1,2 @@ -{{assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} +{{~assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} {{~> (partial aggregateCommandsForMethod.templateFile)}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs index c878a265..c5645c05 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/aggregates-commands-methodBody.hbs @@ -1,4 +1,5 @@ -{{#if (eq (size aggregateCommandsForMethod.aggregatesCommandsForMethod) 1)}} + {{{logMethodCall method}}} +{{~#if (eq (size aggregateCommandsForMethod.aggregatesCommandsForMethod) 1)}} {{~assign 'aggregateCommand' aggregateCommandsForMethod.aggregatesCommandsForMethod.0}} {{~#if method.paramId}} var {{asInstanceName aggregateCommand.aggregate.className}} = {{aggregateCommand.entity.instanceName}}Repository.find{{aggregateCommand.aggregate.className}}ById({{method.paramId}}).orElseThrow(); diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs index 522db148..136aa10d 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/main/java/core/implementation/partials/mongodb/methodBody.hbs @@ -1,2 +1,2 @@ -{{assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} +{{~assign 'aggregateCommandsForMethod' (findAggregateCommandsForMethod method)}} {{~> (partial aggregateCommandsForMethod.templateFile)}} diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs index b3517854..ea59afc7 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/ServicesInMemoryConfig.java.hbs @@ -68,6 +68,10 @@ public class ServicesInMemoryConfig extends RepositoriesInMemoryConfig { } {{~#if (includeEmitEventsImplementation service)}} + public EventsProducerInMemoryContext getEventsProducerInMemoryContext() { + return eventsProducerInMemoryContext; + } + private List publishedEvents = new ArrayList<>(); public List getPublishedEvents() { diff --git a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/TestDataLoader-mongodb.java.hbs b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/TestDataLoader-mongodb.java.hbs index bda43ffd..21af6a4d 100644 --- a/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/TestDataLoader-mongodb.java.hbs +++ b/plugins/backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/BackendApplicationDefaultGenerator/src/test/java/config/TestDataLoader-mongodb.java.hbs @@ -28,6 +28,7 @@ public class TestDataLoader { public TestDataLoader(List> mongoManagedTypes) { this.mongoManagedTypes = mongoManagedTypes; + mappingConverter = mappingConverter(); } public List loadCollectionTestDataAsObjects(Class collectionClass) { @@ -67,7 +68,7 @@ public class TestDataLoader { return mappingConverter.read(type, org.bson.Document.parse(json)); } - MappingMongoConverter mappingConverter = mappingConverter(); + MappingMongoConverter mappingConverter; MappingMongoConverter mappingConverter() { MappingMongoConverter mappingConverter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mongoMappingContext()); From 5860d329c921584787c2f6c5e6fd51e7b6675ba1 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Sat, 30 Mar 2024 10:23:54 +0100 Subject: [PATCH 6/6] upgrades jacoco --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cf5ebb6a..1564abed 100644 --- a/pom.xml +++ b/pom.xml @@ -190,7 +190,7 @@ org.jacoco jacoco-maven-plugin - 0.8.7 + 0.8.11 com/intuit/karate/core/**