Skip to content

Commit

Permalink
Merge branch 'master' into openApi-3.1-ComposedSchema-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
GooDer committed Apr 23, 2024
2 parents 09202fa + 616350b commit 49d9684
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,20 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
isPrimitive = true;
}
if (model == null) {
PrimitiveType primitiveType = PrimitiveType.fromType(type);
if (primitiveType != null) {
model = PrimitiveType.fromType(type).createProperty();
isPrimitive = true;
if (resolvedSchemaAnnotation != null && StringUtils.isEmpty(resolvedSchemaAnnotation.type())) {
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(type, resolvedSchemaAnnotation.format());
if (primitiveType != null) {
model = primitiveType.createProperty();
isPrimitive = true;
}
}

if (model == null) {
PrimitiveType primitiveType = PrimitiveType.fromType(type);
if (primitiveType != null) {
model = primitiveType.createProperty();
isPrimitive = true;
}
}
}

Expand Down Expand Up @@ -629,7 +639,8 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
propType = ((AnnotatedMethod)member).getParameterType(0);
}

}
}

String propSchemaName = null;
io.swagger.v3.oas.annotations.media.Schema ctxSchema = AnnotationsUtils.getSchemaAnnotation(annotations);
if (AnnotationsUtils.hasSchemaAnnotation(ctxSchema)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,10 @@ public static Optional<Header> getHeader(io.swagger.v3.oas.annotations.headers.H
if (resolvedSchema.schema != null) {
headerObject.setSchema(resolvedSchema.schema);
}
resolvedSchema.referencedSchemas.forEach(components::addSchemas);
if (resolvedSchema.referencedSchemas != null && components != null) {
resolvedSchema.referencedSchemas.forEach(components::addSchemas);
}

}
}
if (hasArrayAnnotation(header.array())){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -41,13 +43,23 @@ public Schema createProperty() {
},
BYTE(Byte.class, "byte") {
@Override
public ByteArraySchema createProperty() {
public Schema createProperty() {
if (
(System.getProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY) != null && System.getProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY).equals(Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_STRING_SCHEMA.toString())) ||
(System.getenv(Schema.BINARY_STRING_CONVERSION_PROPERTY) != null && System.getenv(Schema.BINARY_STRING_CONVERSION_PROPERTY).equals(Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_STRING_SCHEMA.toString()))) {
return new StringSchema().format("byte");
}
return new ByteArraySchema();
}
},
BINARY(Byte.class, "binary") {
@Override
public BinarySchema createProperty() {
public Schema createProperty() {
if (
(System.getProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY) != null && System.getProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY).equals(Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_STRING_SCHEMA.toString())) ||
(System.getenv(Schema.BINARY_STRING_CONVERSION_PROPERTY) != null && System.getenv(Schema.BINARY_STRING_CONVERSION_PROPERTY).equals(Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_STRING_SCHEMA.toString()))) {
return new StringSchema().format("binary");
}
return new BinarySchema();
}
},
Expand Down Expand Up @@ -149,6 +161,7 @@ public Schema createProperty() {
};

private static final Map<Class<?>, PrimitiveType> KEY_CLASSES;
private static final Map<Class<?>, Collection<PrimitiveType>> MULTI_KEY_CLASSES;
private static final Map<Class<?>, PrimitiveType> BASE_CLASSES;
/**
* Adds support of a small number of "well-known" types, specifically for
Expand Down Expand Up @@ -244,6 +257,11 @@ public Schema createProperty() {
addKeys(keyClasses, OBJECT, Object.class);
KEY_CLASSES = Collections.unmodifiableMap(keyClasses);

final Map<Class<?>, Collection<PrimitiveType>> multiKeyClasses = new HashMap<>();
addMultiKeys(multiKeyClasses, BYTE, byte[].class);
addMultiKeys(multiKeyClasses, BINARY, byte[].class);
MULTI_KEY_CLASSES = Collections.unmodifiableMap(multiKeyClasses);

final Map<Class<?>, PrimitiveType> baseClasses = new HashMap<>();
addKeys(baseClasses, DATE_TIME, java.util.Date.class, java.util.Calendar.class);
BASE_CLASSES = Collections.unmodifiableMap(baseClasses);
Expand Down Expand Up @@ -343,6 +361,20 @@ public static Set<String> nonSystemTypePackages() {
return nonSystemTypePackages;
}

public static PrimitiveType fromTypeAndFormat(Type type, String format) {
final Class<?> raw = TypeFactory.defaultInstance().constructType(type).getRawClass();
final Collection<PrimitiveType> keys = MULTI_KEY_CLASSES.get(raw);
if (keys == null || keys.isEmpty() || StringUtils.isBlank(format)) {
return fromType(type);
} else {
return keys
.stream()
.filter(t -> t.getCommonName().equalsIgnoreCase(format))
.findAny()
.orElse(null);
}
}

public static PrimitiveType fromType(Type type) {
final Class<?> raw = TypeFactory.defaultInstance().constructType(type).getRawClass();
final PrimitiveType key = KEY_CLASSES.get(raw);
Expand All @@ -351,6 +383,14 @@ public static PrimitiveType fromType(Type type) {
return key;
}
}

final Collection<PrimitiveType> keys = MULTI_KEY_CLASSES.get(raw);
if (keys != null && !keys.isEmpty()) {
final PrimitiveType first = keys.iterator().next();
if (!customExcludedClasses.contains(raw.getName())) {
return first;
}
}

final PrimitiveType custom = customClasses.get(raw.getName());
if (custom != null) {
Expand Down Expand Up @@ -424,6 +464,15 @@ private static <K> void addKeys(Map<K, PrimitiveType> map, PrimitiveType type, K
}
}

private static <K> void addMultiKeys(Map<K, Collection<PrimitiveType>> map, PrimitiveType type, K... keys) {
for (K key : keys) {
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(type);
}
}

private static class DateStub {
private DateStub() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.swagger.v3.jaxrs2;

import java.io.IOException;

import io.swagger.v3.oas.models.media.Schema;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import io.swagger.v3.jaxrs2.annotations.AbstractAnnotationTest;
import io.swagger.v3.jaxrs2.resources.BinaryParameterResource;

public class BinaryParameterResourceTest extends AbstractAnnotationTest {

@Test(description = "check binary model serialization with base64", singleThreaded = true) // tests issue #2466
public void shouldSerializeBinaryParameterBase64() throws IOException {
try {
System.setProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY, Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_BASE64.toString());
compareAsYaml(BinaryParameterResource.class, getOpenAPIAsString("BinaryParameterResource.yaml"));
} finally {
System.clearProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY);
}
}

@BeforeTest
public void before() {
System.clearProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY);
}

@AfterTest
public void after() {
System.clearProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY);
}


@Test(description = "check binary model serialization with StringSchema", singleThreaded = true) // tests issue #2466
public void shouldSerializeBinaryParameterStringSchema() throws IOException {
try {
System.setProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY, Schema.BynaryStringConversion.BINARY_STRING_CONVERSION_STRING_SCHEMA.toString());
compareAsYaml(BinaryParameterResource.class, getOpenAPIAsString("BinaryParameterResource.yaml"));
} finally {
System.clearProperty(Schema.BINARY_STRING_CONVERSION_PROPERTY);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.swagger.v3.jaxrs2.resources;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import io.swagger.v3.jaxrs2.resources.model.Item;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;

@Path("/")
public class BinaryParameterResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Path("/binary")
@POST
@Operation(
summary = "Create new item",
description = "Post operation with entity in a body",
responses = {
@ApiResponse(
content = @Content(
schema = @Schema(implementation = Item.class),
mediaType = MediaType.APPLICATION_JSON
),
headers = @Header(name = "Location"),
responseCode = "201"
)
}
)
public Response createItem(@Context final UriInfo uriInfo, @Parameter(required = true) final Item item) {
return Response
.created(uriInfo.getBaseUriBuilder().path(item.getName()).build())
.entity(item).build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.swagger.v3.jaxrs2.resources.model;

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

public class Item {
private String name;
private String value;
@Schema(example = "Ynl0ZQ==")
private byte[] bytes;
@Schema(format = "binary", example = "YmluYXJ5")
private byte[] binary;

private byte[] byteNoAnnotation;

public Item() {
}

public void setBinary(byte[] binary) {
this.binary = binary;
}

public byte[] getBinary() {
return binary;
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setValue(String value) {
this.value = value;
}

public String getValue() {
return value;
}

public void setBytes(byte[] bytes) {
this.bytes = bytes;
}

public byte[] getBytes() {
return bytes;
}

public void setByteNoAnnotation(byte[] byteNoAnnotation) {
this.byteNoAnnotation = byteNoAnnotation;
}

public byte[] getByteNoAnnotation() {
return byteNoAnnotation;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
openapi: 3.0.1
paths:
/binary:
post:
summary: Create new item
description: Post operation with entity in a body
operationId: createItem
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
required: true
responses:
"201":
headers:
Location:
style: simple
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
components:
schemas:
Item:
type: object
properties:
name:
type: string
value:
type: string
bytes:
type: string
format: byte
example: Ynl0ZQ==
binary:
type: string
format: binary
example: YmluYXJ5
byteNoAnnotation:
type: string
format: byte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.swagger.v3.oas.models.media;

import java.util.Base64;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -36,6 +37,13 @@ protected byte[] cast(Object value) {
try {
if (value instanceof byte[]) {
return (byte[]) value;
} else if (value instanceof String) {
if (
(System.getProperty(BINARY_STRING_CONVERSION_PROPERTY) != null && System.getProperty(BINARY_STRING_CONVERSION_PROPERTY).equals(BynaryStringConversion.BINARY_STRING_CONVERSION_BASE64.toString())) ||
(System.getenv(BINARY_STRING_CONVERSION_PROPERTY) != null && System.getenv(BINARY_STRING_CONVERSION_PROPERTY).equals(BynaryStringConversion.BINARY_STRING_CONVERSION_BASE64.toString()))) {
return Base64.getDecoder().decode((String) value);
}
return value.toString().getBytes();
} else {
return value.toString().getBytes();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.swagger.v3.oas.models.media;

import java.util.Base64;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -36,6 +37,13 @@ protected byte[] cast(Object value) {
try {
if (value instanceof byte[]) {
return (byte[]) value;
} else if (value instanceof String) {
if (
(System.getProperty(BINARY_STRING_CONVERSION_PROPERTY) != null && System.getProperty(BINARY_STRING_CONVERSION_PROPERTY).equals(BynaryStringConversion.BINARY_STRING_CONVERSION_BASE64.toString())) ||
(System.getenv(BINARY_STRING_CONVERSION_PROPERTY) != null && System.getenv(BINARY_STRING_CONVERSION_PROPERTY).equals(BynaryStringConversion.BINARY_STRING_CONVERSION_BASE64.toString()))) {
return Base64.getDecoder().decode((String) value);
}
return value.toString().getBytes();
} else {
return value.toString().getBytes();
}
Expand Down
Loading

0 comments on commit 49d9684

Please sign in to comment.