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

Update to AsyncApi 3.0 #507

Merged
merged 14 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class MonetaryAmount {

@JsonProperty("amount")
@Schema(example = "99.99")
@Schema(example = "99.99", minimum = "0.1")
timonback marked this conversation as resolved.
Show resolved Hide resolved
private BigDecimal amount;

@JsonProperty("currency")
Expand Down
4 changes: 3 additions & 1 deletion springwolf-add-ons/springwolf-generic-binding/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ plugins {

dependencies {
api project(":springwolf-core")
api project(":springwolf-asyncapi")

implementation "com.asyncapi:asyncapi-core:${asyncapiCoreVersion}"
implementation "org.slf4j:slf4j-api:${slf4jApiVersion}"

implementation "org.springframework:spring-context"
implementation "org.springframework:spring-core"

annotationProcessor "org.projectlombok:lombok:${lombokVersion}"

compileOnly "org.projectlombok:lombok:${lombokVersion}"

testImplementation "org.assertj:assertj-core:${assertjCoreVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter:${junitJupiterVersion}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.addons.generic_binding.annotation.processor;

import com.asyncapi.v2.binding.operation.OperationBinding;
import io.github.stavshamir.springwolf.addons.generic_binding.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.ProcessedOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.processor.AbstractOperationBindingProcessor;
import io.github.stavshamir.springwolf.asyncapi.v3.bindings.OperationBinding;

import java.util.HashMap;
import java.util.Map;
Expand Down
1 change: 1 addition & 0 deletions springwolf-add-ons/springwolf-json-schema/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation "org.springframework:spring-context"

annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
compileOnly "org.projectlombok:lombok:${lombokVersion}"

testImplementation "org.mockito:mockito-core:${mockitoCoreVersion}"
testImplementation "org.assertj:assertj-core:${assertjCoreVersion}"
Expand Down
1 change: 1 addition & 0 deletions springwolf-asyncapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {

See https://github.com/asyncapi/converter-js#conversion-2xx-to-3xx


# Contributions

Any contributions are welcome, including, but not limited to:
Expand Down
2 changes: 1 addition & 1 deletion springwolf-asyncapi/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ publishing {
mavenJava(MavenPublication) {
pom {
name = 'springwolf-asyncapi'
description = 'AsyncAPI schema generator'
description = 'Springwolf implementation of the AsyncApi specification'
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SQSChannelBindingQueue {
* identifier should be the one in this field.
*/
@NotNull
@JsonProperty("queue")
@JsonProperty("name")
private String name;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* SQS Point-To-Point
* </p>
Expand All @@ -32,7 +34,7 @@ public class SQSOperationBinding extends OperationBinding {
*/
@NotNull
@JsonProperty("queues")
private SQSChannelBindingQueue queues;
private List<SQSChannelBindingQueue> queues;

/**
* Optional, defaults to latest. The version of this binding.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.v3.model.channel;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.github.stavshamir.springwolf.asyncapi.v3.bindings.ChannelBinding;
import io.github.stavshamir.springwolf.asyncapi.v3.model.ExtendableObject;
Expand Down Expand Up @@ -29,14 +28,6 @@
@EqualsAndHashCode(callSuper = true)
public class ChannelObject extends ExtendableObject implements Channel {

/**
* An identifier for the described channel. The channelId value is case-sensitive. Tools and libraries MAY use the
* channelId to uniquely identify a channel, therefore, it is RECOMMENDED to follow common programming naming
* conventions.
*/
@JsonIgnore
private String channelId;

/**
* An optional string representation of this channel's address. The address is typically the "topic name",
* "routing key", "event type", or "path". When null or absent, it MUST be interpreted as unknown. This is useful
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,4 @@ public String getRef() {
public static ChannelReference fromChannel(String channelName) {
return new ChannelReference("#/channels/" + channelName);
}

/**
* Convenient Builder to create a Channel reference to an existing Channel
* @param channel Channel to create the reference to. This Channel MUST have a 'channelId' field
* @return a Channel with the 'ref' field pointing to "#/channels/{channelId"
*/
public static ChannelReference fromChannel(ChannelObject channel) {
var channelId = channel.getChannelId();
if (channelId == null) {
throw new IllegalArgumentException("The channel must have a 'channelId' defined");
}
return new ChannelReference("#/channels/" + channelId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import io.github.stavshamir.springwolf.asyncapi.v3.jackson.model.channel.message.MessageHeadersSerializer;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.MultiFormatSchema;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.SchemaObject;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@Getter
@JsonSerialize(using = MessageHeadersSerializer.class)
@EqualsAndHashCode
public class MessageHeaders {
private MultiFormatSchema multiFormatSchema;
private SchemaObject schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,14 @@ public class MessageObject extends ExtendableObject implements Message {
*/
@JsonProperty(value = "traits")
private List<MessageTrait> traits;

/*
* Override the getMessageId to guarantee that there's always a value. Defaults to 'name'
*/
public String getMessageId() {
timonback marked this conversation as resolved.
Show resolved Hide resolved
if (messageId == null) {
return this.name;
}
return messageId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import io.github.stavshamir.springwolf.asyncapi.v3.jackson.model.channel.message.MessagePayloadSerializer;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.MultiFormatSchema;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.SchemaObject;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@Getter
@JsonSerialize(using = MessagePayloadSerializer.class)
@EqualsAndHashCode
public class MessagePayload {
private MultiFormatSchema multiFormatSchema;
private SchemaObject schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,27 @@ public String getRef() {

/**
* Convenient Builder to create a Message reference to an existing Message
* @param message Message to create the reference to. This Message MUST have a 'messageId' field
* @return a Message with the 'ref' field pointing to "#/components/messages/{messageId"
*
* @param message Message to create the reference to. This Message MUST have a 'messageName' field
* @return a Message with the 'ref' field pointing to "#/components/messages/{messageName}"
*/
public static MessageReference fromMessage(MessageObject message) {
var messageId = message.getMessageId();
if (messageId == null) {
throw new IllegalArgumentException("The message must have a 'messageId' defined");
}
return new MessageReference("#/components/messages/" + messageId);
public static MessageReference toComponentMessage(MessageObject message) {
return toComponentMessage(message.getName());
}

public static MessageReference fromMessage(String messageName) {
public static MessageReference toComponentMessage(String messageName) {
return new MessageReference("#/components/messages/" + messageName);
}

public static MessageReference fromSchema(String schemaName) {
public static MessageReference toChannelMessage(String channelName, MessageObject message) {
return new MessageReference("#/channels/" + channelName + "/messages/" + message.getName());
}

public static MessageReference toChannelMessage(String channelName, String messageName) {
return new MessageReference("#/channels/" + channelName + "/messages/" + messageName);
}

public static MessageReference toSchema(String schemaName) {
return new MessageReference("#/components/schemas/" + schemaName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class SchemaObject extends ExtendableObject implements Schema {
private String type;

@JsonProperty(value = "properties")
private Map<String, Schema> properties;
private Map<String, Object> properties;

/**
* <a href="https://spec.commonmark.org/">CommonMark syntax</a> can be used for rich text representation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.v3.model.schema;

public class SchemaType {
public static final String NULL = "null";
public static final String BOOLEAN = "boolean";
public static final String OBJECT = "object";
public static final String ARRAY = "array";
public static final String NUMBER = "number";
public static final String STRING = "string";
public static final String INTEGER = "integer";

private SchemaType() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AMQPBindingTest {
private static final DefaultAsyncApiSerializer serializer = new DefaultAsyncApiSerializer();

@Test
void shouldSerializeAMQPChannelBinding() throws IOException {
void shouldSerializeAMQPChannelBindingQueue() throws IOException {

var asyncapi = AsyncAPI.builder()
.channels(Map.of(
Expand All @@ -30,13 +30,36 @@ void shouldSerializeAMQPChannelBinding() throws IOException {
.bindings(Map.of(
"amqp",
AMQPChannelBinding.builder()
.is(AMQPChannelType.ROUTING_KEY)
.is(AMQPChannelType.QUEUE)
.queue(AMQPChannelQueueProperties.builder()
.name("my-queue-name")
.durable(true)
.exclusive(true)
.autoDelete(false)
.build())
.build()))
.build()))
.build();

// Uses https://github.com/asyncapi/bindings/blob/master/amqp/README.md#example
var example = ClasspathUtil.parseYamlFile("/v3/bindings/amqp/amqp-channel-queue.yaml");
assertThatJson(serializer.toJsonString(asyncapi))
.whenIgnoringPaths("asyncapi", "operations")
.isEqualTo(example);
}

@Test
void shouldSerializeAMQPChannelBindingRouting() throws IOException {

var asyncapi = AsyncAPI.builder()
.channels(Map.of(
"userSignup",
ChannelObject.builder()
.address("user/signup")
.bindings(Map.of(
"amqp",
AMQPChannelBinding.builder()
.is(AMQPChannelType.ROUTING_KEY)
.exchange(AMQPChannelExchangeProperties.builder()
.name("myExchange")
.type(AMQPChannelExchangeType.TOPIC)
Expand All @@ -48,7 +71,7 @@ void shouldSerializeAMQPChannelBinding() throws IOException {
.build();

// Uses https://github.com/asyncapi/bindings/blob/master/amqp/README.md#example
var example = ClasspathUtil.parseYamlFile("/v3/bindings/amqp/amqp-channel.yaml");
var example = ClasspathUtil.parseYamlFile("/v3/bindings/amqp/amqp-channel-routing.yaml");
assertThatJson(serializer.toJsonString(asyncapi))
.whenIgnoringPaths("asyncapi", "operations")
.isEqualTo(example);
Expand Down
Loading
Loading