Skip to content

Commit

Permalink
e2e: customer-address-relational.zdl
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangsa committed Jan 28, 2024
1 parent 332e3de commit 9ea0f18
Show file tree
Hide file tree
Showing 26 changed files with 856 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package io.zenwave360.sdk.e2e;

import java.io.File;

import io.zenwave360.sdk.options.DatabaseType;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.*;

import io.zenwave360.sdk.MainGenerator;
import io.zenwave360.sdk.Plugin;
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 TestCustomerAddressRelationalProject {

private static String project = "customer-address-relational";
private static String sourceFolder = "src/test/resources/projects/" + project + "/";
private static String targetFolder = "target/projects/" + project + "/";
private String basePackage = "io.zenwave360.example";
private String zdlFile = targetFolder + "/customer-address-relational.zdl";

@BeforeAll
public static void beforeAll() throws Exception {
// 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());
}

// @Test
public void test() throws Exception {
Plugin plugin = new BackendApplicationDefaultPlugin()
.withSpecFile(zdlFile)
.withTargetFolder(targetFolder)
.withOption("basePackage", basePackage)
.withOption("persistence", PersistenceType.jpa)
.withOption("databaseType", DatabaseType.mariadb)
.withOption("style", ProgrammingStyle.imperative)
.withOption("useLombok", true)
.withOption("includeEmitEventsImplementation", true)
.withOption("forceOverwrite", true)
.withOption("haltOnFailFormatting", false);


new MainGenerator().generate(plugin);
// int exitCode = MavenCompiler.compile(new File(targetFolder));
// Assertions.assertEquals(0, exitCode);
}

@Order(1)
@Test
public void generateApis() throws Exception {
Plugin plugin = null;

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);

var replace = " - name: \"identifier\"\n" +
" in: path\n" +
" required: true\n" +
" schema:\n" +
" type: integer\n" +
" format: int64";
var replacement = " - name: \"identifier\"\n" +
" in: path\n" +
" required: true\n" +
" schema:\n" +
" type: string";
TextUtils.replaceInFile(new File(targetFolder + "/src/main/resources/apis/openapi.yml"), replace, replacement);

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);
}

@Order(2)
@Test
public void generateSourceFromAPIs() throws Exception {
int exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);
}

@Order(3)
@Test
public void generateModule() throws Exception {
Plugin plugin = null;
int exitCode = 0;

plugin = new BackendApplicationDefaultPlugin()
.withSpecFile(zdlFile)
.withTargetFolder(targetFolder)
.withOption("basePackage", basePackage)
.withOption("persistence", PersistenceType.jpa)
.withOption("databaseType", DatabaseType.mariadb)
.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}}.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);
exitCode = MavenCompiler.compile(new File(targetFolder));
Assertions.assertEquals(0, exitCode);
}

}
22 changes: 22 additions & 0 deletions e2e/src/test/java/io/zenwave360/sdk/e2e/TextUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.zenwave360.sdk.e2e;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

public class TextUtils {

public static void replaceInFile(File file, String regex, String replacement) throws IOException {
String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
content = Pattern.compile(fixMultilineRegex(regex), Pattern.MULTILINE).matcher(content).replaceAll(replacement);
FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8);
}

public static String fixMultilineRegex(String text) {
return StringUtils.replace(text, "\r\n", "\\n").replace("\n", "\\r?\\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* 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 */
}

@aggregate
entity 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 */
}

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

relationship ManyToOne {
Address{customer} to Customer
}


// == 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("/{customerId}/address/{identifier}")
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 9ea0f18

Please sign in to comment.