Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -65,7 +65,7 @@ private ObjectNode mapToJsonSchema(
node.set("allOf", arrayNode);
}
if (schema.getConstValue() != null) {
node.put("const", schema.getConstValue().toString());
node.set("const", jsonMapper.valueToTree(schema.getConstValue()));
}
if (schema.getDescription() != null) {
node.put("description", schema.getDescription());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ public static Stream<Arguments> validateJsonSchemaTest() {
schema.setConst("test");
return schema;
}),
Arguments.of(
"{\"const\": 42,\"type\":\"integer\",\"$schema\":\"https://json-schema.org/draft-07/schema#\"}",
(Supplier<Schema<?>>) () -> {
Schema<Integer> schema = new Schema<>();
schema.setType("integer");
schema.setConst(42);
return schema;
}),
Arguments.of(
"{\"const\": true,\"type\":\"boolean\",\"$schema\":\"https://json-schema.org/draft-07/schema#\"}",
(Supplier<Schema<?>>) () -> {
BooleanSchema schema = new BooleanSchema();
schema.setConst(true);
return schema;
}),
Arguments.of(
"{\"description\": \"test\",\"type\":\"string\",\"$schema\":\"https://json-schema.org/draft-07/schema#\"}",
(Supplier<Schema<?>>) () -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public class SchemaObject extends ExtendableObject implements Schema {
@JsonProperty(value = "maxLength")
private Integer maxLength;

/**
* For a single entry, use {@link #constValue}
*/
@JsonProperty("enum")
private List<String> enumValues;

Expand Down Expand Up @@ -125,6 +128,9 @@ public class SchemaObject extends ExtendableObject implements Schema {
@JsonProperty(value = "anyOf")
private List<ComponentSchema> anyOf;

/**
* For multiple entries, use {@link #enumValues}
*/
@JsonProperty(value = "const")
private Object constValue;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private AsyncAPI getAsyncAPITestObject(SchemaFormat schemaFormat) {
Map<String, Message> messages = Map.of(message.getMessageId(), message);

SchemaObject groupId = new SchemaObject();
groupId.setEnumValues(List.of("myGroupId"));
groupId.setConstValue("myGroupId");
groupId.setType(Set.of(SchemaType.STRING.getValue()));

OperationBinding operationBinding =
Expand All @@ -102,11 +102,9 @@ private AsyncAPI getAsyncAPITestObject(SchemaFormat schemaFormat) {
.build();

ChannelObject newUserChannel = ChannelObject.builder()
// FIXME: Can we autogenerate the address somehow?
.address("new-user")
.description("This channel is used to exchange messages about users signing up")
.servers(List.of(
ServerReference.builder().ref("#/servers/production").build()))
.servers(List.of(ServerReference.fromServer("production")))
.messages(Map.of(message.getMessageId(), MessageReference.toComponentMessage(message)))
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@
"kafka": {
"groupId": {
"type": "string",
"enum": [
"myGroupId"
]
"const": "myGroupId"
},
"bindingVersion": "0.5.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ operations:
kafka:
groupId:
type: string
enum:
- myGroupId
const: myGroupId
bindingVersion: 0.5.0
messages:
- "$ref": "#/channels/new-user/messages/io.github.springwolf.core.ExamplePayload"
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@
"kafka": {
"groupId": {
"type": "string",
"enum": [
"myGroupId"
]
"const": "myGroupId"
},
"bindingVersion": "0.5.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ operations:
kafka:
groupId:
type: string
enum:
- myGroupId
const: myGroupId
bindingVersion: 0.5.0
messages:
- "$ref": "#/channels/new-user/messages/io.github.springwolf.core.ExamplePayload"
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;

import java.util.List;
import java.util.Set;

public class KafkaOperationBindingProcessor extends AbstractOperationBindingProcessor<KafkaAsyncOperationBinding> {
Expand Down Expand Up @@ -42,7 +41,7 @@ protected ProcessedOperationBinding mapToOperationBinding(KafkaAsyncOperationBin
private static SchemaObject createStringSchema(String value) {
if (value != null && !value.isEmpty()) {
SchemaObject schema = new SchemaObject();
schema.setEnumValues(List.of(value));
schema.setConstValue(value);
schema.setType(Set.of(SchemaType.STRING.getValue()));
return schema;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,10 @@ private Optional<T> buildExampleFromUnvisitedSchema(
return composedSchemaExample;
}

// schema may be an openapi v3 or v3.1 schema. While v3 uses an simple 'type' field, v3.1 supports a set of
// types, for example ["string", "null"].
Optional<T> constOrEnumExample = buildFromConstOrEnum(schema);
if (constOrEnumExample.isPresent()) {
return constOrEnumExample;
}

String type = getTypeForExampleValue(schema);
if (type == null) {
Expand Down Expand Up @@ -200,11 +202,6 @@ private Optional<T> buildArrayExample(Schema schema, Map<String, Schema> definit
}

private Optional<T> buildFromStringSchema(Schema schema) {
String firstEnumValue = getFirstEnumValue(schema);
if (firstEnumValue != null) {
return exampleValueGenerator.createEnumExample(firstEnumValue, schema);
}

String format = schema.getFormat();
if (format == null) {
return exampleValueGenerator.createStringExample(DEFAULT_STRING_EXAMPLE, schema);
Expand All @@ -222,6 +219,20 @@ private Optional<T> buildFromStringSchema(Schema schema) {
};
}

private Optional<T> buildFromConstOrEnum(Schema schema) {
Object constValue = schema.getConst();
if (constValue != null) {
return exampleValueGenerator.createStringExample(constValue.toString(), schema);
}

String firstEnumValue = getFirstEnumValue(schema);
if (firstEnumValue != null) {
return exampleValueGenerator.createEnumExample(firstEnumValue, schema);
}

return Optional.empty();
}

private String getFirstEnumValue(Schema schema) {
List<String> enums = schema.getEnum();
if (enums != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ public static SchemaObject getAsyncHeaders(AsyncOperation op, StringValueResolve
List<String> values = getHeaderValues(headersValues, stringValueResolver);
if (!values.isEmpty()) {
property.setExamples(new ArrayList<>(values));
property.setEnumValues(values);
if (values.size() == 1) {
property.setConstValue(values.get(0));
} else {
property.setEnumValues(values);
}
}
headerSchema.getProperties().put(propertyName, property);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,11 @@ private SchemaObject mapSwaggerSchemaToAsyncApiSchema(Schema<?> swaggerSchema) {
if (isNullable) {
enumStringValues.add(null);
}
builder.enumValues(enumStringValues);
if (enumStringValues.size() == 1) {
builder.constValue(anEnum.get(0));
} else {
builder.enumValues(enumStringValues);
}
}

Object example = swaggerSchema.getExample();
Expand Down Expand Up @@ -181,7 +185,9 @@ private SchemaObject mapSwaggerSchemaToAsyncApiSchema(Schema<?> swaggerSchema) {
builder.anyOf(anyOf.stream().map(this::mapSchemaOrRef).collect(Collectors.toList()));
}

builder.constValue(swaggerSchema.getConst());
if (swaggerSchema.getConst() != null) {
builder.constValue(swaggerSchema.getConst());
}

Schema not = swaggerSchema.getNot();
if (not != null) {
Expand Down Expand Up @@ -297,6 +303,7 @@ private Schema mapSchemaObjectToSwagger(SchemaObject asyncApiSchema) {
swaggerSchema.setDescription(asyncApiSchema.getDescription());
swaggerSchema.setExamples(asyncApiSchema.getExamples());
swaggerSchema.setEnum(asyncApiSchema.getEnumValues());
swaggerSchema.setConst(asyncApiSchema.getConstValue());

if (asyncApiSchema.getProperties() != null) {
Map<String, Schema> properties = asyncApiSchema.getProperties().entrySet().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,20 @@ void mapEnum() {
assertThat(componentSchema.getSchema().getEnumValues()).isEqualTo(schema.getEnum());
}

@Test
void mapSingleEnumValueAsConst() {
// given
ObjectSchema schema = new ObjectSchema();
schema.setEnum(List.of("only"));

// when
ComponentSchema componentSchema = swaggerSchemaMapper.mapSchema(schema);

// then
assertThat(componentSchema.getSchema().getEnumValues()).isNull();
assertThat(componentSchema.getSchema().getConstValue()).isEqualTo("only");
}

@Test
void mapExample() {
// given
Expand Down Expand Up @@ -723,6 +737,19 @@ void mapEnum() {
assertThat(swaggerSchema.getEnum()).isEqualTo(schema.getEnumValues());
}

@Test
void mapConst() {
// given
SchemaObject schema = new SchemaObject();
schema.setConstValue(42);

// when
Schema<?> swaggerSchema = swaggerSchemaMapper.mapToSwagger(schema);

// then
assertThat(swaggerSchema.getConst()).isEqualTo(42);
}

@Test
void mapNullableEnum() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import io.swagger.v3.oas.models.media.Schema;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -24,4 +26,19 @@ void getTypeForExampleValue() {
assertThat(schemaWalker.getTypeForExampleValue(schema3)).isEqualTo("string");
assertThat(schemaWalker.getTypeForExampleValue(schema4)).isEqualTo("integer");
}

@Test
void getDefaultValue() {
DefaultSchemaWalker schemaWalker = new DefaultSchemaWalker<>(new DummyExampleValueGenerator());

Schema schema1 = new Schema().type("string");
Schema schema2 = new Schema().type("string");
schema2.setConst("constValue");
Schema schema3 = new Schema().type("string");
schema3.setEnum(List.of("example1", "example2"));

assertThat(schemaWalker.fromSchema(schema1, Map.of())).isEqualTo("string");
assertThat(schemaWalker.fromSchema(schema2, Map.of())).isEqualTo("constValue");
assertThat(schemaWalker.fromSchema(schema3, Map.of())).isEqualTo("example1");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.springwolf.core.asyncapi.components.examples.walkers;

import io.swagger.v3.oas.models.media.Schema;

import java.util.List;
import java.util.Optional;

class DummyExampleValueGenerator implements ExampleValueGenerator {

@Override
public boolean canHandle(String contentType) {
return true;
}

@Override
public Optional<String> lookupSchemaName(Schema schema) {
return Optional.empty();
}

@Override
public Object prepareForSerialization(Schema name, Object exampleObject) {
return exampleObject;
}

@Override
public Optional createIntegerExample(Integer value, Schema schema) {
return Optional.of("integerExample");
}

@Override
public Optional createDoubleExample(Double value, Schema schema) {
return Optional.of("doubleExample");
}

@Override
public Optional createBooleanExample(Boolean value, Schema schema) {
return Optional.of("booleanExample");
}

@Override
public Optional createEmptyObjectExample() {
return Optional.of("emptyObjectExample");
}

@Override
public Optional createStringExample(String value, Schema schema) {
return Optional.of(value);
}

@Override
public Optional createEnumExample(String anEnumValue, Schema schema) {
return Optional.of(anEnumValue);
}

@Override
public Optional createUnknownSchemaStringTypeExample(String schemaType) {
return Optional.empty();
}

@Override
public Optional createUnknownSchemaStringFormatExample(String schemaFormat) {
return Optional.empty();
}

@Override
public Object createRaw(Object exampleValueString) {
return exampleValueString;
}

@Override
public Object getExampleOrNull(Optional fieldName, Schema schema, Object example) {
return schema.getExample();
}

@Override
public Object createArrayExample(Optional name, Object arrayItem) {
return null;
}

@Override
public void addPropertyExamples(Object object, List properties) {}

@Override
public Object startObject(Optional name) {
return null;
}
}
Loading
Loading