Giter Club home page Giter Club logo

java-spring-cloud-stream-template's Introduction

Java Spring Cloud Stream Generator Template

This template generates a Spring Cloud Stream (SCSt) microservice. It uses version 3 of SCSt which uses function names to configure the channels. See the reference. The generated microservice is a Maven project so it can easily be imported into your IDE.

This template has been tested with Kafka, RabbitMQ and Solace.

The Spring Cloud Stream microservice generated using this template will be an ready to run Spring Boot app. By default, the microservice will contain a java class, Application.java, which includes methods to publish or subscribe events as defined in the AsyncAPI document. These generated methods include Supplier, Consumer and Function functional interfaces from the java.util.function package. These methods will already be pre-configured to publish to and consume from the channels as defined in the AsyncAPI. This configuration is located in the spring.cloud.stream section of the generated application.yml file.

Note that this template ignores the 'Servers' section of AsyncAPI documents. The main reason for this is because SCSt does not directly work with messaging protocols. Protocols are implementation details specific to binders, and SCSt applications need not know or care which protocol is being used.

Technical requirements

Specification Conformance

Note that this template interprets the AsyncAPI document in conformance with the AsyncAPI Specification. This means that when the template sees a subscribe operation, it will generate code to publish to that operation's channel. It is possible to override this, see the 'view' parameter in the parameters section below.

Which Methods are created

The template works as follows:

  • By default, for each channel in the AsyncAPI document, if there is a subscribe operation a Supplier method will be generated, and for a publish operation a Consumer method will get generated.

  • To customize this default behavior, you can make use of the x-scs-function-name extension. If one publish operation and one subscribe operation share a x-scs-function-name attribute then a java.util.function.Function method will be created which uses the subscribe operation's message as the input and the publish operation's message as the output to the generated Function method. It will also wire up the proper channel information in the generated application.yaml file.

  • Note that at this time the generator does not support the creation of functions that have more than one publish and/or more than one subscribe operation with the same x-scs-function-name attribute. This scenario will result in error.

  • Additionally, if a channel has parameters and a subscribe operation, a send method will be generated that takes the payload and the parameters as function arguments, formats the topic from the parameters, and sends the message using the StreamBridge as described in the Spring Cloud Steam documentation. If you use x-scs-function-name to combine a subscribe and a publish operation and the subscribe operation has parameters, then this template will render a Consumer method that will receive a message and then call the generated send method to send out a new message through the StreamBridge.

    This behaviour may be modified by setting the dynamicType parameter to 'header'. This is to support binders that can route messages by putting the topic into a message header. In this case, a Supplier and a Function will set the header on the message rather than use the StreamBridge, however send methods will still be rendered for convenience.

Method Naming

The generated methods are named as follows:

  • For each operation (i.e., publish or subscribe in each channel), the template looks for the specification extension x-scs-function-name. If present, it uses that to name the function.
  • If using the same x-scs-function-name on one publish operation and one subscribe operation to create a Function the name of the generated method will be the x-scs-function-name
  • If there is no x-scs-function-name attribute, the generator checks the operation's operationId value. If set, that is used as the function name.
  • If there is no x-scs-function-name or operationId available, then a name will be generated by taking the channel name, removing non-alphanumeric characters, converting to camel case, and appending 'Supplier' or 'Producer.' For example, if there is a channel called store/process with a publisher operation with a payload called Order, the following method will get generated:
@Bean
public Supplier<Order> storeProcessSupplier () {
 // Add business logic here.
 return null;
}

Property Naming

When converting from property names to Java field names, the property names are first converted to camelCase, removing non-alphanumeric characters in the process. If the resulting name ends up being a Java keyword, it is prepended with an underscore.

Application vs Library

By default, this will generate a runnable Spring Boot application. If you set the artifactType parameter to library, then it will generate a project without a main Application class and without the main Spring Boot dependencies. That will produce a library that can be imported into another application as a Maven artifact. It will contain the model classes and the Spring Cloud Stream configuration.

Doing that allows you to have a clean separation between the generated code and your hand-written code, and ensures that regenerating the library will not overwrite your business logic.

How to Use This Template

  1. Install the AsyncAPI Generator
npm install -g @asyncapi/generator
  1. Run the Generator using the Java Spring Cloud Stream Template
ag ~/AsyncApiDocument.yaml @asyncapi/java-spring-cloud-stream-template
  1. Run the Generator using the Java Spring Cloud Stream Template with Parameters
ag -p binder=solace -p artifactId=ExampleArtifactId -p groupId=com.example -p javaPackage=com.example.foo -p solaceSpringCloudVersion=1.0.0 -p springCloudStreamVersion=Horsham.SR3 -p springCloudVersion=Hoxton.SR3 ~/AsyncApiDocument.yaml @asyncapi/java-spring-cloud-stream-template

Configuration Options

Please note that none of the parameters or specification extensions is required. All parameters have defaults as documented below.

Any parameters or specification extensions that include the name 'Solace' only have an effect when the Solace binder is specified. If and when other binder-specific parameters are added to this template, they will follow a similar naming pattern.

Destination Overrides

There are two specification extensions you can use to shape how the bindings are configured. You can add the following to a subscribe operation:

x-scs-destination : This overrides the destination value in a binder. This is useful when you are using the Solace binder and you are following the Solace pattern of publishing to topics and consuming from queues. In this case the x-scs-destination value would be treated as the name of the queue which your microservice will consume from.

x-scs-group : This will add the group value on a binding which configures your microservice to use Consumer Groups

Limitations

Currently any schemas that are used must be in the components/schemas part of the document. We do not support anonymous object-type schemas in the message/payload sections.

Parameters

Parameters can be passed to the generator using command line arguments in the form -p param=value -p param2=value2. Here is a list of the parameters that can be used with this template. In some cases these can be put into the AsyncAPI documents using the specification extensions feature. In those cases, the 'info' prefix means that it belongs in the info section of the document.

Parameter Extension Default Description
actuator false If true, it adds the dependencies for spring-boot-starter-web, spring-boot-starter-actuator and micrometer-registry-prometheus.
artifactId info.x-artifact-id project-name The Maven artifact id.
artifactType application The type of project to generate, application or library. When generating an application, the pom.xml file will contain the complete set of dependencies required to run an app, and it will contain an Application class with a main function. Otherwise the pom file will include only the dependencies required to compile a library.
binder kafka The name of the binder implementation, one of kafka, rabbit or solace. Default: kafka. If you need other binders to be supported, please let us know!
dynamicType streamBridge If you publish to a channel with parameters, i.e. a topic that can change with every message, the standard way to do this is to use StreamBridge. But some binders such as Solace can do the dynamic routing using just a message header. If you use such a binder, then you can set this value to 'header' and the generated code will set the topic on the header rather than use StreamBridge.
groupId info.x-group-id com.company The Maven group id.
host tcp://localhost:55555 The host connection property. Currently this only works with the Solace binder. When other binders are used this parameter is ignored.
javaPackage info.x-java-package The Java package of the generated classes. If not set then the classes will be in the default package.
msgVpn default The message vpn connection property. Currently this only works with the Solace binder. When other binders are used this parameter is ignored.
password default The client password connection property. Currently this only works with the Solace binder. When other binders are used this parameter is ignored.
parametersToHeaders false If true, this will create headers on the incoming messages for each channel parameter. Currently this only works with messages originating from Solace (using the solace_destination header) and RabbitMQ (using the amqp_receivedRoutingKey header.)
reactive false If true, the generated functions will use the Reactive style and use the Flux class.
solaceSpringCloudVersion info.x-solace-spring-cloud-version 2.1.0 The version of the solace-spring-cloud-bom dependency used when generating an application.
springBootVersion info.x-spring-boot-version 2.4.7 The version of Spring Boot used when generating an application.
springCloudVersion info.x-spring-cloud-version 2020.0.3 The version of the spring-cloud-dependencies BOM dependency used when generating an application.
springCloudStreamVersion info.x-spring-cloud-stream-version 3.1.3 The version of the spring-cloud-stream dependency specified in the Maven file, when generating a library. When generating an application, the spring-cloud-dependencies BOM is used instead
username default The client username connection property. Currently this only works with the Solace binder. When other binders are used this parameter is ignored.
view info.x-view client By default, this template generates publisher code for subscribe operations and vice versa. You can switch this by setting this parameter to 'provider'.
useServers false This parameter only works when the binder parameter is kafka. It takes all the urls under the server section and concatenates them to a set of brokers.

Specification Extensions

The following specification extensions are supported. In some cases, their value can be provided as a command line parameter. The 'info' prefix means that it belongs in the info section of the document.

Extension Parameter Default Description
info.x-artifact-id artifactId project-name The Maven artifact id.
info.x-group-id groupId com.company The Maven group id.
info.x-java-package javaPackage The Java package of the generated classes. If not set then the classes will be in the default package.
info.x-solace-spring-cloud-version solaceSpringCloudVersion 1.0.0 The version of the solace-spring-cloud BOM dependency used when generating an application.
info.x-spring-boot-version info.x-spring-boot-version 2.2.6.RELEASE The version of the Spring Boot used when generating an application.
info.x-spring-cloud-version info.x-spring-cloud-version Hoxton.SR3 The version of the spring-cloud-dependencies BOM dependency used when generating an application.
info.x-spring-cloud-stream-version springCloudStreamVersion 3.0.3.RELEASE The version of the spring-cloud-stream dependency specified in the Maven file, when generating a library. When generating an application, the spring-cloud-dependencies BOM is used instead.
info.x-view view client By default, this template generates publisher code for subscribe operations and vice versa. You can switch this by setting this parameter to 'provider'.
operation.x-scs-function-name This specifies the base function name to use on a publish or subscribe operation. If the same name is used on one subscribe operation and one publish operation, a processor function will be generated.
channel.subscription.x-scs-destination This overrides the destination on an incoming binding. It can be used to specify, for example, the name of a queue to subscribe to instead of a topic.
channel.subscription.x-scs-group This is used to specify the group property of an incoming binding.

Development

This project follows the all-contributors specification. Contributions of any kind are welcome!

If you do contribute, please run npm run lint and npm test before you submit your code.

Contributors

Thanks goes to these wonderful people (emoji key):


Michael Davis

πŸ’» πŸ“– πŸ‘€ πŸ’¬

Marc DiPasquale

πŸ“–

Fran MΓ©ndez

πŸ’» πŸš‡

Lukasz Gornicki

πŸš‡ πŸ’»

blzsaa

πŸ’»

java-spring-cloud-stream-template's People

Contributors

allcontributors[bot] avatar amrutprabhu avatar anmaso avatar arshrai17 avatar asyncapi-bot avatar beni0888 avatar binsentsu avatar blzsaa avatar cameronrushton avatar codingtenshi avatar damaru-inc avatar dependabot[bot] avatar derberg avatar dyspc avatar fmvilas avatar hutchhutchhutch avatar joeljosedev avatar michaeldavissolace avatar mrc0113 avatar ragezbla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-spring-cloud-stream-template's Issues

Maven/Gradle plugin will exist?

Reason/Context

Hi,

Is there any plan to provide a maven/gradle plugin to generate code based on asyncapi?

Description

I know this is an initial stage of project but were wonderful to know if maven/gradle plugin will have native support and not depends on third party generation...

Regards

Update Default Versions

Should update the default versions of generated apps:

  • Use latest Spring Boot 2.4.X release. Since Spring Boot has modified their releases, 2.5 (when released) may deprecate code from 2.4 but won't remove it. By moving to 2.4 this should future proof the generated apps for a bit.
  • While doing that might as well update to latest Spring Cloud + default binder versions

Cannot render AsyncAPI document with no components

Describe the bug

const schemas = asyncapi.components().schemas();
assumes there will always be components when that's not the case.

{
  "asyncapi": "2.0.0",
  "info": {
    "title": "Streetlight",
    "version": "1.0.0"
  },
  "defaultContentType": "json",
  "channels": {
    "test": {
      "description": "Channel for the turn on command which should turn on the streetlight",
      "parameters": {
        "streetlight_id": {
          "description": "The ID of the streetlight",
          "schema": {
            "type": "string"
          }
        }
      },
      "publish": {
        "operationId": "test",
        "message": {
          "name": "TurnonCommand",
          "payload": {
            "x-parser-schema-id": "CustomClass",
            "$id": "CustomClass",
            "type": "object",
            "properties": {
              "prop1": { 
                  "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

Immediately return expression instead of assigning it to the temporary variable

3 occurances:

Reason:

Declaring a variable only to immediately return or throw it is a bad practice.

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

Noncompliant Code Example
function computeDurationInMilliseconds() {
  var duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
  return duration;
}
Compliant Solution
function computeDurationInMilliseconds() {
  return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
}

Cleanup GitHub Actions workflows

Context

  1. We want to make sure we have healthy community and people respec each other in GitHub. We want to monitor all comments in every repository and analyze sentiments to identify negative ones and get proper notification. Idea is to use GitHub Actions for it, to check sentiments with Google Natural Language API and post negative comments to Slack for review.

  2. We manage community files in global .github repo, and we have GitHub Funding config file there too. As a result we need to cleanup all the repos to remove .github/FUNDING.yml

  3. Start supporting new GitHub pull request event that allows gives access to GITHUB_TOKEN with write access. Fix welcome contributors workflow is needed.

  4. We want to automatically merge Pull Requests that are submitted by Dependanbot. New workflow needs to be added, or if already existins it needs to be modified

Description

  1. Add this workflow file called sentiment-analysis.yml to .github/workflows (create it if it doesn't exist yet) directory: https://gist.github.com/derberg/ab362e4b37f542e7e1813e67b7cb11ee
    Proper secrets are already added to GitHub organization so it is as simple as adding above file to workflows dir.
  2. Remove .github/FUNDING.yml if it exists
  3. If not done already rename pull_request from line 4 to pull_request_target in .github/workflows/welcome-first-time-contrib.yml file
  4. Create new file called automerge.yml with the following content: https://gist.github.com/derberg/024814a26959d54f683e7bd68d68f007
    If the repository already has a file called automerge-release-pr-bump.yml than rename it and adjust if statements to check github.actor == 'asyncapi-bot' || github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' instead of github.actor == 'asyncapi-bot'

Add support for schema constraints and descriptions

Reason/Context

This template currently ignores schema assertions such as 'maxLength' or 'required.' It also ignores the descriptions of the fields.

Description

It would be nice to use as much information as possible from the schema definitions in generating the Java POJOs.

Generator is failing to add "@Bean" annotation to java.util.function.Function contract

Describe the bug

Codegen failed to put the "@bean" annotation for the Function construct (corresponding import statement is also missing)

How to Reproduce

Snippet from AsyncAPI document:
....
channels:
'SmartTown/Operations/OperationalAlert/created/v1/{AlertPriority}/{AlertType}':
subscribe:
x-scs-function-name: processTemperatureReading
message:
$ref: '#/components/messages/OperationalAlert'
parameters:
AlertType:
schema:
type: string
AlertPriority:
schema:
type: string
'SmartTown/Operations/temperatureReading/created/v1/{city}/{latitude}/{longitude}':
publish:
x-scs-function-name: processTemperatureReading
message:
$ref: '#/components/messages/TemperatureReading'
parameters:
city:
schema:
type: string
latitude:
schema:
type: string
longitude:
schema:
type: string
....

Expected behavior

Just need to add the @bean annotation - otherwise one has to do that manually.

Extra words show up in the imports section of a schema file.

We saw this:

package com.solace.covidtracking.states;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
		has functions.
import java.util.function.Function

Allow for Channel Parameters to be available as message headers

Spring Cloud Stream / Spring Cloud Function are currently working on defining header mapping capabilities in this issue. Once available we should consider using this to allow for the AsyncAPI code generator template to make channel parameters available as headers on inbound messages.

For example if the generator received an AsyncAPI document containing a channel like the one below, it could (optionally?) generate the configuration for the parameters to be made available as headers on the Spring Message used by the developer.

channels:
  'taxinyc/ops/ride/updated/v1/{ride_status}/{driver_id}':
    publish:
      message:
        $ref: '#/components/messages/TaxiStatusUpdate'
    parameters:
      driver_id:
        schema:
          type: string
      ride_status:
        schema:
          type: string
          enum:
            - accepted
            - pickup
            - enroute
            - dropoff

An incorrect function signature was generated

Describe the bug

A user ran the template against a file that was missing some types on some properties. The generator created this function signature:

public Function<CovidTracking_StateCurrentData, CovidTracking_StateCurrentData > calculatePercentages()

which was wrong. After adding the property types the function was created properly:

public Function<CovidTracking_StateCurrentData, CovidTracking_StateCurrentTestPercentData> calculatePercentages()

Here's the document:

bad-function.txt

Need to check that generated class names are not common java.lang class names

Describe the bug

A user defined an enum called 'string', which caused the generator to generate
public static enum String { ... }

How to Reproduce

Create a document that has a property like:

        status:
          default: OK
          examples:
            - OK
          pattern: ^(.*)$
          type: string
          title: The Status Schema
          enum:
            - OK
            - STOP
            - FAIL
            - START
            - STOPPED
            - FLAT_TIRE
            - ENGINE_PROBLEM

Expected behavior

The generator should use the property name (status) not the type (string) when generating the enum class name.

Update Binder Config Location

It would be ideal if the template would put the binder connection information under spring.cloud.stream.binders instead of under solace.java or wherever Rabbit/Kafka go by default. By putting them under this new location it allows for the generated app to more easily be modified to use multiple binders.

With this change I would expect the generated config to look something like this:

spring:
  cloud:
    function:
      definition: uppercase
    stream:
      bindings:
        uppercase-in-0:
          destination: queuename
          group: myconsumergroup
          binder: solace-broker
        uppercase-out-0:
          destination: uppercase/topic
          binder: solace-broker
      binders:
        solace-broker:
          type: solace
          environment:
            solace:
              java:
                host: tcp://localhost:55555
                msgVpn: default
                clientUsername: default
                clientPassword: default
                connectRetries: -1
                reconnectRetries: -1

Improve Kafka support

Reason/Context

The support for kafka needs to be improved:

  1. It should ensure that topic names are valid. Slashes should be replaced with dots.
  2. Kafka-specific binding and connection properties should be passed in through parameters.

Description

This shall be implemented by detecting which binder is being used, and then generating the appropriate code. We currently do this when the Solace binder is selected - that triggers the generation of Solace connection properties. A similar thing can be done with Kafka.

Generator is failing to add 'import com.fasterxml.jackson.annotation.JsonProperty;' statement

Describe the bug

Snippet from the asynapi document:
....
lat:
default: 0
examples:
- -71.518929
description: An explanation about the purpose of this instance.
type: number
title: The lat schema
$id: '#/properties/lat'
long:
default: 0
examples:
- -71.518929
description: An explanation about the purpose of this instance.
type: number
title: The long schema
$id: '#/properties/long'
....

There is a variable by name 'long' !!

In the generated code - 'long' being a reserved word, it did the right thing of naming the variable as "_long" and added a JsonProperty to be "long", which is fine.

But, what the generator failed to do was to include the "import com.fasterxml.jackson.annotation.JsonProperty;" statement.

How to Reproduce

Just add a variable with name "long" in any valid AsyncAPI document and put it through code generation.

Expected behavior

"import com.fasterxml.jackson.annotation.JsonProperty;" should automatically be present in the generated POJO.

Wrong usage of operation meaning

I just realized about this on the README:

Note that this template interprets the AsyncAPI document from the perspective of an application, not an API. This means that when the template sees a subscribe operation, it generates code to subscribe to a topic, not publish to one.

Is there any reason for this? This is making the template not compliant with AsyncAPI. As far as I understood, this template is not about generating "consumer" code but the "provider" one (i.e., it says from "an application" perspective). In other words, if we were building a microservices architecture, this code would generate the code of one of these microservices. Am I understanding it right?

Generation fails when schemas have an $Id field.

Describe the bug

Generation fails when schemas have an $Id field.

How to Reproduce

Run the generator with the attached file, see the error messages.

Expected behavior

The file is valid and should work (I renamed it to .txt so it could be attached.)
asyncapi.txt

Supplier is created for application for an API definition with a consumer

I am creating a simple consumer application that has the following API definition.

asyncapi: 2.0.0
info:
  title: Some backend events
  version: 1.0.0
channels:
  some.transaction.000:
    description: |-
      This contains events related to transactions.
    subscribe:
      operationId: consumeTransactionEvent
      message:
        $ref: '#/components/messages/trasactionEvent'
components:
  messages:
    trasactionEvent:
      name: trasactionEvent
      schemaFormat: 'application/vnd.aai.asyncapi;version=2.0.0'
      contentType: 'application/json'
      payload:
        ref: '#/components/schemas/TransactionEventPayload'
  schemas:
    TransactionEventPayload:
      type: object
      properties:
        transactionId:
          description: Catalog id for the item
          type: string
          format: uuid

when using the java spring cloud stream template it creates a project with two problems.

  1. It creates a supplier rather than a consumer in the consumeTransactionEvent.
  2. It using AnonymousSchema1 when there is already a schema created and doesn't even use the schema.

Here is the code it creates:-

@SpringBootApplication
public class Application {

	private static final Logger logger = LoggerFactory.getLogger(Application.class);

	public static void main(String[] args) {
		SpringApplication.run(Application.class);
	}

	@Bean
	public Supplier<AnonymousSchema1> consumeTransactionEvent() {
		// Add business logic here.
		return null;
	}

}

@JsonInclude(JsonInclude.Include.NON_NULL)
public class TransactionEventPayload {

	public TransactionEventPayload () {
	}
	public TransactionEventPayload (
		String transactionId) {
		this.transactionId = transactionId;
	}


	private String transactionId;

	public String getTransactionId() {
		return transactionId;
	}

	public TransactionEventPayload setTransactionId(String transactionId) {
		this.transactionId = transactionId;
		return this;
	}


	public String toString() {
		return "TransactionEventPayload ["
		+ " transactionId: " + transactionId
		+ " ]";
	}
}

These are the only two classes it creates.

Expected behavior

I think for a subscriber, It should create a consumer and not a supplier.

Thanks a lot in advance for looking into this

The template does not handle multiple SMF bindings.

Describe the bug

Documents may contain multiple SMF bindings per operation, but this template does not handle that.

How to Reproduce

Run the example below, it causes an error.

Expected behaviour

The template should handle this kind of file.

Example:

components:
  schemas:
    Person:
      properties:
        name:
          type: string
  messages:
    PersonEvent:
      payload:
        $ref: '#/components/schemas/Person'
      schemaFormat: application/vnd.aai.asyncapi+json;version=2.0.0
      contentType: application/json
channels:
  'person/{eventType}/{eventVerb}':
    publish:
      bindings:
        smf:
          bindingVersion: 0.2.0
          bindings:
            - topicSubscriptions:
                - person/*/updated
              channelType: queue
              queueName: UpdatedHREvents
            - topicSubscriptions:
                - person/*/created
              channelType: queue
              queueName: CreatedHREvents
      message:
        $ref: '#/components/messages/PersonEvent'
    parameters:
      eventVerb:
        schema:
          type: string
      eventType:
        schema:
          type: string
asyncapi: 2.0.0
info:
  title: HRApp
  version: 0.0.1

Error: Unable to call `modelClass["getClassName"]`, which is undefined or falsey

Describe the bug

while generating a Spring Cloud Stream project with the follwing spec :

IntegrationTask.yaml.txt

using the following command line :

ag IntegrationTask.yaml @asyncapi/java-spring-cloud-stream-template -o IntegrationTaskProject #-p server=production

Note : this is in the https://www.asyncapi.com/tools/generator example, and it doesn't work with Spring Cloud Stream (didn't test the other generators)
#-p server=production

Full exception :

Template render error: (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/template/src/main/java/$$everySchema$$.java) [Line 2, Column 43]
  Error: Unable to call `modelClass["getClassName"]`, which is undefined or falsey
    at Object._prettifyError (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/lib.js:36:11)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:563:19
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:46:11)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:613:9
    at Template.root [as rootRenderFunc] (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:854:3)
    at Template.getExported (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:611:10)
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:45:5)
    at Environment.getTemplate (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:279:9)
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:43:5)
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:25:1)
    at fn (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:26:24)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:66:22
    at executeSync (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:8:15)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:65:11
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:20:1)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:571:11

Expected behavior

No exception, and a full project generated.

Error generating code

Describe the bug

I use the following asyncapi.yaml and got and incomprehensible error.

asyncapi: '2.0.0'
id: 'urn:com:kafka:server'
info:
  title: Kafka Application
  version: '1.0.0'
  description: Kafka Application
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
servers:
  production:
    url: localhost:9092
    description: Development server
    protocol: kafka
    protocolVersion: '1.0.0'
    x-trigger-version: v0.9.1-0.20190603184501-d845e1d612f8
    x-activity-version: v0.9.1-0.20190603184501-d845e1d612f8
channels:
  /message:
    description: A message channel
    subscribe:
      summary: Get messages
      message:
        $ref: '#/components/messages/message'
      traits:
        - bindings:
            flogo-kafka:
              partitions: "0"
              offset: 0
    publish:
      summary: Send messages
      message:
        $ref: '#/components/messages/message'
      traits:
        - bindings:
            flogo-kafka:
              partitions: "0"
              offset: 0
  /dup:
    description: A duplicate message channel
    subscribe:
      summary: Get messages
      message:
        $ref: '#/components/messages/message'
    publish:
      summary: Send messages
      message:
        $ref: '#/components/messages/message'
components:
  messages:
    message:
      name: message
      title: A message
      summary: A message
      contentType: application/json
      payload:
        $ref: "#/components/schemas/message"
  schemas:
    message:
      type: object

How to Reproduce

ag asyncapi.yaml @asyncapi/java-spring-cloud-stream-template --force-write

Expected behavior

Something went wrong:
Error: There was a problem registering the hooks: Cannot find module '../lib/ScsLib'
Require stack:
- /home/jarp/.nvm/versions/node/v14.2.0/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/hooks/post-process.js
- /home/jarp/.nvm/versions/node/v14.2.0/lib/node_modules/@asyncapi/generator/lib/generator.js
- /home/jarp/.nvm/versions/node/v14.2.0/lib/node_modules/@asyncapi/generator/cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1020:15)
    at Function.Module._load (internal/modules/cjs/loader.js:890:27)
    at Module.require (internal/modules/cjs/loader.js:1080:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/home/jarp/.nvm/versions/node/v14.2.0/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/hooks/post-process.js:5:16)
    at Module._compile (internal/modules/cjs/loader.js:1176:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1196:10)
    at Module.load (internal/modules/cjs/loader.js:1040:32)
    at Function.Module._load (internal/modules/cjs/loader.js:929:14)
    at Module.require (internal/modules/cjs/loader.js:1080:19)

Any suggestion? is this template available for use?

Regards

The generated send() function should be commented out.

Describe the bug

When we generate code that publishes to a topic with parameters, we generate two functions, the standard Supplier, and also a custom function that constructs the topic and sends it via the StreamBridge.

Early feedback from users was that having both functions was confusing, and they asked to comment out the custom function, leaving it as an example in case people wanted to use it.

Add supportedProtocols in package.json for java-spring-cloud

Reason/Context

Please try answering few of those questions

  • Why we need this improvement?.
    To maintain consistency across generators.

  • How will this change help?
    We can know what are the protocols supported on one sight.

  • What is the motivation?
    Some of the generators got the key (supportedProtocols) but not here.

https://github.com/asyncapi/java-spring-template/blob/master/package.json#L70
https://github.com/asyncapi/nodejs-ws-template/blob/master/package.json#L69

Description

Please try answering few of those questions

  • What changes have to be introduced?
    L1 change: We have to introduce supportedProtocols key in package.json for the first cut.
    L2 change: Next we may need to check the spec file and see only the listed protocols are there before generating.

  • Will this be a breaking change?

L1 change will be just for readbility.
L2 change will allow only the certain sets of spec files which the protocols are supported for.

  • How could it be implemented/designed?
    We have to start by adding supportedProtocols key and value in package.json under generator

Something went wrong: Template render error

Hi. I'm trying to generate code, but I don't understand the error in the template. Could you check if it's my problem or if there's a problem with the template?

Something went wrong: Template render error: (C:\Users\JAMILENADAZJ\eclipse-workspace\asyncapi\tmp\node_modules\@asyncapi\java-spring-cloud-stream-template\template\src\main\java\$$schema$$.java) [Line 53, Column 12] TypeError: Cannot read property 'items' of undefined at Object._prettifyError (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\lib.js:36:11) at C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:561:19 at eval (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:29:11) at C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:611:9 at Template.root [as rootRenderFunc] (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:740:3) at Template.getExported (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:609:10) at eval (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:28:5) at Environment.getTemplate (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:277:9) at eval (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:26:5) at eval (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:23:1) at fn (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\a-sync-waterfall\index.js:26:24) at C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\a-sync-waterfall\index.js:66:22 at executeSync (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\a-sync-waterfall\index.js:8:15) at C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\a-sync-waterfall\index.js:65:11 at eval (eval at _compile (C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:631:18), <anonymous>:18:1) at C:\Users\JAMILENADAZJ\AppData\Roaming\npm\node_modules\@asyncapi\generator\node_modules\nunjucks\src\environment.js:569:11

node --version ==> v12.16.1
Launch command ==> ag --force-write ..\AsyncAPI-2.0.0.yaml https://github.com/asyncapi/java-spring-cloud-stream-template.git

The asyncAPI I've defined is this
AsyncAPI-2.0.0.yaml.zip

Thanks.

Request for a AWS Kinesis Binder

Reason/Context

  • Why we need this improvement?
    It'd help to provider AWS Kinesis binder support with reference to spring-cloud-stream-binder-aws-kinesis
  • How will this change help?
    Helps in generating code templates for AWS Kinesis users like us.
  • What is the motivation?
    Reusable code template for AWS Kinesis users.

Description

  • What changes have to be introduced?
    A new binder implementation similar to Kafka.
  • Will this be a breaking change?
    No
  • How could it be implemented/designed?
    May be with reference to spring-cloud-stream-binder-aws-kinesis

Simplify Generated Spring Config when parameters are in channel name and using Solace Binder

The Solace Spring Cloud Stream binder introduced this enhancement in v2.0.0 to enhance destination wildcard handling in the binder. This allows us to simplify the generated config when using the Solace binder for a defined channel w/ parameters. Right now the generated app skeleton includes the destination and the queueAdditionalSubscriptions in this scenario but with the binder's enhancement only the destination will be necessary.

Remote schema references fails with Basic Auth url (getaddrinfo ENOTFOUND)

Describe the bug

Triying to reference payload pointed to remote uri (with basic Auth) is not well parsed.

How to Reproduce

Define a channel payload like this in the async-api-notifications.yml definition:
example: publish: message: schemaFormat: 'application/vnd.apache.avro;version=1.9.0' payload: $ref: 'https://UALKJIVWHIF3I36T:[email protected]/schemas/ids/1'
And run (docker execution)
docker run --rm -it -v ${PWD}:/app asyncapi/generator apiDefinitions/async-api-notifications.yml \ @asyncapi/java-spring-cloud-stream-template \ -o generated-sources \ -p binder=kafka \ -p artifactId=MyArtifact \ -p groupId=com.dani \ -p javaPackage=com.dani.myartifact \ -p useServers=true \ --force-write

failed with

Error: Error downloading https://ly422rbu2hn6jq5t/:+f8wz9a0iM06AX7xfwbzSM9YPw/JIkr22Cvl5EKT5Hb1d/nz5nOpbXV/[email protected]/subjects/test/versions/1/schema
getaddrinfo ENOTFOUND ly422rbu2hn6jq5t
at dereference (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/parser/lib/parser.js:159:11)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at parse (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/parser/lib/parser.js:87:5)
at Generator.generateFromString (/usr/local/lib/node_modules/@asyncapi/generator/lib/generator.js:265:22)

Expected behavior

The inline authorization is not well parsed, and is interpreted as host.

If an Avro schema has a namespace, that's not set in the Java model's package declaration.

Describe the bug

The last feature implemented was to improve Avro support. We do look at the Avro schema's namespace and put the file into the right directory. However we forgot to change the Java package declaration in that file.

How to Reproduce

Run a file containing something like this:

      message:
        schemaFormat: 'application/vnd.apache.avro;version=1.9.0'
        payload:
          name: User
          namespace: com.example.publisher
          type: record
          doc: User information
          fields:
            - name: displayName
              type: string
            - name: email
              type: string

It is expected that the User class file ends up in the 'com.example.publisher' package and has the line

package com.example.publisher;

but the package name isn't changed from the one set by the javaPackage parameter.

Expected behavior

The declared package should match the Avro namespace.

Classes not generated for 2nd level nested complex elements in Json schema

Classes are not generated in the generated code for the 2nd level onwards complex nested elements.

How to Reproduce

  1. Code generator used to generate code for the attached yaml file which has nested complex elements in the json schema.
  2. Code generated successfully with project structure but no object classes generated for the child/grandchild elements in the schema.
  3. Attached screenshot and yaml file to replicate the issue.

image002

Channel_API_Gateway_v1.yaml.zip

Expected behavior

All object classes should be generated for the json schema in the yaml file.

Improve handling of properties without types

Describe the bug

When a property is defined without a type, and it is not an enum, then the template assumes it is a $ref to a different schema and assumes that the title attribute is the class name of the related schema. If there is no $ref then we should raise an exception.

Guard against invalid Java class names.

Describe the bug

When a schema name contains special characters, invalid Java class names are generated.

How to Reproduce

Create or modify an AsyncAPI document such that a schema name contains a period or some other special character. Run the generator. Observe that the class name isn't valid.

Expected behavior

The template should guard against that by stripping out invalid characters.

Template render error: topicInfo filter: type not found in typeMap: [object Object]

Describe the bug

Generator gives an error

/app # vi /usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-strea
m-template/filters/all.js 
 /app # ag -o /app/output2 /app/streetlights.yaml @asyncapi/java-spring-cloud-stream-template --force-write -p javaPackage=com.example.foo -p groupId=com.example -p artifactId=ExampleArtifactId
 Something went wrong:
 Template render error: (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/template/src/main/java/Messaging.java)
   Template render error: (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/partials/java-package)
  Error: topicInfo filter: type not found in typeMap: [object Object]
    at Object._prettifyError (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/lib.js:36:11)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:561:19
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:631:18), <anonymous>:19:11)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:569:11
    at Template.root [as rootRenderFunc] (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:631:18), <anonymous>:31:3)
    at Template.render (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:550:10)
    at eval (eval at _compile (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/nunjucks/src/environment.js:631:18), <anonymous>:18:10)
    at fn (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:26:24)
    at /usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:66:22
    at executeSync (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/a-sync-waterfall/index.js:8:15)

How to Reproduce

Downloaded the streetlights.yaml example contract from: https://raw.githubusercontent.com/asyncapi/asyncapi/master/examples/2.0.0/streetlights.yml

Using the Docker CLI command to generate the java code

docker run --rm -it \
-v ${PWD}/streetlights.yml:/app/asyncapi.yml \
-v ${PWD}/output:/app/output \
asyncapi/generator -o /app/output /app/asyncapi.yml @asyncapi/java-spring-cloud-stream-template --force-write

Expected behavior

The way to correct the behaviour was to change the file filters/all.js (haven't reviewed it in detail)
from:
const javaType = typeMap.get(type);

to this one:
const javaType = type.javaType || typeMap.get(type);

Kafka broker information is not populated in the properties file

Describe the bug

Kakfa broker information is not created in the properties file that gets generated.

I have added broker information inside the servers section, but this information does not get populated in the properties file.
I tried using the java-spring-template, and it was able to populate the broker information.

here is the api defintion;

asyncapi: 2.0.0
info:
  title: Banking backend events
  version: 1.0.0
servers:
  development:
    url: localhost:9092
    protocol: kafka
channels:
  banking.transaction.000:
    description: |-
      This contains events related to transactions.
    publish:
      operationId: consumeTransactionEvent
      message:
        $ref: '#/components/messages/transactionEvent'
      bindings:
        kafka:
          groupId:
            type: string
            enum: [ 'myGroupId' ]
          clientId:
            type: string
            enum: [ 'myClientId' ]
          bindingVersion: '0.1.0'

components:
  messages:
    transactionEvent:
      name: trasactionEvent
      contentType: 'application/json'
      payload:
        $ref: '#/components/schemas/TransactionEventPayload'
  schemas:
    TransactionEventPayload:
      type: object
      properties:
        transactionId:
          description: Transaction Id
          type: string
          format: uuid
        amount:
          type: integer

Here the resulting properties file generated from this definition.


spring:
  cloud:
    function:
      definition: consumeTransactionEvent
    stream:
      bindings:
        consumeTransactionEvent-in-0:
          destination: banking.transaction.000
logging:
  level:
    root: info
    org:
      springframework: info

Generate a comment when a channel has multiple messages.

Reason/Context

The Async API code generation for spring cloud streams generates a Consumer function for consumers. When a consumer can consume more than one message type, the developer doesn't know what the types are because the method signature accepts Message<?>. The codegen should add a comment saying what the valid method types for the generic are.

For example:

// The message can be of type:
// User
// Account

Description

Please try answering few of those questions

What changes have to be introduced?
We will need to determine when a channel has multiple messages, and then generate a comment that lists those messages.
Will this be a breaking change?
no.

Generated project does not compile

Hi! First of all thanks for working on developing a tooling around AsyncAPI πŸ˜ƒ

I'm facing 2 bugs with the generator.

Describe the bug

When using the example reference AsyncAPI definition (https://bit.ly/asyncapi) which is using camelCase for schemas, the generated project is not Java compliant and hence does not build.

I observe 2 problems:

First one: Casing mismatch (breaks build)

The generated model classes (the schemas) are in a file named in camelCase.java whilst the class definition itself is in PascalCase.
The above example results in:

  • File name: dimLightPayload.java
  • Class definition: public class DimLightPayload

So the file name should be always switched to PascalCase as its being done with the class name itself (following Java conventions).

One should argue that the definition of the official sample API could be updated to turn schema names into PascalCase to help align conventions. In my personal guideline I always define schemas in PascalCase and parameters in camelCase, which semantically maps to classes (or data models) and arguments of a function respectively (I guess in Java and probably many other languages). What do you think @fmvilas ?

But giving the above thought aside, the Java/Spring-Cloud-Stream generator should handle the casing properly 😁

Second one: Duplicate constructor (breaks build)

The generated model class SentAt, which is defined in API definition as a date-time:

    sentAt:
      type: string
      format: date-time
      description: Date and time when the message was sent.

contains 2 empty constructors, which prevents the code to compile:

	public SentAt () {
	}
	public SentAt () {
	}

Another thing here is that OpenAPI generator for Java, would use a java.time.LocalDateTime for this type (instead of generating a model) as defined date-time which bould be much more convenient. I know this is an improvement of the current generator template and could be a feature-request instead πŸ˜‰

How to Reproduce

npm install -g @asyncapi/generator
ag https://bit.ly/asyncapi @asyncapi/java-spring-cloud-stream-template
mvn clean verify

Expected behavior

Let the code to compile (and hopefully use a LocalDate/LocalDateTime for string/date/string/date-time in YAML πŸ˜„ )

Generation of array types is not possible anymore

The code generator is failing everytime it has to generate an array type with the error shown below.
This change was probably introduced with the release 0.11.3, until release version 0.11.2 it worked fine.

grafik

avro schema don't work with java-spring-cloud-stream-template

Hi,

I can't generate code with java-spring-cloud-template and avro schema. I got the following error

Something went wrong:
TypeError: Cannot read property 'schemas' of null
at generate:after (C:\Users\usuario\AppData\Roaming\npm\node_modules@asyncapi\generator\node_modules@asyncapi\java-spring-cloud-stream-template\hooks\post-process.js:76:42)
at C:\Users\usuario\AppData\Roaming\npm\node_modules@asyncapi\generator\lib\generator.js:729:20
at Array.map ()
at Generator.launchHook (C:\Users\usuario\AppData\Roaming\npm\node_modules@asyncapi\generator\lib\generator.js:727:43)
at Generator.generate (C:\Users\usuario\AppData\Roaming\npm\node_modules@asyncapi\generator\lib\generator.js:188:16)
at async C:\Users\usuario\AppData\Roaming\npm\node_modules@asyncapi\generator\cli.js:149:9

My asyncapi specification contains this:

asyncapi: '2.0.0'
info:
title: Streetlights API
version: '1.0.0'
description: |
The Smartylighting Streetlights API allows you
to remotely manage the city lights.
license:
name: Apache 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0'

servers:
production:
url: kafka.bootstrap:{port}
protocol: kafka
variables:
port:
default: '9092'
enum:
- '9092'
- '9093'

channels:
event.lighting.measured:
publish:
bindings:
kafka:
groupId: my-group
operationId: readLightMeasurement
message:
schemaFormat: 'application/vnd.apache.avro;version=1.9.0'
payload: # The following is an Avro schema in YAML format (JSON format is also supported)
type: record
doc: User information
fields:
- name: displayName
type: string
- name: email
type: string
- name: age
type: int
subscribe:
operationId: updateLightMeasurement
message:
schemaFormat: 'application/vnd.apache.avro;version=1.9.0'
payload: # The following is an Avro schema in YAML format (JSON format is also supported)
type: record
doc: User information
fields:
- name: displayName
type: string
- name: email
type: string
- name: age
type: int

I have used 1.0.0-rc.7 generator version

Note : I thought that my asyncapi specifications is wrong but when I made the test with the same asyncapi specification and java-spring-template I don't get errors

Error: filter not found: upperFirst

OS: Windows 10
Generator: 0.53.1 (Docker run)

Command to reproduce:
docker run --rm -it -v ${PWD}/test/docs/streetlights.yml:/app/asyncapi.yml -v ${PWD}/output:/app/output asyncapi/generator -o ./output asyncapi.yml @asyncapi/java-spring-cloud-stream-template --force-write

Result:
Something went wrong:
Template render error: (/app/node_modules/@asyncapi/java-spring-cloud-stream-template/template/src/main/java/$$schema$$.java)
Error: filter not found: upperFirst
at Object._prettifyError (/app/node_modules/nunjucks/src/lib.js:36:11)
at /app/node_modules/nunjucks/src/environment.js:561:19
at eval (eval at _compile (/app/node_modules/nunjucks/src/environment.js:631:18), :44:11)
at /app/node_modules/nunjucks/src/environment.js:611:9
at Template.root [as rootRenderFunc] (eval at _compile (/app/node_modules/nunjucks/src/environment.js:631:18), :830:3)
at Template.getExported (/app/node_modules/nunjucks/src/environment.js:609:10)
at eval (eval at _compile (/app/node_modules/nunjucks/src/environment.js:631:18), :43:5)
at createTemplate (/app/node_modules/nunjucks/src/environment.js:313:9)
at handle (/app/node_modules/nunjucks/src/environment.js:325:11)
at /app/node_modules/nunjucks/src/environment.js:337:9
at next (/app/node_modules/nunjucks/src/lib.js:280:7)
at Object.asyncIter (/app/node_modules/nunjucks/src/lib.js:286:3)
at Environment.getTemplate (/app/node_modules/nunjucks/src/environment.js:319:9)
at eval (eval at _compile (/app/node_modules/nunjucks/src/environment.js:631:18), :41:5)
at eval (eval at _compile (/app/node_modules/nunjucks/src/environment.js:631:18), :23:1)
at fn (/app/node_modules/a-sync-waterfall/index.js:26:24)

Improve the way dynamic topics are rendered

Reason/Context

This is in response to this comment: #129 (comment)

The ask is that we add a new parameter to guide the code generation of methods that publish to dynamic topics, using either the StreamBridge or a destination header on the message. Please see the linked comment for details.

  • Why we need this improvement?
    It would improve the quality of the generated code.

Description

Please try answering few of those questions

  • What changes have to be introduced?
    A new parameter will be added which will change the way dynamic topics are handled.

  • Will this be a breaking change?
    no.

Date-time format is not supported


name: Bug Date-time format is not supported
labels: bug

Describe the bug

Date-time format is not supported

How to Reproduce

Generating code with date-time format at some of theirs fields

  • asyncapi file example
info:
  title: Streetlights API
  version: '1.0.0'
  description: |
    The Smartylighting Streetlights API allows you
    to remotely manage the city lights.
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0'

servers:
  production:
    url: kafka.bootstrap:{port}
    protocol: kafka
    variables:
      port:
        default: '9092'
        enum:
          - '9092'
          - '9093'

channels:
  event.lighting.measured:
    publish:
      bindings:
        kafka:
          groupId: my-group
      operationId: readLightMeasurement
      message:
        $ref: '#/components/messages/lightMeasured'
    subscribe:
      operationId: updateLightMeasurement
      message:
        $ref: '#/components/messages/lightMeasured'
components:
  messages:
    lightMeasured:
      summary: Inform about environmental lighting conditions for a particular streetlight.
      payload:
        $ref: "#/components/schemas/lightMeasuredPayload"
  schemas:
    lightMeasuredPayload:
      type: object
      properties:
        lumens:
          type: integer
          minimum: 0
          description: Light intensity measured in lumens.
        sentAt:
          $ref: "#/components/schemas/sentAt"
      sentAt:
      type: string
      format: date-time
      description: Date and time when the message was sent.

Expected behavior

I expected this:

public class LightMeasuredPayload {
    
    private @Valid int lumens;
    
    private @Valid java.time.LocalDateTime sentAt;

but I got this

@JsonInclude(JsonInclude.Include.NON_NULL)
public class LightMeasuredPayload {

	public LightMeasuredPayload () {
	}
	public LightMeasuredPayload (
		Integer lumens, 
		String sentAt) {
		this.lumens = lumens;
		this.sentAt = sentAt;
	}


	private Integer lumens;
	private String sentAt;

SentAt field must be java.time.LocalDateTime type

Template render error: invalid type of array property into rendered java class

Describe the bug

In the components.schemas section, for properties that have the array type specified in the generated java class, the type [object Map][] is set instead of java.util.List<> or Java Array

How to Reproduce

source asyncapi-example.yaml:

asyncapi: 2.0.0
info:
  title: Example
  version: 1.0.0
channels:
  test/example:
    subscribe:
      message:
        payload:
          $ref: '#/components/schemas/PayloadExample'
components:
  schemas:
    PayloadExample:
      type: object
      properties:
        p1:
          type: string
        p2:
          type: string
        p3:
          type: array
          items:
            type: string

result java-class:

package some.package;

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class PayloadExample {

	public PayloadExample () {
	}
	public PayloadExample (
		String p1, 
		String p2, 
		[object Map][] p3) {
		this.p1 = p1;
		this.p2 = p2;
		this.p3 = p3;
	}
	private String p1;
	private String p2;
	private [object Map][] p3; // <-- o_O
       
        // .....
}

package.json with build-script

{
  "name": "rnd-asyncapi",
  "version": "1.0.0",
  "scripts": {
    "build": "ag -p artifactType=library -p javaPackage=some.package -o ./build/generate/aas/java ./asyncapi-example.yaml @asyncapi/java-spring-cloud-stream-template"
  },
  "dependencies": {
    "@asyncapi/generator": "~1.6.0",
    "@asyncapi/java-spring-cloud-stream-template": "~0.6.6",
  }
}

Expected behavior

instead of [object Map][] must be of type List<String> or String[]

Generation of java code for 'allOff' modifier doesn't generates descendant class

Describe the bug

Generation of java code for 'allOff' modifier doesn't generates descendant class as for Inheritance so Composition

How to Reproduce

Using configuration in schemas like this produces only ErrorModel class

    ErrorModel:
      type: object
      required:
      - message
      - code
      properties:
        message:
          type: string
        code:
          type: integer
          minimum: 100
          maximum: 600
    ExtendedErrorModel:
      allOf:
      - $ref: '#/components/schemas/ErrorModel'
      - type: object
        required:
        - rootCause
        properties:
          rootCause:
            type: string

Expected behavior

Must be generated ErrorModel.java and ExtendedErrorModel.java

Move Versions to Config Files

As discussed in #54 it would be ideal to move hard coded version information to config files instead of in the code.
This would be for things like Spring Boot, Spring Cloud & Cloud Stream Binder versions.

import java.math.BigDecimal instead of using the fully qualified name.

Reason/Context

Please try answering few of those questions

  • Why we need this improvement?
    When a schema uses 'number' we use the java.math.BigDecimal class. But instead of importing it, we use the fully qualified name everywhere it's used.
  • How will this change help?
    This will improve readability.
  • What is the motivation?
    We strive to make the code appear as if it were human-written. This looks awkward.

Description

Please try answering few of those questions

  • What changes have to be introduced?
    Will have to detect when we use BigDecimal and adjust the appExtraIncludes function to include it.
  • Will this be a breaking change?
    no.
  • How could it be implemented/designed?
    See above.

The template fails when an operation can publish or subscribe multiple types of messages

Describe the bug

When you have a pub or sub that uses oneOf like so:

    publish:
      message:
        oneOf:
          - $ref: '#/components/messages/NewOrder'
          - $ref: '#/components/messages/UpdateOrder'

the template fails with the message

Template render error: (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/java-spring-cloud-stream-template/template/src/main/resources/config/application.yml)
  TypeError: Cannot read property 'startsWith' of undefined

How to Reproduce

Include multiple messages in a pub or sub operation as shown above.

Expected behaviour

This error happens when the template tries to determine the payload class of an operation. My proposed solution is to return 'Message<?>'. That will allow the client to examine headers to determine which message type to use.

Generated Code should return a function

It looks like Spring has updated some of their type checking when running a cloud stream app and if you run the app as generated with no business logic you now get an error saying somethign along the lines of Class 'class org.springframework.beans.factory.support.NullBean' is not a FunctionalInterface

It would be nice if generated code would return a lambda to avoid this.

So instead of a generated bean being something like this which returns null:

	@Bean
	public Consumer<StddsPayloadSchema> EvaLaxGroundCrew() {
		// Add business logic here.
		return null;
	}

Change it to this which returns a lambda:

	@Bean
	public Consumer<StddsPayloadSchema> EvaLaxGroundCrew() {
		return v -> {
			// Add business logic here.
			logger.info(v.toString());
		};
	}

Note this would require it being a bit different for Consumer, Supplier and Function.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.