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: 3.0.0 preview #10

Merged
merged 54 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
cbceb46
feat(3.0.0): AsyncAPI
Pakisan Sep 24, 2023
6700e20
feat(3.0.0): Contact
Pakisan Sep 24, 2023
7c25d5b
feat(3.0.0): Licence
Pakisan Sep 24, 2023
faaed80
feat(3.0.0): ExternalDocumentation
Pakisan Sep 24, 2023
ec89194
feat(3.0.0): Tag
Pakisan Sep 24, 2023
cb01541
feat(3.0.0): Info
Pakisan Sep 24, 2023
e4fa43d
feat(3.0.0): ExternalDocumentation tests
Pakisan Sep 24, 2023
b44f5f0
feat(3.0.0): Tag tests
Pakisan Sep 24, 2023
e74a2d0
feat(3.0.0): Reference tests
Pakisan Sep 26, 2023
9e9cf96
feat(3.0.0): Contact tests
Pakisan Sep 26, 2023
12f812e
feat(3.0.0): License tests
Pakisan Sep 26, 2023
e765347
feat(3.0.0): Info tests
Pakisan Sep 26, 2023
685afec
feat(3.0.0): ServerVariable
Pakisan Sep 27, 2023
ca00f7c
feat(3.0.0): ApiKeySecurityScheme
Pakisan Sep 27, 2023
6accd4e
feat(3.0.0): OpenIdConnectSecurityScheme
Pakisan Sep 27, 2023
21a9077
feat(3.0.0): userPassword security scheme
Pakisan Sep 27, 2023
72dec6b
feat(3.0.0): X509 security scheme
Pakisan Sep 27, 2023
a333ee2
feat(3.0.0): symmetricEncryption security scheme
Pakisan Sep 27, 2023
2fe1728
feat(3.0.0): asymmetricEncryption security scheme
Pakisan Sep 27, 2023
e88711d
feat(3.0.0): HttpApiKeySecurityScheme
Pakisan Sep 27, 2023
6d7c110
feat(3.0.0): HttpSecurityScheme
Pakisan Sep 27, 2023
f1759fc
feat(3.0.0): OAuth2SecurityScheme
Pakisan Sep 27, 2023
1db0532
feat(3.0.0): plain security scheme
Pakisan Sep 27, 2023
5a0182d
feat(3.0.0): scramSha256 security scheme
Pakisan Sep 27, 2023
47c6ca6
feat(3.0.0): scramSha512 security scheme
Pakisan Sep 27, 2023
63e5012
feat(3.0.0): gssapi security scheme
Pakisan Sep 27, 2023
9624430
feat(3.0.0): ServerBinding
Pakisan Sep 27, 2023
a9f5b25
feat(3.0.0): Server
Pakisan Sep 27, 2023
250e413
feat(3.0.0): Channel parameter
Pakisan Sep 28, 2023
1d2d6d2
feat(3.0.0): Schema
Pakisan Sep 28, 2023
bbcbf4b
feat(3.0.0): Schema
Pakisan Sep 28, 2023
deddbd7
feat(3.0.0): Schema types
Pakisan Sep 28, 2023
16a05c9
feat(3.0.0): Multi Format Schema
Pakisan Sep 28, 2023
732e555
feat(3.0.0): CorrelationId
Pakisan Sep 28, 2023
1fcb1c5
feat(3.0.0): MessageExample
Pakisan Sep 28, 2023
6a2f987
feat(3.0.0): MessageBinding
Pakisan Sep 28, 2023
67ef603
feat(3.0.0): MessageTrait
Pakisan Oct 1, 2023
cde8684
feat(3.0.0): Message
Pakisan Oct 1, 2023
d904d03
fix(3.0.0): SchemasAdditionalPropertiesDeserializer fix schema version
Pakisan Oct 1, 2023
ffb19a3
feat(3.0.0): ChannelBinding
Pakisan Oct 1, 2023
977d04e
feat(3.0.0): Channel
Pakisan Oct 2, 2023
879341c
feat(3.0.0): OperationBinding
Pakisan Oct 2, 2023
45d44b6
feat(3.0.0): OperationReplyAddress
Pakisan Oct 3, 2023
2f89ae6
feat(3.0.0): OperationReply
Pakisan Oct 3, 2023
5445d18
feat(3.0.0): OperationTrait
Pakisan Oct 3, 2023
0bb710e
feat(3.0.0): OperationTrait @Nullable
Pakisan Oct 3, 2023
e9e72a4
feat(3.0.0): Operation
Pakisan Oct 3, 2023
1362ab5
feat(3.0.0): Components
Pakisan Oct 4, 2023
29ecb19
feat(3.0.0): AsyncAPI test
Pakisan Oct 4, 2023
898d915
feat(3.0.0): refactor tests
Pakisan Oct 5, 2023
bd0b8e9
refactor(tests): new location for security_scheme test resources
Pakisan Oct 5, 2023
2425b60
refactor(tests): new location for binding test resources
Pakisan Oct 5, 2023
944f338
refactor(tests): new location for 2.0.0 test resources
Pakisan Oct 5, 2023
d61c3f9
refactor(tests): new location for 2.6.0 test resources
Pakisan Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.asyncapi.v3;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties({"extensionFields"})
public class ExtendableObject {

private static final Pattern extensionPropertyNamePattern = Pattern.compile("^x-[\\w\\d\\-\\_]+$");

/**
* Extension fields in the form x-extension-field-name for the exposed API.
*/
@Nullable
@JsonAnyGetter
protected Map<String, Object> extensionFields;

@JsonAnySetter
protected final void readExtensionProperty(String name, Object value) {
if (extensionPropertyNamePattern.matcher(name).matches()) {
if (extensionFields == null) {
extensionFields = new HashMap<>();
}

extensionFields.put(name, value);
} else {
throw new IllegalArgumentException(String.format("\"%s\" is not valid extension property", name));
}
}

}
38 changes: 38 additions & 0 deletions asyncapi-core/src/main/java/com/asyncapi/v3/Reference.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.asyncapi.v3;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

/**
* A simple object to allow referencing other components in the specification, internally and externally.
* <p>
* The Reference Object is defined by <a href="https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03">JSON Reference</a> and follows the same structure, behavior and rules.
* A JSON Reference SHALL only be used to refer to a schema that is formatted in either JSON or YAML.
* In the case of a YAML-formatted Schema, the JSON Reference SHALL be applied to the JSON representation of
* that schema. The JSON representation SHALL be made by applying the conversion described <a href="https://www.asyncapi.com/docs/reference/specification/v2.6.0#format">here</a>.
* <p>
* For this specification, reference resolution is done as defined by the JSON Reference specification and not by
* the JSON Schema specification.
*
* @version 3.0.0
* @see <a href="https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.14#referenceObject">Reference</a>
* @author Pavel Bodiachevskii
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Reference {

/**
* Required.
* <p>
* The reference string.
*/
@NotNull
@JsonProperty(value = "$ref")
private String ref = "";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.asyncapi.v3._0_0.jackson.model;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.ExternalDocumentation;
import com.asyncapi.v3.jackson.ReferenceOrObjectDeserializer;

/**
* Deserializes external documentation.
*
* @author Pavel Bodiachevskii
*/
public class ExternalDocumentationDeserializer extends ReferenceOrObjectDeserializer<ExternalDocumentation> {

@Override
public Class<ExternalDocumentation> objectTypeClass() {
return ExternalDocumentation.class;
}

public Class<?> referenceClass() {
return Reference.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.asyncapi.v3._0_0.jackson.model;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.Tag;
import com.asyncapi.v3.jackson.ListOfReferencesOrObjectsDeserializer;

/**
* Deserializes tags.
*
* @author Pavel Bodiachevskii
*/
public class TagsDeserializer extends ListOfReferencesOrObjectsDeserializer<Tag> {

@Override
public Class<Tag> objectTypeClass() {
return Tag.class;
}

@Override
public Class<?> referenceClass() {
return Reference.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.asyncapi.v3._0_0.jackson.model.channel;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.channel.Parameter;
import com.asyncapi.v3.jackson.MapOfReferencesOrObjectsDeserializer;

/**
* Serializes {@link com.asyncapi.v3._0_0.model.channel.Parameter} variables map.
*
* @version 3.0.0
* @author Pavel Bodiachevskii
*/
public class ChannelParametersDeserializer extends MapOfReferencesOrObjectsDeserializer<Parameter> {

@Override
public Class<Parameter> objectTypeClass() {
return Parameter.class;
}

@Override
public Class<?> referenceClass() {
return Reference.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.asyncapi.v3._0_0.jackson.model.channel;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.channel.Channel;
import com.asyncapi.v3.jackson.MapOfReferencesOrObjectsDeserializer;

/**
* Serializes component channels map.
*
* @author Pavel Bodiachevskii
*/
public class ChannelsDeserializer extends MapOfReferencesOrObjectsDeserializer<Channel> {

@Override
public Class<Channel> objectTypeClass() {
return Channel.class;
}

@Override
public Class<?> referenceClass() {
return Reference.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.asyncapi.v3._0_0.jackson.model.channel.message;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.channel.message.CorrelationId;
import com.asyncapi.v3.jackson.ReferenceOrObjectDeserializer;

/**
* Serializes message correlation id.
*
* @author Pavel Bodiachevskii
*/
public class MessageCorrelationIdDeserializer extends ReferenceOrObjectDeserializer<CorrelationId> {

@Override
public Class<CorrelationId> objectTypeClass() {
return CorrelationId.class;
}

public Class<?> referenceClass() {
return Reference.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.asyncapi.v3._0_0.jackson.model.channel.message;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3.schema.Schema;
import com.asyncapi.v3.schema.MultiFormatSchema;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

/**
* Serializes message traits list.
*
* @author Pavel Bodiachevskii
*/
public class MessageHeadersDeserializer extends JsonDeserializer<Object> {

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectCodec objectCodec = p.getCodec();
JsonNode node = objectCodec.readTree(p);

/*
Problem:
Both, Reference class and Schema class have $ref field.
So, this is only reason why I receive next exception:
"com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "title" (class com.asyncapi.v2._6_0.model.Reference),
not marked as ignorable (one known property: "$ref"])"
in case when Schema contains $ref.
Solution:
Try to deserialize reference. In case of exception, try to deserialize it as given ObjectType. In case of
one more exception, throw it.
TODO: Think how to improve.
*/
try {
return chooseKnownPojo(node, objectCodec);
} catch (UnrecognizedPropertyException unrecognizedPropertyException) {
return readAsObject(node, objectCodec);
}
}

private Object chooseKnownPojo(JsonNode jsonNode, ObjectCodec objectCodec) throws IOException {
JsonNode ref = jsonNode.get("$ref");
try (JsonParser jsonParser = jsonNode.traverse(objectCodec)) {
if (isMultiFormatSchema(jsonNode)) {
return jsonParser.readValueAs(MultiFormatSchema.class);
}

if (ref != null) {
return jsonParser.readValueAs(Reference.class);
} else {
return jsonParser.readValueAs(Schema.class);
}
}
}

private Object readAsObject(JsonNode jsonNode, ObjectCodec objectCodec) throws IOException {
try (JsonParser jsonParser = jsonNode.traverse(objectCodec)) {
return jsonParser.readValueAs(Schema.class);
}
}

private boolean isMultiFormatSchema(@NotNull JsonNode jsonNode) {
JsonNode schemaFormat = jsonNode.get("schemaFormat");
JsonNode schema = jsonNode.get("schema");

return (schemaFormat != null) && (schema != null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.asyncapi.v3._0_0.jackson.model.channel.message;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3.schema.MultiFormatSchema;
import com.asyncapi.v3.schema.Schema;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

/**
* Serializes message traits list.
*
* @author Pavel Bodiachevskii
*/
public class MessagePayloadDeserializer extends JsonDeserializer<Object> {

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectCodec objectCodec = p.getCodec();
JsonNode node = objectCodec.readTree(p);

/*
Problem:
Both, Reference class and Schema class have $ref field.
So, this is only reason why I receive next exception:
"com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "title" (class com.asyncapi.v2._6_0.model.Reference),
not marked as ignorable (one known property: "$ref"])"
in case when Schema contains $ref.
Solution:
Try to deserialize reference. In case of exception, try to deserialize it as given ObjectType. In case of
one more exception, throw it.
TODO: Think how to improve.
*/
try {
return chooseKnownPojo(node, objectCodec);
} catch (UnrecognizedPropertyException unrecognizedPropertyException) {
return readAsObject(node, objectCodec);
}
}

private Object chooseKnownPojo(JsonNode jsonNode, ObjectCodec objectCodec) throws IOException {
JsonNode ref = jsonNode.get("$ref");
try (JsonParser jsonParser = jsonNode.traverse(objectCodec)) {
if (isMultiFormatSchema(jsonNode)) {
return jsonParser.readValueAs(MultiFormatSchema.class);
}

if (ref != null) {
return jsonParser.readValueAs(Reference.class);
} else {
return jsonParser.readValueAs(Schema.class);
}
}
}

private Object readAsObject(JsonNode jsonNode, ObjectCodec objectCodec) throws IOException {
try (JsonParser jsonParser = jsonNode.traverse(objectCodec)) {
return jsonParser.readValueAs(Schema.class);
}
}

private boolean isMultiFormatSchema(@NotNull JsonNode jsonNode) {
JsonNode schemaFormat = jsonNode.get("schemaFormat");
JsonNode schema = jsonNode.get("schema");

return (schemaFormat != null) && (schema != null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.asyncapi.v3._0_0.jackson.model.channel.message;

import com.asyncapi.v3.Reference;
import com.asyncapi.v3._0_0.model.channel.message.MessageTrait;
import com.asyncapi.v3.jackson.ListOfReferencesOrObjectsDeserializer;

/**
* Deserializes message traits.
*
* @author Pavel Bodiachevskii
*/
public class MessageTraitsDeserializer extends ListOfReferencesOrObjectsDeserializer<MessageTrait> {

@Override
public Class<MessageTrait> objectTypeClass() {
return MessageTrait.class;
}

@Override
public Class<?> referenceClass() {
return Reference.class;
}

}
Loading