Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable v3 and scala for model generation #1155

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions src/commands/generate/models.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { CSharpFileGenerator, JavaFileGenerator, JavaScriptFileGenerator, TypeScriptFileGenerator, GoFileGenerator, Logger, DartFileGenerator, PythonFileGenerator, RustFileGenerator, TS_COMMON_PRESET, TS_JSONBINPACK_PRESET, CSHARP_DEFAULT_PRESET, CSHARP_NEWTONSOFT_SERIALIZER_PRESET, CSHARP_COMMON_PRESET, CSHARP_JSON_SERIALIZER_PRESET, KotlinFileGenerator, TS_DESCRIPTION_PRESET, PhpFileGenerator, CplusplusFileGenerator, JAVA_CONSTRAINTS_PRESET, JAVA_JACKSON_PRESET, JAVA_COMMON_PRESET, JAVA_DESCRIPTION_PRESET } from '@asyncapi/modelina';
import { CSharpFileGenerator, JavaFileGenerator, JavaScriptFileGenerator, TypeScriptFileGenerator, GoFileGenerator, Logger, DartFileGenerator, PythonFileGenerator, RustFileGenerator, TS_COMMON_PRESET, TS_JSONBINPACK_PRESET, CSHARP_NEWTONSOFT_SERIALIZER_PRESET, CSHARP_COMMON_PRESET, CSHARP_JSON_SERIALIZER_PRESET, KotlinFileGenerator, TS_DESCRIPTION_PRESET, PhpFileGenerator, CplusplusFileGenerator, JAVA_CONSTRAINTS_PRESET, JAVA_JACKSON_PRESET, JAVA_COMMON_PRESET, JAVA_DESCRIPTION_PRESET, ScalaFileGenerator } from '@asyncapi/modelina';
import { Flags } from '@oclif/core';
import { ConvertDocumentParserAPIVersion } from '@smoya/multi-parser';
import Command from '../../base';
import { load } from '../../models/SpecificationFile';
import { formatOutput, parse, validationFlags } from '../../parser';
Expand All @@ -18,7 +17,8 @@ enum Languages {
rust = 'rust',
kotlin='kotlin',
php='php',
cplusplus='cplusplus'
cplusplus='cplusplus',
scala='scala'
}
const possibleLanguageValues = Object.values(Languages).join(', ');

Expand Down Expand Up @@ -171,20 +171,12 @@ export default class Models extends Command {
const { tsModelType, tsEnumType, tsIncludeComments, tsModuleSystem, tsExportType, tsJsonBinPack, tsMarshalling, tsExampleInstance, namespace, csharpAutoImplement, csharpArrayType, csharpNewtonsoft, csharpHashcode, csharpEqual, csharpSystemJson, packageName, javaIncludeComments, javaJackson, javaConstraints, output } = flags;
const { language, file } = args;
const inputFile = (await load(file)) || (await load());
if (inputFile.isAsyncAPI3()) {
this.error('Generate Models command does not support AsyncAPI v3 yet, please checkout https://github.com/asyncapi/modelina/issues/1376');
}
const { document, diagnostics ,status } = await parse(this, inputFile, flags);
if (!document || status === 'invalid') {
const severityErrors = diagnostics.filter((obj) => obj.severity === 0);
this.log(`Input is not a correct AsyncAPI document so it cannot be processed.${formatOutput(severityErrors,'stylish','error')}`);
return;
}

// Modelina, atm, is not using @asyncapi/[email protected] but @asyncapi/[email protected], so it still uses Parser-API v1.0.0.
// This call converts the parsed document object using @asyncapi/[email protected] (Parser-API v2) to a document compatible with the Parser-API version in use in @asyncapi/[email protected] (v1)
// This is needed until https://github.com/asyncapi/modelina/issues/1493 gets fixed.
const convertedDoc = ConvertDocumentParserAPIVersion(document.json(), 1);

Logger.setLogger({
info: (message) => {
Expand Down Expand Up @@ -242,15 +234,6 @@ export default class Models extends Command {
if (namespace === undefined) {
throw new Error('In order to generate models to C#, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.');
}

if (csharpAutoImplement) {
presets.push({
preset: CSHARP_DEFAULT_PRESET,
options: {
autoImplementedProperties: true
}
});
}
if (csharpNewtonsoft) {
presets.push(CSHARP_NEWTONSOFT_SERIALIZER_PRESET);
}
Expand All @@ -269,7 +252,8 @@ export default class Models extends Command {

fileGenerator = new CSharpFileGenerator({
presets,
collectionType: csharpArrayType as 'Array' | 'List'
collectionType: csharpArrayType as 'Array' | 'List',
autoImplementedProperties: csharpAutoImplement
});

fileOptions = {
Expand All @@ -284,6 +268,15 @@ export default class Models extends Command {
namespace
});
break;
case Languages.scala:
if (packageName === undefined) {
throw new Error('In order to generate models to Scala, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.');
}
fileGenerator = new ScalaFileGenerator();
fileOptions = {
packageName
};
break;
case Languages.golang:
if (packageName === undefined) {
throw new Error('In order to generate models to Go, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.');
Expand Down Expand Up @@ -345,7 +338,7 @@ export default class Models extends Command {

if (output) {
const models = await fileGenerator.generateToFiles(
convertedDoc as any,
document,
output,
{ ...fileOptions, });
const generatedModels = models.map((model) => { return model.modelName; });
Expand All @@ -354,7 +347,7 @@ export default class Models extends Command {
}

const models = await fileGenerator.generateCompleteModels(
convertedDoc as any,
document,
{ ...fileOptions });
const generatedModels = models.map((model) => {
return `
Expand Down
206 changes: 206 additions & 0 deletions test/fixtures/asyncapi_v3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
asyncapi: 3.0.0
info:
title: Streetlights Kafka API
version: 1.0.0
description: |-
The Smartylighting Streetlights API allows you to remotely manage the city
lights.
### Check out its awesome features:

* Turn a specific streetlight on/off 🌃
* Dim a specific streetlight 😎
* Receive real-time information about environmental lighting conditions 📈
license:
name: Apache 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0'
defaultContentType: application/json
servers:
scram-connections:
host: 'test.mykafkacluster.org:18092'
protocol: kafka-secure
description: Test broker secured with scramSha256
security:
- $ref: '#/components/securitySchemes/saslScram'
tags:
- name: 'env:test-scram'
description: >-
This environment is meant for running internal tests through
scramSha256
- name: 'kind:remote'
description: This server is a remote server. Not exposed by the application
- name: 'visibility:private'
description: This resource is private and only available to certain users
mtls-connections:
host: 'test.mykafkacluster.org:28092'
protocol: kafka-secure
description: Test broker secured with X509
security:
- $ref: '#/components/securitySchemes/certs'
tags:
- name: 'env:test-mtls'
description: This environment is meant for running internal tests through mtls
- name: 'kind:remote'
description: This server is a remote server. Not exposed by the application
- name: 'visibility:private'
description: This resource is private and only available to certain users
channels:
lightingMeasured:
address: 'smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured'
messages:
lightMeasured:
$ref: '#/components/messages/lightMeasured'
description: The topic on which measured values may be produced and consumed.
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightTurnOn:
address: 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.on'
messages:
turnOn:
$ref: '#/components/messages/turnOnOff'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightTurnOff:
address: 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.off'
messages:
turnOff:
$ref: '#/components/messages/turnOnOff'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightsDim:
address: 'smartylighting.streetlights.1.0.action.{streetlightId}.dim'
messages:
dimLight:
$ref: '#/components/messages/dimLight'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
operations:
receiveLightMeasurement:
action: receive
channel:
$ref: '#/channels/lightingMeasured'
summary: >-
Inform about environmental lighting conditions of a particular
streetlight.
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightingMeasured/messages/lightMeasured'
turnOn:
action: send
channel:
$ref: '#/channels/lightTurnOn'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightTurnOn/messages/turnOn'
turnOff:
action: send
channel:
$ref: '#/channels/lightTurnOff'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightTurnOff/messages/turnOff'
dimLight:
action: send
channel:
$ref: '#/channels/lightsDim'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightsDim/messages/dimLight'
components:
messages:
lightMeasured:
name: lightMeasured
title: Light measured
summary: >-
Inform about environmental lighting conditions of a particular
streetlight.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/lightMeasuredPayload'
turnOnOff:
name: turnOnOff
title: Turn on/off
summary: Command a particular streetlight to turn the lights on or off.
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/turnOnOffPayload'
dimLight:
name: dimLight
title: Dim light
summary: Command a particular streetlight to dim the lights.
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/dimLightPayload'
schemas:
lightMeasuredPayload:
type: object
properties:
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
sentAt:
$ref: '#/components/schemas/sentAt'
turnOnOffPayload:
type: object
properties:
command:
type: string
enum:
- 'on'
- 'off'
description: Whether to turn on or off the light.
sentAt:
$ref: '#/components/schemas/sentAt'
dimLightPayload:
type: object
properties:
percentage:
type: integer
description: Percentage to which the light should be dimmed to.
minimum: 0
maximum: 100
sentAt:
$ref: '#/components/schemas/sentAt'
sentAt:
type: string
format: date-time
description: Date and time when the message was sent.
securitySchemes:
saslScram:
type: scramSha256
description: Provide your username and password for SASL/SCRAM authentication
certs:
type: X509
description: Download the certificate files from service provider
parameters:
streetlightId:
description: The ID of the streetlight.
messageTraits:
commonHeaders:
headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
operationTraits:
kafka:
bindings:
kafka:
clientId:
type: string
enum:
- my-app-id
Loading
Loading