Skip to content

Commit

Permalink
Merge pull request #29 from ZenWave360/develop
Browse files Browse the repository at this point in the history
Promote to Main (version 1.5.1)
  • Loading branch information
ivangsa authored May 8, 2024
2 parents 88d7511 + 1511fa0 commit 882a4e0
Show file tree
Hide file tree
Showing 60 changed files with 1,798 additions and 79 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,25 @@ ZenWave SDK is a configurable and extensible toolkit for **Domain Driven Design
The easiest way to install ZenWave SDK is as a [JBang alias](https://www.jbang.dev/documentation/guide/latest/alias_catalogs.html):

```shell
jbang alias add --fresh --name=zw release@zenwave360/zenwave-sdk
jbang alias add --fresh --force --name=zw release@zenwave360/zenwave-sdk
```

or if you prefer to use the latest **snapshot** versions:

```shell
jbang alias add --fresh --name=zw snapshots@zenwave360/zenwave-sdk
jbang alias add --fresh --force --name=zw snapshots@zenwave360/zenwave-sdk
```

or if you prefer to use the _next_ experimental/unstable **snapshot** versions:

```shell
jbang alias add --fresh --name=zw next@zenwave360/zenwave-sdk
jbang alias add --fresh --force --name=zw next@zenwave360/zenwave-sdk
```

If you plan to use **custom plugins** you will need to use the command in the following format:

```shell
jbang alias add --name=zw \
jbang alias add --name=zw --force \
-m=io.zenwave360.sdk.Main \
--repos=mavencentral,snapshots=https://s01.oss.sonatype.org/content/repositories/snapshots \
--deps=\
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package io.zenwave360.sdk.e2e;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import io.zenwave360.sdk.MainGenerator;
import io.zenwave360.sdk.Plugin;
import io.zenwave360.sdk.options.DatabaseType;
import io.zenwave360.sdk.options.PersistenceType;
import io.zenwave360.sdk.options.ProgrammingStyle;
import io.zenwave360.sdk.plugins.BackendApplicationDefaultPlugin;
import io.zenwave360.sdk.plugins.OpenAPIControllersPlugin;
import io.zenwave360.sdk.plugins.ZDLToAsyncAPIPlugin;
import io.zenwave360.sdk.plugins.ZDLToOpenAPIPlugin;
import io.zenwave360.sdk.testutils.MavenCompiler;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestCustomerAddressPostgresJsonProject {
private String basePackage = "io.zenwave360.example";

@Test
public void testCustomerAddressPostgresJson() throws Exception {
String sourceFolder = "src/test/resources/projects/customer-address-postgres-json/";
String targetFolder = "target/customer-address-postgres-json/";
String zdlFile = targetFolder + "/customer-address-postgres-json.zdl";

// copy whole dir from sourceFolder to targetFolder
FileUtils.deleteDirectory(new File(targetFolder));
FileUtils.forceMkdir(new File(targetFolder));
FileUtils.copyDirectory(new File(sourceFolder), new File(targetFolder));
Assertions.assertTrue(new File(targetFolder).exists());

Plugin plugin = null;
int exitCode = 0;

plugin = new ZDLToOpenAPIPlugin()
.withSpecFile(zdlFile)
.withOption("idType", "integer")
.withOption("idTypeFormat", "int64")
.withOption("targetFile", "/src/main/resources/apis/openapi.yml")
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

plugin = new ZDLToAsyncAPIPlugin()
.withSpecFile(zdlFile)
.withOption("asyncapiVersion", "v3")
.withOption("idType", "integer")
.withOption("idTypeFormat", "int64")
.withOption("targetFile", "/src/main/resources/apis/asyncapi.yml")
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

plugin = new BackendApplicationDefaultPlugin()
.withSpecFile(zdlFile)
.withTargetFolder(targetFolder)
.withOption("basePackage", basePackage)
.withOption("persistence", PersistenceType.jpa)
.withOption("databaseType", DatabaseType.postgresql)
.withOption("style", ProgrammingStyle.imperative)
.withOption("useLombok", true)
.withOption("includeEmitEventsImplementation", true)
.withOption("forceOverwrite", true)
.withOption("haltOnFailFormatting", false);

new MainGenerator().generate(plugin);

TextUtils.replaceInFile(new File(targetFolder + "/src/main/java/io/zenwave360/example/core/implementation/mappers/EventsMapper.java"),
"io.zenwave360.example.core.outbound.events.dtos.Customer asCustomer\\(Customer customer\\);",
"""
@org.mapstruct.Mapping(target = "extraProperties", ignore = true)
io.zenwave360.example.core.outbound.events.dtos.Customer asCustomer(Customer customer);
""");

exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);

plugin = new OpenAPIControllersPlugin()
.withSpecFile(targetFolder + "/src/main/resources/apis/openapi.yml")
.withOption("zdlFile", zdlFile)
.withOption("basePackage", basePackage)
.withOption("controllersPackage", "{{basePackage}}.adapters.web")
.withOption("openApiApiPackage", "{{basePackage}}.adapters.web")
.withOption("openApiModelPackage", "{{basePackage}}.adapters.web.model")
.withOption("openApiModelNameSuffix", "DTO")
// .withOption("operationIds", List.of("addPet", "updatePet"))
.withOption("style", ProgrammingStyle.imperative)
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

TextUtils.replaceInFile(new File(targetFolder + "/src/main/java/io/zenwave360/example/adapters/web/mappers/CustomerDTOsMapper.java"),
"// request mappings",
"""
// request mappings
default Map map(Object value) { return new HashMap();}
""");

exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package io.zenwave360.sdk.e2e;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import io.zenwave360.sdk.MainGenerator;
import io.zenwave360.sdk.Plugin;
import io.zenwave360.sdk.options.DatabaseType;
import io.zenwave360.sdk.options.PersistenceType;
import io.zenwave360.sdk.options.ProgrammingStyle;
import io.zenwave360.sdk.plugins.BackendApplicationDefaultPlugin;
import io.zenwave360.sdk.plugins.OpenAPIControllersPlugin;
import io.zenwave360.sdk.plugins.ZDLToAsyncAPIPlugin;
import io.zenwave360.sdk.plugins.ZDLToOpenAPIPlugin;
import io.zenwave360.sdk.testutils.MavenCompiler;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestSimpleDomainPackagingProject {
private String basePackage = "io.zenwave360.example.customer";

@Test
public void testCustomerAddressPostgresJson() throws Exception {
String sourceFolder = "src/test/resources/projects/simple-domain-packaging/";
String targetFolder = "target/projects/simple-domain-packaging";
String zdlFile = targetFolder + "/customer-address-relational-one-to-many.zdl";

// copy whole dir from sourceFolder to targetFolder
FileUtils.deleteDirectory(new File(targetFolder));
FileUtils.forceMkdir(new File(targetFolder));
FileUtils.copyDirectory(new File(sourceFolder), new File(targetFolder));
Assertions.assertTrue(new File(targetFolder).exists());

Plugin plugin = null;
int exitCode = 0;

plugin = new ZDLToOpenAPIPlugin()
.withSpecFile(zdlFile)
.withOption("idType", "integer")
.withOption("idTypeFormat", "int64")
.withOption("targetFile", "/src/main/resources/apis/openapi.yml")
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

plugin = new ZDLToAsyncAPIPlugin()
.withSpecFile(zdlFile)
.withOption("asyncapiVersion", "v3")
.withOption("idType", "integer")
.withOption("idTypeFormat", "int64")
.withOption("targetFile", "/src/main/resources/apis/asyncapi.yml")
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

plugin = new BackendApplicationDefaultPlugin()
.withSpecFile(zdlFile)
.withTargetFolder(targetFolder)

.withOption("simpleDomainPackaging", true)

.withOption("basePackage", basePackage)
.withOption("persistence", PersistenceType.jpa)
.withOption("databaseType", DatabaseType.postgresql)
.withOption("style", ProgrammingStyle.imperative)
.withOption("useLombok", true)
.withOption("includeEmitEventsImplementation", true)
.withOption("forceOverwrite", true)
.withOption("haltOnFailFormatting", false);

new MainGenerator().generate(plugin);

exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);

plugin = new OpenAPIControllersPlugin()
.withSpecFile(targetFolder + "/src/main/resources/apis/openapi.yml")
.withOption("zdlFile", zdlFile)
.withOption("basePackage", basePackage)
.withOption("controllersPackage", "{{basePackage}}")
.withOption("openApiApiPackage", "{{basePackage}}")
.withOption("openApiModelPackage", "{{basePackage}}.dtos")
.withOption("openApiModelNameSuffix", "DTO")

.withOption("entitiesPackage", "{{basePackage}}.model")
.withOption("inboundDtosPackage", "{{basePackage}}.dtos")
.withOption("servicesPackage", "{{basePackage}}")

// .withOption("operationIds", List.of("addPet", "updatePet"))
.withOption("style", ProgrammingStyle.imperative)
.withTargetFolder(targetFolder);
new MainGenerator().generate(plugin);

exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* Simple Event-Driven CRUD for Customer/Addresses.
*/
config {
title "ZenWave Playground Customer-Address MariaDB"
basePackage "io.zenwave360.example"
persistence jpa
databaseType mariadb
// haltOnFailFormatting false

plugins {

ZDLToOpenAPIPlugin {
idType integer
idTypeFormat int64
targetFile "src/main/resources/apis/openapi.yml"
}

ZDLToAsyncAPIPlugin {
asyncapiVersion v3
idType integer
idTypeFormat int64
targetFile "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
specFile "src/main/resources/apis/openapi.yml"
zdlFile "customer-address-relational.zdl"

// thse should match the values of openapi-generator-maven-plugin
openApiApiPackage "{{basePackage}}.adapters.web"
openApiModelPackage "{{basePackage}}.adapters.web.model"
openApiModelNameSuffix DTO
}
}
}


// == Entities =============================
/**
* Customer javadoc comment
*/
@aggregate
entity Customer {
username String required unique /** username javadoc comment */
email String required unique /** email javadoc comment */
@jsonb
address Address {
street String required /** street javadoc comment */
city String /** city javadoc comment */
state String /** state javadoc comment */
zip String /** zip javadoc comment */
type AddressType required /** address type is an enum */
}
@jsonb extraProperties Map = "new HashMap<String, Object>()"
}

enum AddressType { HOME(1) /** home description */, WORK(1) /** work description */ }


// == Services =============================

@inline
input AddressInput {
identifier String required /** Description identifier for this Address */
address Address
}

/**
Service javadoc comment
*/
@rest("/customers")
service CustomerService for (Customer) {
/**
* Create customer javadoc comment
*/
@post
createCustomer(Customer) Customer withEvents CustomerEvent

@put("/{customerId}")
updateCustomer(id, Customer) Customer? withEvents CustomerEvent

/** Updates a the customer address identified by address.identifier */
@put({path: "/{customerId}/address/{identifier}", params: {identifier: String}})
updateCustomerAddress(id, AddressInput) Customer? withEvents CustomerEvent CustomerAddressUpdated

@delete("/{customerId}")
deleteCustomer(id) withEvents CustomerEvent

@get("/{customerId}")
getCustomer(id) Customer?

@get({params: {search: "string"}})
@paginated
listCustomers() Customer[]
}

// == Events =============================

@skip // skip generating this domain enum, it will genereate by asyncapi code generator.
enum EventType { CREATED(1) /** created description */, UPDATED(1) /** updated description */, DELETED(1) /** deleted description */ }

@asyncapi({channel: "CustomerEventsChannel", topic: "customer.events"})
event CustomerEvent {
customerId String
eventType EventType
customer Customer
}

@asyncapi({channel: "CustomerAddressEventsChannel", topic: "customer.address-events"})
event CustomerAddressUpdated {
customerId String
addressDescription String
originalAddress Address
newAddress Address
}
Loading

0 comments on commit 882a4e0

Please sign in to comment.