-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate events using jsonschema2pojo and mustache template (#58)
Initial changes to generate events using jsonschema2pojo and mustache template, /src/main/resources/template/event-template.mustache pom.xml has the plugin to generate jsonschema2pojo and plugin to run the main class from CDEventsGenerator to create events using mustache template. Running ./mvnw verify Generates models using jsonschema2pojo for each event under - dev.cdevents.models.generated.subject.predicate Generates events from mustache template and placed under - dev.cdevents.events.generated Note: Generating only 3 events for an initial review and schema files for the same are placed under - /src/main/resources/schema (This will essentially point to spec repo to generate all the events once reviewed) Removed current Events(dev.cdevents.events) and Models(dev.cdevents.models) that are manually created earlier. --------- Signed-off-by: Jalander Ramagiri <[email protected]> Co-authored-by: Lapenta Francesco Davide <[email protected]>
- Loading branch information
Showing
109 changed files
with
3,492 additions
and
10,066 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>dev.cdevents</groupId> | ||
<artifactId>cdevents-sdk-java-parent</artifactId> | ||
<version>0.1.3-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>cdevents-sdk-java-generator</artifactId> | ||
|
||
<name>cdevents-sdk-java-generator</name> | ||
<description>Source code generator for CDEvents Java SDK</description> | ||
<url>https://github.com/cdevents</url> | ||
|
||
<properties> | ||
<maven.javadoc.skip>true</maven.javadoc.skip> | ||
<maven.source.skip>true</maven.source.skip> | ||
<maven.deploy.skip>true</maven.deploy.skip> | ||
<maven.compiler.source>11</maven.compiler.source> | ||
<maven.compiler.target>11</maven.compiler.target> | ||
<sdk.project.dir>${project.basedir}/../sdk</sdk.project.dir> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.fasterxml.jackson.core</groupId> | ||
<artifactId>jackson-databind</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.fasterxml.jackson.datatype</groupId> | ||
<artifactId>jackson-datatype-jsr310</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
<version>${slf4j.version}</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
<version>3.12.0</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.github.spullara.mustache.java</groupId> | ||
<artifactId>compiler</artifactId> | ||
<version>0.9.6</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-simple</artifactId> | ||
<version>${slf4j.version}</version> | ||
<scope>runtime</scope> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.jsonschema2pojo</groupId> | ||
<artifactId>jsonschema2pojo-maven-plugin</artifactId> | ||
<version>1.2.1</version> | ||
<configuration> | ||
<outputDirectory>${sdk.project.dir}/src/main/java</outputDirectory> | ||
<includeHashcodeAndEquals>false</includeHashcodeAndEquals> | ||
<includeToString>false</includeToString> | ||
<addCompileSourceRoot>false</addCompileSourceRoot> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>generate-artifact-packaged-from-schema</id> | ||
<phase>generate-sources</phase> | ||
<goals> | ||
<goal>generate</goal> | ||
</goals> | ||
<configuration> | ||
<sourcePaths> | ||
<sourcePath>${sdk.project.dir}/src/main/resources/schema/artifact-packaged-event.json | ||
</sourcePath> | ||
</sourcePaths> | ||
<targetPackage>dev.cdevents.models.artifact.packaged</targetPackage> | ||
</configuration> | ||
</execution> | ||
<execution> | ||
<id>generate-artifact-published-from-schema</id> | ||
<phase>generate-sources</phase> | ||
<goals> | ||
<goal>generate</goal> | ||
</goals> | ||
<configuration> | ||
<sourcePaths> | ||
<sourcePath>${sdk.project.dir}/src/main/resources/schema/artifact-published-event.json | ||
</sourcePath> | ||
</sourcePaths> | ||
<targetPackage>dev.cdevents.models.artifact.published</targetPackage> | ||
</configuration> | ||
</execution> | ||
<execution> | ||
<id>generate-pipeline-run-finished-from-schema</id> | ||
<phase>generate-sources</phase> | ||
<goals> | ||
<goal>generate</goal> | ||
</goals> | ||
<configuration> | ||
<sourcePaths> | ||
<sourcePath> | ||
${sdk.project.dir}/src/main/resources/schema/pipeline-run-finished-event.json | ||
</sourcePath> | ||
</sourcePaths> | ||
<targetPackage>dev.cdevents.models.pipelinerun.finished</targetPackage> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.codehaus.mojo</groupId> | ||
<artifactId>exec-maven-plugin</artifactId> | ||
<version>3.1.0</version> | ||
<executions> | ||
<execution> | ||
<id>run-CDEventsGenerator-main-class</id> | ||
<phase>process-classes</phase> | ||
<goals> | ||
<goal>java</goal> | ||
</goals> | ||
<configuration> | ||
<mainClass>dev.cdevents.generator.CDEventsGenerator</mainClass> | ||
<arguments> | ||
<argument>${project.basedir}</argument> | ||
<argument>${sdk.project.dir}</argument> | ||
</arguments> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
165 changes: 165 additions & 0 deletions
165
generator/src/main/java/dev/cdevents/generator/CDEventsGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
package dev.cdevents.generator; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.github.mustachejava.DefaultMustacheFactory; | ||
import com.github.mustachejava.Mustache; | ||
import com.github.mustachejava.MustacheFactory; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import java.io.BufferedWriter; | ||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public final class CDEventsGenerator { | ||
|
||
private CDEventsGenerator() { | ||
} | ||
|
||
private static ObjectMapper objectMapper = new ObjectMapper(); | ||
private static Logger log = LoggerFactory.getLogger(CDEventsGenerator.class); | ||
|
||
private static final int SUBJECT_INDEX = 2; | ||
private static final int PREDICATE_INDEX = 3; | ||
private static final int VERSION_INDEX = 4; | ||
private static final int SUBSTRING_PIPELINE_INDEX = 8; | ||
|
||
private static final String TARGET_PACKAGE = "src/main/java/dev/cdevents/events"; | ||
|
||
/** | ||
* Event JsonSchema files location. | ||
*/ | ||
private static final String RESOURCES_DIR = "src/main/resources/"; | ||
/** | ||
* Mustache generic event template file. | ||
*/ | ||
private static final String EVENT_TEMPLATE_MUSTACHE = RESOURCES_DIR + "template/event-template.mustache"; | ||
|
||
/** | ||
* Main method to generate CDEvents from Json schema files. | ||
* @param args [0] - base directory for the cdevents-java-sdk-generator module | ||
* [1] - base directory for the cdevents-java-sdk module | ||
*/ | ||
public static void main(String[] args) { | ||
if (args == null || args.length < 2) { | ||
throw new IllegalArgumentException("Insufficient arguments passed to CDEventsGenerator"); | ||
} | ||
String generatorBaseDir = args[0]; | ||
String sdkBaseDir = args[1]; | ||
String targetPackageDir = sdkBaseDir + File.separator + "src/main/java/dev/cdevents/events"; | ||
File folder = new File(sdkBaseDir + File.separator + RESOURCES_DIR + "schema"); | ||
System.out.println(folder.toPath().toAbsolutePath()); | ||
if (folder.isDirectory()) { | ||
File[] files = folder.listFiles((dir, name) -> name.toLowerCase().endsWith(".json")); | ||
if (files != null) { | ||
//Create Mustache factory and compile event-template.mustache template | ||
MustacheFactory mf = new DefaultMustacheFactory(); | ||
Mustache mustache = mf.compile(generatorBaseDir + File.separator + EVENT_TEMPLATE_MUSTACHE); | ||
|
||
//Generate a class file for each Json schema file using a mustache template | ||
|
||
for (File file : files) { | ||
SchemaData schemaData = buildCDEventDataFromJsonSchema(file); | ||
generateClassFileFromSchemaData(mustache, schemaData, targetPackageDir); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static void generateClassFileFromSchemaData(Mustache mustache, SchemaData schemaData, String targetPackageDir) { | ||
String classFileName = StringUtils.join(new String[]{schemaData.getCapitalizedSubject(), schemaData.getCapitalizedPredicate(), "CDEvent", ".java"}); | ||
File classFile = new File(targetPackageDir, classFileName); | ||
try { | ||
FileWriter fileWriter = new FileWriter(classFile); | ||
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); | ||
mustache.execute(bufferedWriter, schemaData).flush(); | ||
fileWriter.close(); | ||
} catch (IOException e) { | ||
log.error("Exception occurred while generating class file from Json schema {}", e.getMessage()); | ||
throw new IllegalStateException("Exception occurred while generating class file from Json schema ", e); | ||
} | ||
log.info("Rendered event-template has been written to file - {}", classFile.getAbsolutePath()); | ||
} | ||
|
||
private static SchemaData buildCDEventDataFromJsonSchema(File file) { | ||
SchemaData schemaData = new SchemaData(); | ||
|
||
log.info("Processing event JsonSchema file: {}", file.getAbsolutePath()); | ||
try { | ||
JsonNode rootNode = objectMapper.readTree(file); | ||
JsonNode contextNode = rootNode.get("properties").get("context").get("properties"); | ||
|
||
String eventType = contextNode.get("type").get("enum").get(0).asText(); | ||
log.info("eventType: {}", eventType); | ||
String[] type = eventType.split("\\."); | ||
String subject = type[SUBJECT_INDEX]; | ||
String predicate = type[PREDICATE_INDEX]; | ||
String capitalizedSubject = StringUtils.capitalize(subject); | ||
if (subject.equals("pipelinerun")) { | ||
capitalizedSubject = capitalizedSubject.substring(0, SUBSTRING_PIPELINE_INDEX) | ||
+ StringUtils.capitalize(subject.substring(SUBSTRING_PIPELINE_INDEX)); | ||
} | ||
String capitalizedPredicate = StringUtils.capitalize(predicate); | ||
String version = type[VERSION_INDEX]; | ||
|
||
//set the Schema JsonNode required values to schemaData | ||
schemaData.setSubject(subject); | ||
schemaData.setPredicate(predicate); | ||
schemaData.setCapitalizedSubject(capitalizedSubject); | ||
schemaData.setCapitalizedPredicate(capitalizedPredicate); | ||
schemaData.setSchemaFileName(file.getName()); | ||
schemaData.setUpperCaseSubject(subject.toUpperCase()); | ||
schemaData.setVersion(version); | ||
|
||
JsonNode subjectNode = rootNode.get("properties").get("subject").get("properties"); | ||
JsonNode subjectContentNode = subjectNode.get("content").get("properties"); | ||
updateSubjectContentProperties(schemaData, subjectContentNode); | ||
} catch (IOException e) { | ||
log.error("Exception occurred while building schema data from Json schema {}", e.getMessage()); | ||
throw new IllegalStateException("Exception occurred while building schema data from Json schema ", e); | ||
} | ||
return schemaData; | ||
} | ||
|
||
private static void updateSubjectContentProperties(SchemaData schemaData, JsonNode subjectContentNode) { | ||
Iterator<Map.Entry<String, JsonNode>> contentProps = subjectContentNode.fields(); | ||
List<SchemaData.ContentField> contentFields = new ArrayList<>(); | ||
List<SchemaData.ContentObjectField> contentObjectFields = new ArrayList<>(); | ||
while (contentProps.hasNext()) { | ||
Map.Entry<String, JsonNode> contentMap = contentProps.next(); | ||
String contentField = contentMap.getKey(); | ||
String capitalizedContentField = StringUtils.capitalize(contentField); | ||
JsonNode contentNode = contentMap.getValue(); | ||
if (!contentNode.get("type").asText().equals("object")) { | ||
contentFields.add(new SchemaData.ContentField(contentField, capitalizedContentField, "String")); | ||
} else { | ||
schemaData.setObjectName(contentField); | ||
schemaData.setCapitalizedObjectName(capitalizedContentField); | ||
JsonNode contentObjectNode = contentNode.get("properties"); | ||
Iterator<String> contentObjectProps = contentObjectNode.fieldNames(); | ||
while (contentObjectProps.hasNext()) { | ||
String contentObjField = contentObjectProps.next(); | ||
String capitalizedContentObjField = StringUtils.capitalize(contentObjField); | ||
contentObjectFields.add(new SchemaData.ContentObjectField(contentObjField, | ||
capitalizedContentObjField, contentField, capitalizedContentField, "String")); | ||
} | ||
} | ||
} | ||
schemaData.setContentFields(contentFields); | ||
schemaData.setContentObjectFields(contentObjectFields); | ||
} | ||
|
||
private static String getFieldsDataType(String fieldName) { | ||
if (fieldName.equalsIgnoreCase("url")) { | ||
return "URI"; | ||
} else { | ||
return "String"; | ||
} | ||
} | ||
} |
Oops, something went wrong.