diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b0c054951..7b1e0a379 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,11 +85,14 @@ jobs: tck-reporting: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: include: - - tck-version: "2.0.1" - - tck-version: "3.0" - - tck-version: "3.1.1" + # Disable older TCK jobs prior to 4.0 GA release + #- tck-version: "2.0.1" + #- tck-version: "3.0" + #- tck-version: "3.1.1" + - tck-version: "4.0" name: MicroProfile OpenAPI TCK ${{ matrix.tck-version }} steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3c253c720..02c6b9525 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,9 +73,11 @@ jobs: strategy: matrix: include: - - tck-version: "2.0.1" - - tck-version: "3.0" - - tck-version: "3.1.1" + # Disable older TCK jobs prior to 4.0 GA release + #- tck-version: "2.0.1" + #- tck-version: "3.0" + #- tck-version: "3.1.1" + - tck-version: "4.0" name: MicroProfile OpenAPI TCK ${{ matrix.tck-version }} steps: diff --git a/core/pom.xml b/core/pom.xml index 8530b873c..3a5cb8e66 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-core diff --git a/core/src/main/java/io/smallrye/openapi/api/OpenApiConfig.java b/core/src/main/java/io/smallrye/openapi/api/OpenApiConfig.java index 44880c8b7..be3995998 100644 --- a/core/src/main/java/io/smallrye/openapi/api/OpenApiConfig.java +++ b/core/src/main/java/io/smallrye/openapi/api/OpenApiConfig.java @@ -209,6 +209,10 @@ default String getInfoTermsOfService() { return getConfigValue(SmallRyeOASConfig.INFO_TERMS, String.class, () -> null); } + default String getInfoSummary() { + return getConfigValue(SmallRyeOASConfig.INFO_SUMMARY, String.class, () -> null); + } + default String getInfoContactEmail() { return getConfigValue(SmallRyeOASConfig.INFO_CONTACT_EMAIL, String.class, () -> null); } @@ -225,6 +229,10 @@ default String getInfoLicenseName() { return getConfigValue(SmallRyeOASConfig.INFO_LICENSE_NAME, String.class, () -> null); } + default String getInfoLicenseIdentifier() { + return getConfigValue(SmallRyeOASConfig.INFO_LICENSE_IDENTIFIER, String.class, () -> null); + } + default String getInfoLicenseUrl() { return getConfigValue(SmallRyeOASConfig.INFO_LICENSE_URL, String.class, () -> null); } diff --git a/core/src/main/java/io/smallrye/openapi/api/SmallRyeOASConfig.java b/core/src/main/java/io/smallrye/openapi/api/SmallRyeOASConfig.java index 5421e2c2c..93fb00160 100644 --- a/core/src/main/java/io/smallrye/openapi/api/SmallRyeOASConfig.java +++ b/core/src/main/java/io/smallrye/openapi/api/SmallRyeOASConfig.java @@ -62,11 +62,13 @@ private SmallRyeOASConfig() { public static final String INFO_TITLE = SMALLRYE_PREFIX + "info.title"; public static final String INFO_VERSION = SMALLRYE_PREFIX + "info.version"; public static final String INFO_DESCRIPTION = SMALLRYE_PREFIX + "info.description"; + public static final String INFO_SUMMARY = SMALLRYE_PREFIX + "info.summary"; public static final String INFO_TERMS = SMALLRYE_PREFIX + "info.termsOfService"; public static final String INFO_CONTACT_EMAIL = SMALLRYE_PREFIX + "info.contact.email"; public static final String INFO_CONTACT_NAME = SMALLRYE_PREFIX + "info.contact.name"; public static final String INFO_CONTACT_URL = SMALLRYE_PREFIX + "info.contact.url"; public static final String INFO_LICENSE_NAME = SMALLRYE_PREFIX + "info.license.name"; + public static final String INFO_LICENSE_IDENTIFIER = SMALLRYE_PREFIX + "info.license.identifier"; public static final String INFO_LICENSE_URL = SMALLRYE_PREFIX + "info.license.url"; public static final String OPERATION_ID_STRAGEGY = SMALLRYE_PREFIX + "operationIdStrategy"; public static final String DUPLICATE_OPERATION_ID_BEHAVIOR = SMALLRYE_PREFIX + "duplicateOperationIdBehavior"; @@ -81,7 +83,7 @@ private SmallRyeOASConfig() { public static final String AUTO_INHERITANCE = SMALLRYE_PREFIX + "auto-inheritance"; public static final class Defaults { - public static final String VERSION = "3.0.3"; + public static final String VERSION = "3.1.0"; private Defaults() { } diff --git a/core/src/main/java/io/smallrye/openapi/api/SmallRyeOpenAPI.java b/core/src/main/java/io/smallrye/openapi/api/SmallRyeOpenAPI.java index d7d92174d..1e344d2bb 100644 --- a/core/src/main/java/io/smallrye/openapi/api/SmallRyeOpenAPI.java +++ b/core/src/main/java/io/smallrye/openapi/api/SmallRyeOpenAPI.java @@ -216,7 +216,7 @@ public Builder enableStandardFilter(boolean enableStandardFilter) { *
  • Set a generated value for {@code info.title} if none specified *
  • Set a generated value for {@code info.version} if none specified *
  • Set a default value for {@code openapi} (the specification - * version) if none specified. E.g. 3.0.3 + * version) if none specified. E.g. 3.1.0 * * * @param defaultRequiredProperties @@ -585,7 +585,7 @@ public Schema parseSchema(String jsonSchema) { .map(parser -> parser.apply(jsonSchema)) .orElseGet(() -> { V schemaModel = modelIO.jsonIO().fromString(jsonSchema, Format.JSON); - return modelIO.schemas().readValue(schemaModel); + return modelIO.schemaIO().readValue(schemaModel); }); } }; diff --git a/core/src/main/java/io/smallrye/openapi/api/models/ComponentsImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/ComponentsImpl.java index cceb4e47c..aad573f24 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/ComponentsImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/ComponentsImpl.java @@ -4,6 +4,7 @@ import java.util.Map; import org.eclipse.microprofile.openapi.models.Components; +import org.eclipse.microprofile.openapi.models.PathItem; import org.eclipse.microprofile.openapi.models.callbacks.Callback; import org.eclipse.microprofile.openapi.models.examples.Example; import org.eclipse.microprofile.openapi.models.headers.Header; @@ -30,6 +31,7 @@ public class ComponentsImpl extends ExtensibleImpl implements Compon private Map securitySchemes; private Map links; private Map callbacks; + private Map pathItems; /** * @see org.eclipse.microprofile.openapi.models.Components#getSchemas() @@ -338,4 +340,25 @@ public void removeCallback(String key) { ModelUtil.remove(this.callbacks, key); } + @Override + public Map getPathItems() { + return ModelUtil.unmodifiableMap(this.pathItems); + } + + @Override + public void setPathItems(Map pathItems) { + this.pathItems = ModelUtil.replace(pathItems, LinkedHashMap::new); + } + + @Override + public Components addPathItem(String name, PathItem pathItem) { + this.pathItems = ModelUtil.add(name, pathItem, this.pathItems, LinkedHashMap::new); + return this; + } + + @Override + public void removePathItem(String name) { + ModelUtil.remove(this.pathItems, name); + } + } \ No newline at end of file diff --git a/core/src/main/java/io/smallrye/openapi/api/models/MapBasedModelImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/MapBasedModelImpl.java new file mode 100644 index 000000000..593191f76 --- /dev/null +++ b/core/src/main/java/io/smallrye/openapi/api/models/MapBasedModelImpl.java @@ -0,0 +1,180 @@ +package io.smallrye.openapi.api.models; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import io.smallrye.openapi.api.util.MergeUtil; +import io.smallrye.openapi.runtime.util.ModelUtil; + +/** + * Base implementation for extensible model objects which wrap a map of properties + */ +public abstract class MapBasedModelImpl implements ModelImpl { + + protected final LinkedHashMap data = new LinkedHashMap<>(); + + protected MapBasedModelImpl() { + } + + /** + * Merge all properties from another map-based model object into this one + *

    + * Usually this method will return {@code this}, but it may return {@code other} or a new object. + * + * @param other the other map-based model object + * @return the merged object + */ + public MapBasedModelImpl mergeFrom(MapBasedModelImpl other) { + mergeMap(data, other.data, getNonMergableCollections()); + return this; + } + + public Map getDataMap() { + return data; + } + + private static void mergeMap(Map into, Map from, Set nonMergableNames) { + for (Entry entry : from.entrySet()) { + String name = entry.getKey(); + T value = entry.getValue(); + T oldValue = into.get(entry.getKey()); + if (oldValue == null || oldValue.getClass() != value.getClass()) { + into.put(name, value); + } else { + if (oldValue instanceof Map && !nonMergableNames.contains(name)) { + mergeMap((Map) oldValue, (Map) value, nonMergableNames); + } else if (oldValue instanceof List && !nonMergableNames.contains(name)) { + mergeList((List) oldValue, (List) value); + } else if (oldValue instanceof ModelImpl) { + into.put(name, MergeUtil.mergeObjects(oldValue, value)); + } else { + into.put(name, value); + } + } + } + } + + private static void mergeList(List oldValue, List value) { + Set contents = new HashSet<>(oldValue); + for (T element : value) { + if (!contents.contains(element)) { + oldValue.add(element); + } + } + } + + protected void setProperty(String propertyName, T value) { + if (value == null) { + data.remove(propertyName); + } else { + data.put(propertyName, value); + } + } + + protected T getProperty(String propertyName, Class type) { + Object result = data.get(propertyName); + if (type.isInstance(result)) { + return type.cast(result); + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + protected List getListProperty(String propertyName) { + Object result = data.get(propertyName); + if (result instanceof List) { + return Collections.unmodifiableList((List) result); + } else { + return null; + } + } + + protected void setListProperty(String propertyName, List value) { + value = ModelUtil.replace(value, ArrayList::new); + if (value == null) { + data.remove(propertyName); + } else { + data.put(propertyName, value); + } + } + + protected void addToListProperty(String propertyName, T value) { + if (value != null) { + Object existing = data.get(propertyName); + List list; + if (existing instanceof List) { + list = (List) existing; + } else { + list = new ArrayList<>(); + data.put(propertyName, list); + } + list.add(value); + } + } + + protected void removeFromListProperty(String propertyName, T toRemove) { + Object existing = data.get(propertyName); + if (existing instanceof List) { + List list = (List) existing; + ModelUtil.remove(list, toRemove); + } + } + + protected void setMapProperty(String propertyName, Map value) { + value = ModelUtil.replace(value, HashMap::new); + if (value == null) { + data.remove(propertyName); + } else { + data.put(propertyName, value); + } + } + + protected Map getMapProperty(String propertyName) { + Object result = data.get(propertyName); + if (result instanceof Map) { + return Collections.unmodifiableMap((Map) data.get(propertyName)); + } else { + return null; + } + } + + protected void addToMapProperty(String propertyName, String key, T value) { + if (value != null) { + Object existing = data.get(propertyName); + Map map; + if (existing instanceof Map) { + map = (Map) existing; + } else { + map = new HashMap<>(); + data.put(propertyName, map); + } + map.put(key, value); + } + } + + protected void removeFromMapProperty(String propertyName, String key) { + Object existing = data.get(propertyName); + if (existing instanceof Map) { + Map map = (Map) existing; + ModelUtil.remove(map, key); + } + } + + /** + * Return a list of properties whose values should not be merged even if they're collections + * + * @return a list of properties which should be overwritten rather than merged + */ + protected Set getNonMergableCollections() { + return Collections.emptySet(); + } + +} diff --git a/core/src/main/java/io/smallrye/openapi/api/models/OpenAPIImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/OpenAPIImpl.java index 93afcd468..4603b37da 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/OpenAPIImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/OpenAPIImpl.java @@ -1,11 +1,14 @@ package io.smallrye.openapi.api.models; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.eclipse.microprofile.openapi.models.Components; import org.eclipse.microprofile.openapi.models.ExternalDocumentation; import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; import org.eclipse.microprofile.openapi.models.Paths; import org.eclipse.microprofile.openapi.models.info.Info; import org.eclipse.microprofile.openapi.models.security.SecurityRequirement; @@ -26,6 +29,7 @@ public class OpenAPIImpl extends ExtensibleImpl implements OpenAPI, Mod private List security; private List tags; private Paths paths; + private Map webhooks; private Components components; /** @@ -226,4 +230,25 @@ public Components getComponents() { public void setComponents(Components components) { this.components = components; } + + @Override + public Map getWebhooks() { + return ModelUtil.unmodifiableMap(this.webhooks); + } + + @Override + public void setWebhooks(Map webhooks) { + this.webhooks = ModelUtil.replace(webhooks, LinkedHashMap::new); + } + + @Override + public OpenAPI addWebhook(String name, PathItem webhook) { + this.webhooks = ModelUtil.add(name, webhook, this.webhooks, LinkedHashMap::new); + return this; + } + + @Override + public void removeWebhook(String name) { + ModelUtil.remove(this.webhooks, name); + } } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/PathItemImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/PathItemImpl.java index 851318635..32cd6aa11 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/PathItemImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/PathItemImpl.java @@ -10,6 +10,7 @@ import org.eclipse.microprofile.openapi.models.parameters.Parameter; import org.eclipse.microprofile.openapi.models.servers.Server; +import io.smallrye.openapi.runtime.io.ReferenceType; import io.smallrye.openapi.runtime.util.ModelUtil; /** @@ -44,6 +45,9 @@ public String getRef() { */ @Override public void setRef(String ref) { + if (ref != null && !ref.contains("/")) { + ref = ReferenceType.PATH_ITEM.referenceOf(ref); + } this.ref = ref; } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/info/InfoImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/info/InfoImpl.java index ba6166f67..9ae44521f 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/info/InfoImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/info/InfoImpl.java @@ -18,6 +18,7 @@ public class InfoImpl extends ExtensibleImpl implements Info, ModelImpl { private Contact contact; private License license; private String version; + private String summary; /** * @see org.eclipse.microprofile.openapi.models.info.Info#getTitle() @@ -115,4 +116,20 @@ public void setVersion(String version) { this.version = version; } + /** + * @see org.eclipse.microprofile.openapi.models.info.Info#getSummary() + */ + @Override + public String getSummary() { + return summary; + } + + /** + * @see org.eclipse.microprofile.openapi.models.info.Info#setSummary(java.lang.String) + */ + @Override + public void setSummary(String summary) { + this.summary = summary; + } + } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/info/LicenseImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/info/LicenseImpl.java index 90591f7cd..bd41d7867 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/info/LicenseImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/info/LicenseImpl.java @@ -12,6 +12,7 @@ public class LicenseImpl extends ExtensibleImpl implements License, Mod private String name; private String url; + private String identifier; /** * @see org.eclipse.microprofile.openapi.models.info.License#getName() @@ -45,4 +46,20 @@ public void setUrl(String url) { this.url = url; } + /** + * @see org.eclipse.microprofile.openapi.models.info.License#getIdentifier() + */ + @Override + public String getIdentifier() { + return this.identifier; + } + + /** + * @see org.eclipse.microprofile.openapi.models.info.License#setIdentifier(java.lang.String) + */ + @Override + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/media/SchemaImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/media/SchemaImpl.java index 65d139c18..7f5c898df 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/media/SchemaImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/media/SchemaImpl.java @@ -1,72 +1,123 @@ package io.smallrye.openapi.api.models.media; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ADDITIONAL_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ALL_OF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ANY_OF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_COMMENT; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_CONST; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_CONTAINS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_CONTENT_ENCODING; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_CONTENT_MEDIA_TYPE; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_CONTENT_SCHEMA; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DEFAULT; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DEPENDENT_REQUIRED; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DEPENDENT_SCHEMAS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DEPRECATED; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DESCRIPTION; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_DISCRIMINATOR; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ELSE; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ENUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXAMPLE; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXAMPLES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXCLUSIVE_MAXIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXCLUSIVE_MINIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXTERNAL_DOCS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_FORMAT; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_IF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAXIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAX_CONTAINS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAX_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAX_LENGTH; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAX_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MINIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MIN_CONTAINS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MIN_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MIN_LENGTH; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MIN_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MULTIPLE_OF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_NOT; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_ONE_OF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_PATTERN; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_PATTERN_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_PREFIX_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_PROPERTY_NAMES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_READ_ONLY; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_REF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_REQUIRED; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_SCHEMA_DIALECT; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_THEN; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_TYPE; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_UNEVALUATED_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_UNEVALUATED_PROPERTIES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_UNIQUE_ITEMS; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_WRITE_ONLY; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_XML; + import java.math.BigDecimal; import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; -import java.util.stream.Collectors; +import java.util.Set; import org.eclipse.microprofile.openapi.models.ExternalDocumentation; import org.eclipse.microprofile.openapi.models.media.Discriminator; import org.eclipse.microprofile.openapi.models.media.Schema; import org.eclipse.microprofile.openapi.models.media.XML; -import io.smallrye.openapi.api.models.ExtensibleImpl; import io.smallrye.openapi.api.models.ExternalDocumentationImpl; +import io.smallrye.openapi.api.models.MapBasedModelImpl; import io.smallrye.openapi.api.models.ModelImpl; import io.smallrye.openapi.api.util.MergeUtil; import io.smallrye.openapi.runtime.io.ReferenceType; +import io.smallrye.openapi.runtime.io.schema.SchemaConstant; import io.smallrye.openapi.runtime.util.ModelUtil; /** * An implementation of the {@link Schema} OpenAPI model interface. */ -public class SchemaImpl extends ExtensibleImpl implements Schema, ModelImpl { - - private String ref; - private String format; - private final String name; - private String title; - private String description; - private Object defaultValue; - private BigDecimal multipleOf; - private BigDecimal maximum; - private Boolean exclusiveMaximum; - private BigDecimal minimum; - private Boolean exclusiveMinimum; - private Integer maxLength; - private Integer minLength; - private String pattern; - private Integer maxItems; - private Integer minItems; - private Boolean uniqueItems; - private Integer maxProperties; - private Integer minProperties; - private List required; - private List enumeration; - private SchemaType type; - private Schema items; - private List allOf; - private Map properties; - private Schema additionalPropertiesSchema; - private Boolean additionalPropertiesBoolean; - private Boolean readOnly; - private XML xml; - private ExternalDocumentation externalDocs; - private Object example; - private List oneOf; - private List anyOf; - private Schema not; - private Discriminator discriminator; - private Boolean nullable; - private Boolean writeOnly; - private Boolean deprecated; +public class SchemaImpl extends MapBasedModelImpl implements Schema, ModelImpl { + + private static final Set NON_MERGABLE_PROPERTIES = Collections.singleton(SchemaConstant.PROP_EXAMPLES); // Non-standard + private String name; private int modCount; private List typeObservers; + // Value set via setNullable, unless overwritten by call to setType(List) + private Boolean nullable = null; + // Whether user has explicitly added extensions + private boolean explicitSetExtensions = false; + + /** + * The boolean value of this schema. {@code null} in most cases where the schema is an object + */ + private Boolean booleanValue; + + @Override + protected Set getNonMergableCollections() { + return NON_MERGABLE_PROPERTIES; + } + + @Override + public MapBasedModelImpl mergeFrom(MapBasedModelImpl other) { + SchemaImpl otherSchema = null; + + // If either schema is a boolean, we don't merge and just return the other schema + if (this.isBooleanSchema()) { + return other; + } + if (other instanceof SchemaImpl && ((SchemaImpl) other).isBooleanSchema()) { + return otherSchema; + } + + // Otherwise we merge the trees + return super.mergeFrom(other); + } public static boolean isNamed(Schema schema) { return schema instanceof SchemaImpl && ((SchemaImpl) schema).name != null; @@ -82,61 +133,79 @@ public static void addTypeObserver(Schema observable, Schema observer) { obs.typeObservers = ModelUtil.add(observer, obs.typeObservers, ArrayList::new); } - observer.setType(observable.getType()); + setTypeRetainingNull(observer, observable.getType()); } public static SchemaImpl copyOf(Schema other) { - SchemaImpl clone = (SchemaImpl) MergeUtil.mergeObjects(new SchemaImpl(), other); - clone.required = copy(clone.required, () -> new ArrayList<>(clone.required)); - clone.enumeration = copy(clone.enumeration, () -> new ArrayList<>(clone.enumeration)); - clone.items = copy(clone.items, () -> copyOf(clone.items)); - - clone.allOf = copy(clone.allOf, () -> clone.allOf - .stream() - .map(SchemaImpl::copyOf) - .collect(Collectors.toList())); - - clone.properties = copy(clone.properties, () -> { - Map copiedProperties = new LinkedHashMap<>(clone.properties.size()); - clone.properties.forEach((k, v) -> copiedProperties.put(k, copyOf(v))); - return copiedProperties; - }); - - clone.additionalPropertiesSchema = copy(clone.additionalPropertiesSchema, - () -> copyOf(clone.additionalPropertiesSchema)); - - clone.xml = copy(clone.xml, () -> MergeUtil.mergeObjects(new XMLImpl(), clone.xml)); - clone.externalDocs = copy(clone.externalDocs, - () -> MergeUtil.mergeObjects(new ExternalDocumentationImpl(), clone.externalDocs)); - - clone.oneOf = copy(clone.oneOf, () -> clone.oneOf - .stream() - .map(SchemaImpl::copyOf) - .collect(Collectors.toList())); + if (other == null) { + return new SchemaImpl(); + } + if (other instanceof SchemaImpl) { + SchemaImpl otherImpl = (SchemaImpl) other; + SchemaImpl result = new SchemaImpl(); + result.data.putAll(copyOf(otherImpl.data)); + return result; + } + throw new UnsupportedOperationException("Can't copy a different impl"); + } - clone.anyOf = copy(clone.anyOf, () -> clone.anyOf - .stream() - .map(SchemaImpl::copyOf) - .collect(Collectors.toList())); + public static void clear(Schema schema) { + SchemaImpl impl = (SchemaImpl) schema; + impl.data.clear(); + impl.booleanValue = null; + } - clone.not = copy(clone.not, () -> copyOf(clone.not)); + private static Map copyOf(Map map) { + Map clone = new HashMap<>(); + for (Map.Entry entry : map.entrySet()) { + K key = entry.getKey(); + V val = entry.getValue(); + clone.put(key, copyOf(val)); + } + return clone; + } + private static List copyOf(List list) { + List clone = new ArrayList<>(); + for (T value : list) { + clone.add(copyOf(value)); + } return clone; } - private static T copy(T property, Supplier copySupplier) { - if (property != null) { - return copySupplier.get(); + private static T copyOf(T value) { + if (value instanceof Map) { + return (T) copyOf((Map) value); + } else if (value instanceof List) { + return (T) copyOf((List) value); + } else if (value instanceof Schema) { + return (T) copyOf((Schema) value); + } else if (value instanceof XML) { + return (T) MergeUtil.mergeObjects(new XMLImpl(), (XML) value); + } else if (value instanceof ExternalDocumentation) { + return (T) MergeUtil.mergeObjects(new ExternalDocumentationImpl(), (ExternalDocumentation) value); + } else if (value instanceof Discriminator) { + return (T) MergeUtil.mergeObjects(new DiscriminatorImpl(), (Discriminator) value); + } else { + return value; } - return null; } + /** + * Create an empty named schema + * + * @param name the name + */ public SchemaImpl(String name) { + super(); this.name = name; } + /** + * Create an empty schema + */ public SchemaImpl() { - this(null); + this((String) null); } public String getName() { @@ -147,12 +216,101 @@ private void incrementModCount() { modCount++; } + /** + * Implements the old logic of setType(SchemaType). + *

    + * {@link #setType(Schema, SchemaType)}, {@link #setNullable(Schema, Boolean)} and {@link #getNullable(Schema)} can + * be used together allow the type and nullability of a schema to be set separately by different parts of the + * scanning process, even though that information is now contained in one field. + */ + public static void setType(Schema schema, SchemaType type) { + if (!(schema instanceof SchemaImpl)) { + return; + } + + SchemaImpl s = (SchemaImpl) schema; + if (getNullable(schema) == Boolean.TRUE) { + if (type == null) { + s.setListProperty(PROP_TYPE, null); + } else { + s.setListProperty(PROP_TYPE, Arrays.asList(type, SchemaType.NULL)); + } + } else { + if (type == null) { + s.setListProperty(PROP_TYPE, null); + } else { + s.setListProperty(PROP_TYPE, Collections.singletonList(type)); + } + } + + if (s.typeObservers != null) { + s.typeObservers.forEach(o -> SchemaImpl.setType(o, type)); + } + } + + /** + * Implements the old logic of getNullable(). + *

    + * {@link #setType(Schema, SchemaType)}, {@link #setNullable(Schema, Boolean)} and {@link #getNullable(Schema)} can + * be used together allow the type and nullability of a schema to be set separately by different parts of the + * scanning process, even though that information is now contained in one field. + */ + public static Boolean getNullable(Schema schema) { + List types = schema.getType(); + + if (!(schema instanceof SchemaImpl)) { + return types != null && types.contains(SchemaType.NULL); + } + + SchemaImpl s = (SchemaImpl) schema; + + if (types != null) { + boolean nullPermitted = types.contains(SchemaType.NULL); + // Retain old tri-state behaviour of getNullable + // If setNullable has not been called and null is not permitted, return null rather than false + if (!nullPermitted && s.nullable == null) { + return null; + } else { + return nullPermitted; + } + } else { + // If types is unset, return any value passed to setNullable + return s.nullable; + } + } + + /** + * Implements the old logic of setNullable(Boolean). + *

    + * {@link #setType(Schema, SchemaType)}, {@link #setNullable(Schema, Boolean)} and {@link #getNullable(Schema)} can + * be used together allow the type and nullability of a schema to be set separately by different parts of the + * scanning process, even though that information is now contained in one field. + */ + public static void setNullable(Schema schema, Boolean nullable) { + if (!(schema instanceof SchemaImpl)) { + return; + } + + SchemaImpl s = (SchemaImpl) schema; + + s.incrementModCount(); + s.nullable = nullable; + if (nullable == Boolean.TRUE) { + List types = s.getType(); + if (types != null && !types.contains(SchemaType.NULL)) { + s.addType(SchemaType.NULL); + } + } else { + s.removeType(SchemaType.NULL); + } + } + /** * @see org.eclipse.microprofile.openapi.models.Reference#getRef() */ @Override public String getRef() { - return this.ref; + return getProperty(PROP_REF, String.class); } /** @@ -163,8 +321,7 @@ public void setRef(String ref) { if (ref != null && !ref.contains("/")) { ref = ReferenceType.SCHEMA.referenceOf(ref); } - incrementModCount(); - this.ref = ref; + setProperty(PROP_REF, ref); } /** @@ -172,7 +329,7 @@ public void setRef(String ref) { */ @Override public Discriminator getDiscriminator() { - return this.discriminator; + return getProperty(PROP_DISCRIMINATOR, Discriminator.class); } /** @@ -180,8 +337,7 @@ public Discriminator getDiscriminator() { */ @Override public void setDiscriminator(Discriminator discriminator) { - incrementModCount(); - this.discriminator = discriminator; + setProperty(PROP_DISCRIMINATOR, discriminator); } /** @@ -189,7 +345,7 @@ public void setDiscriminator(Discriminator discriminator) { */ @Override public String getTitle() { - return this.title; + return getProperty(SchemaConstant.PROP_TITLE, String.class); } /** @@ -197,8 +353,7 @@ public String getTitle() { */ @Override public void setTitle(String title) { - incrementModCount(); - this.title = title; + setProperty(SchemaConstant.PROP_TITLE, title); } /** @@ -206,7 +361,7 @@ public void setTitle(String title) { */ @Override public Object getDefaultValue() { - return this.defaultValue; + return getProperty(PROP_DEFAULT, Object.class); } /** @@ -214,8 +369,7 @@ public Object getDefaultValue() { */ @Override public void setDefaultValue(Object defaultValue) { - incrementModCount(); - this.defaultValue = defaultValue; + setProperty(SchemaConstant.PROP_DEFAULT, defaultValue); } /** @@ -223,7 +377,7 @@ public void setDefaultValue(Object defaultValue) { */ @Override public List getEnumeration() { - return ModelUtil.unmodifiableList(this.enumeration); + return getListProperty(PROP_ENUM); } /** @@ -231,8 +385,7 @@ public List getEnumeration() { */ @Override public void setEnumeration(List enumeration) { - incrementModCount(); - this.enumeration = ModelUtil.replace(enumeration, ArrayList::new); + setListProperty(PROP_ENUM, enumeration); } /** @@ -240,8 +393,7 @@ public void setEnumeration(List enumeration) { */ @Override public Schema addEnumeration(Object enumeration) { - incrementModCount(); - this.enumeration = ModelUtil.add(enumeration, this.enumeration, ArrayList::new); + addToListProperty(PROP_ENUM, enumeration); return this; } @@ -250,8 +402,7 @@ public Schema addEnumeration(Object enumeration) { */ @Override public void removeEnumeration(Object enumeration) { - incrementModCount(); - ModelUtil.remove(this.enumeration, enumeration); + removeFromListProperty(PROP_ENUM, enumeration); } /** @@ -259,7 +410,7 @@ public void removeEnumeration(Object enumeration) { */ @Override public BigDecimal getMultipleOf() { - return this.multipleOf; + return getProperty(PROP_MULTIPLE_OF, BigDecimal.class); } /** @@ -267,8 +418,7 @@ public BigDecimal getMultipleOf() { */ @Override public void setMultipleOf(BigDecimal multipleOf) { - incrementModCount(); - this.multipleOf = multipleOf; + setProperty(PROP_MULTIPLE_OF, multipleOf); } /** @@ -276,7 +426,7 @@ public void setMultipleOf(BigDecimal multipleOf) { */ @Override public BigDecimal getMaximum() { - return this.maximum; + return getProperty(PROP_MAXIMUM, BigDecimal.class); } /** @@ -284,25 +434,23 @@ public BigDecimal getMaximum() { */ @Override public void setMaximum(BigDecimal maximum) { - incrementModCount(); - this.maximum = maximum; + setProperty(PROP_MAXIMUM, maximum); } /** * @see org.eclipse.microprofile.openapi.models.media.Schema#getExclusiveMaximum() */ @Override - public Boolean getExclusiveMaximum() { - return this.exclusiveMaximum; + public BigDecimal getExclusiveMaximum() { + return getProperty(PROP_EXCLUSIVE_MAXIMUM, BigDecimal.class); } /** - * @see org.eclipse.microprofile.openapi.models.media.Schema#setExclusiveMaximum(java.lang.Boolean) + * @see org.eclipse.microprofile.openapi.models.media.Schema#setExclusiveMaximum(java.math.BigDecimal) */ @Override - public void setExclusiveMaximum(Boolean exclusiveMaximum) { - incrementModCount(); - this.exclusiveMaximum = exclusiveMaximum; + public void setExclusiveMaximum(BigDecimal exclusiveMaximum) { + setProperty(PROP_EXCLUSIVE_MAXIMUM, exclusiveMaximum); } /** @@ -310,7 +458,7 @@ public void setExclusiveMaximum(Boolean exclusiveMaximum) { */ @Override public BigDecimal getMinimum() { - return this.minimum; + return getProperty(PROP_MINIMUM, BigDecimal.class); } /** @@ -318,25 +466,23 @@ public BigDecimal getMinimum() { */ @Override public void setMinimum(BigDecimal minimum) { - incrementModCount(); - this.minimum = minimum; + setProperty(PROP_MINIMUM, minimum); } /** * @see org.eclipse.microprofile.openapi.models.media.Schema#getExclusiveMinimum() */ @Override - public Boolean getExclusiveMinimum() { - return this.exclusiveMinimum; + public BigDecimal getExclusiveMinimum() { + return getProperty(PROP_EXCLUSIVE_MINIMUM, BigDecimal.class); } /** - * @see org.eclipse.microprofile.openapi.models.media.Schema#setExclusiveMinimum(java.lang.Boolean) + * @see org.eclipse.microprofile.openapi.models.media.Schema#setExclusiveMinimum(java.math.BigDecimal) */ @Override - public void setExclusiveMinimum(Boolean exclusiveMinimum) { - incrementModCount(); - this.exclusiveMinimum = exclusiveMinimum; + public void setExclusiveMinimum(BigDecimal exclusiveMinimum) { + setProperty(PROP_EXCLUSIVE_MINIMUM, exclusiveMinimum); } /** @@ -344,7 +490,7 @@ public void setExclusiveMinimum(Boolean exclusiveMinimum) { */ @Override public Integer getMaxLength() { - return this.maxLength; + return getProperty(PROP_MAX_LENGTH, Integer.class); } /** @@ -352,8 +498,7 @@ public Integer getMaxLength() { */ @Override public void setMaxLength(Integer maxLength) { - incrementModCount(); - this.maxLength = maxLength; + setProperty(PROP_MAX_LENGTH, maxLength); } /** @@ -361,7 +506,7 @@ public void setMaxLength(Integer maxLength) { */ @Override public Integer getMinLength() { - return this.minLength; + return getProperty(PROP_MIN_LENGTH, Integer.class); } /** @@ -369,8 +514,7 @@ public Integer getMinLength() { */ @Override public void setMinLength(Integer minLength) { - incrementModCount(); - this.minLength = minLength; + setProperty(PROP_MIN_LENGTH, minLength); } /** @@ -378,7 +522,7 @@ public void setMinLength(Integer minLength) { */ @Override public String getPattern() { - return this.pattern; + return getProperty(PROP_PATTERN, String.class); } /** @@ -386,8 +530,7 @@ public String getPattern() { */ @Override public void setPattern(String pattern) { - incrementModCount(); - this.pattern = pattern; + setProperty(PROP_PATTERN, pattern); } /** @@ -395,7 +538,7 @@ public void setPattern(String pattern) { */ @Override public Integer getMaxItems() { - return this.maxItems; + return getProperty(PROP_MAX_ITEMS, Integer.class); } /** @@ -403,8 +546,7 @@ public Integer getMaxItems() { */ @Override public void setMaxItems(Integer maxItems) { - incrementModCount(); - this.maxItems = maxItems; + setProperty(PROP_MAX_ITEMS, maxItems); } /** @@ -412,7 +554,7 @@ public void setMaxItems(Integer maxItems) { */ @Override public Integer getMinItems() { - return this.minItems; + return getProperty(PROP_MIN_ITEMS, Integer.class); } /** @@ -420,8 +562,7 @@ public Integer getMinItems() { */ @Override public void setMinItems(Integer minItems) { - incrementModCount(); - this.minItems = minItems; + setProperty(PROP_MIN_ITEMS, minItems); } /** @@ -429,7 +570,7 @@ public void setMinItems(Integer minItems) { */ @Override public Boolean getUniqueItems() { - return this.uniqueItems; + return getProperty(PROP_UNIQUE_ITEMS, Boolean.class); } /** @@ -437,8 +578,7 @@ public Boolean getUniqueItems() { */ @Override public void setUniqueItems(Boolean uniqueItems) { - incrementModCount(); - this.uniqueItems = uniqueItems; + setProperty(PROP_UNIQUE_ITEMS, uniqueItems); } /** @@ -446,7 +586,7 @@ public void setUniqueItems(Boolean uniqueItems) { */ @Override public Integer getMaxProperties() { - return this.maxProperties; + return getProperty(PROP_MAX_PROPERTIES, Integer.class); } /** @@ -454,8 +594,7 @@ public Integer getMaxProperties() { */ @Override public void setMaxProperties(Integer maxProperties) { - incrementModCount(); - this.maxProperties = maxProperties; + setProperty(PROP_MAX_PROPERTIES, maxProperties); } /** @@ -463,7 +602,7 @@ public void setMaxProperties(Integer maxProperties) { */ @Override public Integer getMinProperties() { - return this.minProperties; + return getProperty(PROP_MIN_PROPERTIES, Integer.class); } /** @@ -471,8 +610,7 @@ public Integer getMinProperties() { */ @Override public void setMinProperties(Integer minProperties) { - incrementModCount(); - this.minProperties = minProperties; + setProperty(PROP_MIN_PROPERTIES, minProperties); } /** @@ -480,7 +618,7 @@ public void setMinProperties(Integer minProperties) { */ @Override public List getRequired() { - return ModelUtil.unmodifiableList(this.required); + return getListProperty(PROP_REQUIRED); } /** @@ -488,8 +626,7 @@ public List getRequired() { */ @Override public void setRequired(List required) { - incrementModCount(); - this.required = ModelUtil.replace(required, ArrayList::new); + setListProperty(PROP_REQUIRED, required); } /** @@ -497,8 +634,7 @@ public void setRequired(List required) { */ @Override public Schema addRequired(String required) { - incrementModCount(); - this.required = ModelUtil.add(required, this.required, ArrayList::new); + addToListProperty(PROP_REQUIRED, required); return this; } @@ -507,28 +643,65 @@ public Schema addRequired(String required) { */ @Override public void removeRequired(String required) { - incrementModCount(); - ModelUtil.remove(this.required, required); + removeFromListProperty(PROP_REQUIRED, required); } /** * @see org.eclipse.microprofile.openapi.models.media.Schema#getType() */ @Override - public SchemaType getType() { - return this.type; + public List getType() { + List resultList = getListProperty(PROP_TYPE); + if (resultList != null) { + return resultList; + } + + SchemaType result = getProperty(PROP_TYPE, SchemaType.class); + if (result != null) { + return Collections.singletonList(result); + } + + return null; } - /** - * @see org.eclipse.microprofile.openapi.models.media.Schema#setType(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType) - */ @Override - public void setType(SchemaType type) { - incrementModCount(); - this.type = type; + public void setType(List types) { + nullable = null; + setListProperty(PROP_TYPE, types); if (typeObservers != null) { - typeObservers.forEach(o -> o.setType(type)); + typeObservers.forEach(o -> setTypeRetainingNull(o, types)); + } + } + + private static void setTypeRetainingNull(Schema target, List types) { + // Set types on the observer, but retain null if it was set on the observer + List oldTypes = target.getType(); + if (oldTypes != null && types != null + && oldTypes.contains(SchemaType.NULL) + && !types.contains(SchemaType.NULL)) { + types = new ArrayList(types); + types.add(SchemaType.NULL); + } + target.setType(types); + } + + @Override + public Schema addType(SchemaType type) { + addToListProperty(PROP_TYPE, type); + + if (typeObservers != null) { + typeObservers.forEach(o -> o.addType(type)); + } + return this; + } + + @Override + public void removeType(SchemaType type) { + removeFromListProperty(PROP_TYPE, type); + + if (typeObservers != null) { + typeObservers.forEach(o -> o.removeType(type)); } } @@ -537,7 +710,7 @@ public void setType(SchemaType type) { */ @Override public Schema getNot() { - return this.not; + return getProperty(PROP_NOT, Schema.class); } /** @@ -545,8 +718,7 @@ public Schema getNot() { */ @Override public void setNot(Schema not) { - incrementModCount(); - this.not = not; + setProperty(PROP_NOT, not); } /** @@ -554,7 +726,7 @@ public void setNot(Schema not) { */ @Override public Map getProperties() { - return ModelUtil.unmodifiableMap(this.properties); + return getMapProperty(PROP_PROPERTIES); } /** @@ -562,8 +734,7 @@ public Map getProperties() { */ @Override public void setProperties(Map properties) { - incrementModCount(); - this.properties = ModelUtil.replace(properties, LinkedHashMap::new); + setMapProperty(PROP_PROPERTIES, properties); } /** @@ -572,8 +743,7 @@ public void setProperties(Map properties) { */ @Override public Schema addProperty(String key, Schema propertySchema) { - incrementModCount(); - this.properties = ModelUtil.add(key, propertySchema, this.properties, LinkedHashMap::new); + addToMapProperty(PROP_PROPERTIES, key, propertySchema); return this; } @@ -582,18 +752,18 @@ public Schema addProperty(String key, Schema propertySchema) { */ @Override public void removeProperty(String key) { - incrementModCount(); - ModelUtil.remove(this.properties, key); + removeFromMapProperty(PROP_PROPERTIES, key); } @Override public Schema getAdditionalPropertiesSchema() { - return this.additionalPropertiesSchema; + return getProperty(PROP_ADDITIONAL_PROPERTIES, Schema.class); } @Override public Boolean getAdditionalPropertiesBoolean() { - return this.additionalPropertiesBoolean; + Schema additionalPropertiesSchema = getAdditionalPropertiesSchema(); + return additionalPropertiesSchema == null ? null : additionalPropertiesSchema.getBooleanSchema(); } /** @@ -601,9 +771,7 @@ public Boolean getAdditionalPropertiesBoolean() { */ @Override public void setAdditionalPropertiesSchema(Schema additionalProperties) { - incrementModCount(); - this.additionalPropertiesBoolean = null; - this.additionalPropertiesSchema = additionalProperties; + setProperty(PROP_ADDITIONAL_PROPERTIES, additionalProperties); } /** @@ -611,9 +779,11 @@ public void setAdditionalPropertiesSchema(Schema additionalProperties) { */ @Override public void setAdditionalPropertiesBoolean(Boolean additionalProperties) { - incrementModCount(); - this.additionalPropertiesSchema = null; - this.additionalPropertiesBoolean = additionalProperties; + if (additionalProperties != null) { + setAdditionalPropertiesSchema(new SchemaImpl().booleanSchema(additionalProperties)); + } else { + setAdditionalPropertiesSchema(null); + } } /** @@ -621,7 +791,7 @@ public void setAdditionalPropertiesBoolean(Boolean additionalProperties) { */ @Override public String getDescription() { - return this.description; + return getProperty(PROP_DESCRIPTION, String.class); } /** @@ -629,8 +799,7 @@ public String getDescription() { */ @Override public void setDescription(String description) { - incrementModCount(); - this.description = description; + setProperty(PROP_DESCRIPTION, description); } /** @@ -638,7 +807,7 @@ public void setDescription(String description) { */ @Override public String getFormat() { - return this.format; + return getProperty(PROP_FORMAT, String.class); } /** @@ -646,25 +815,7 @@ public String getFormat() { */ @Override public void setFormat(String format) { - incrementModCount(); - this.format = format; - } - - /** - * @see org.eclipse.microprofile.openapi.models.media.Schema#getNullable() - */ - @Override - public Boolean getNullable() { - return this.nullable; - } - - /** - * @see org.eclipse.microprofile.openapi.models.media.Schema#setNullable(java.lang.Boolean) - */ - @Override - public void setNullable(Boolean nullable) { - incrementModCount(); - this.nullable = nullable; + setProperty(PROP_FORMAT, format); } /** @@ -672,7 +823,7 @@ public void setNullable(Boolean nullable) { */ @Override public Boolean getReadOnly() { - return this.readOnly; + return getProperty(PROP_READ_ONLY, Boolean.class); } /** @@ -680,8 +831,7 @@ public Boolean getReadOnly() { */ @Override public void setReadOnly(Boolean readOnly) { - incrementModCount(); - this.readOnly = readOnly; + setProperty(PROP_READ_ONLY, readOnly); } /** @@ -689,7 +839,7 @@ public void setReadOnly(Boolean readOnly) { */ @Override public Boolean getWriteOnly() { - return this.writeOnly; + return getProperty(PROP_WRITE_ONLY, Boolean.class); } /** @@ -697,8 +847,7 @@ public Boolean getWriteOnly() { */ @Override public void setWriteOnly(Boolean writeOnly) { - incrementModCount(); - this.writeOnly = writeOnly; + setProperty(PROP_WRITE_ONLY, writeOnly); } /** @@ -706,7 +855,7 @@ public void setWriteOnly(Boolean writeOnly) { */ @Override public Object getExample() { - return this.example; + return getProperty(PROP_EXAMPLE, Object.class); } /** @@ -714,8 +863,7 @@ public Object getExample() { */ @Override public void setExample(Object example) { - incrementModCount(); - this.example = example; + setProperty(PROP_EXAMPLE, example); } /** @@ -723,7 +871,7 @@ public void setExample(Object example) { */ @Override public ExternalDocumentation getExternalDocs() { - return this.externalDocs; + return getProperty(PROP_EXTERNAL_DOCS, ExternalDocumentation.class); } /** @@ -731,8 +879,7 @@ public ExternalDocumentation getExternalDocs() { */ @Override public void setExternalDocs(ExternalDocumentation externalDocs) { - incrementModCount(); - this.externalDocs = externalDocs; + setProperty(PROP_EXTERNAL_DOCS, externalDocs); } /** @@ -740,7 +887,7 @@ public void setExternalDocs(ExternalDocumentation externalDocs) { */ @Override public Boolean getDeprecated() { - return this.deprecated; + return getProperty(PROP_DEPRECATED, Boolean.class); } /** @@ -748,8 +895,7 @@ public Boolean getDeprecated() { */ @Override public void setDeprecated(Boolean deprecated) { - incrementModCount(); - this.deprecated = deprecated; + setProperty(PROP_DEPRECATED, deprecated); } /** @@ -757,7 +903,7 @@ public void setDeprecated(Boolean deprecated) { */ @Override public XML getXml() { - return this.xml; + return getProperty(PROP_XML, XML.class); } /** @@ -765,8 +911,7 @@ public XML getXml() { */ @Override public void setXml(XML xml) { - incrementModCount(); - this.xml = xml; + setProperty(PROP_XML, xml); } /** @@ -774,7 +919,7 @@ public void setXml(XML xml) { */ @Override public Schema getItems() { - return this.items; + return getProperty(PROP_ITEMS, Schema.class); } /** @@ -782,8 +927,7 @@ public Schema getItems() { */ @Override public void setItems(Schema items) { - incrementModCount(); - this.items = items; + setProperty(PROP_ITEMS, items); } /** @@ -791,7 +935,7 @@ public void setItems(Schema items) { */ @Override public List getAllOf() { - return ModelUtil.unmodifiableList(this.allOf); + return getListProperty(PROP_ALL_OF); } /** @@ -799,8 +943,7 @@ public List getAllOf() { */ @Override public void setAllOf(List allOf) { - incrementModCount(); - this.allOf = ModelUtil.replace(allOf, ArrayList::new); + setListProperty(PROP_ALL_OF, allOf); } /** @@ -808,8 +951,7 @@ public void setAllOf(List allOf) { */ @Override public Schema addAllOf(Schema allOf) { - incrementModCount(); - this.allOf = ModelUtil.add(allOf, this.allOf, ArrayList::new); + addToListProperty(PROP_ALL_OF, allOf); return this; } @@ -818,8 +960,7 @@ public Schema addAllOf(Schema allOf) { */ @Override public void removeAllOf(Schema allOf) { - incrementModCount(); - ModelUtil.remove(this.allOf, allOf); + removeFromListProperty(PROP_ALL_OF, allOf); } /** @@ -827,7 +968,7 @@ public void removeAllOf(Schema allOf) { */ @Override public List getAnyOf() { - return ModelUtil.unmodifiableList(this.anyOf); + return getListProperty(PROP_ANY_OF); } /** @@ -835,8 +976,7 @@ public List getAnyOf() { */ @Override public void setAnyOf(List anyOf) { - incrementModCount(); - this.anyOf = ModelUtil.replace(anyOf, ArrayList::new); + setListProperty(PROP_ANY_OF, anyOf); } /** @@ -844,8 +984,7 @@ public void setAnyOf(List anyOf) { */ @Override public Schema addAnyOf(Schema anyOf) { - incrementModCount(); - this.anyOf = ModelUtil.add(anyOf, this.anyOf, ArrayList::new); + addToListProperty(PROP_ANY_OF, anyOf); return this; } @@ -854,8 +993,7 @@ public Schema addAnyOf(Schema anyOf) { */ @Override public void removeAnyOf(Schema anyOf) { - incrementModCount(); - ModelUtil.remove(this.anyOf, anyOf); + removeFromListProperty(PROP_ANY_OF, anyOf); } /** @@ -863,7 +1001,7 @@ public void removeAnyOf(Schema anyOf) { */ @Override public List getOneOf() { - return ModelUtil.unmodifiableList(this.oneOf); + return getListProperty(PROP_ONE_OF); } /** @@ -871,8 +1009,7 @@ public List getOneOf() { */ @Override public void setOneOf(List oneOf) { - incrementModCount(); - this.oneOf = ModelUtil.replace(oneOf, ArrayList::new); + setListProperty(PROP_ONE_OF, oneOf); } /** @@ -880,8 +1017,7 @@ public void setOneOf(List oneOf) { */ @Override public Schema addOneOf(Schema oneOf) { - incrementModCount(); - this.oneOf = ModelUtil.add(oneOf, this.oneOf, ArrayList::new); + addToListProperty(PROP_ONE_OF, oneOf); return this; } @@ -890,8 +1026,430 @@ public Schema addOneOf(Schema oneOf) { */ @Override public void removeOneOf(Schema oneOf) { + removeFromListProperty(PROP_ONE_OF, oneOf); + } + + @Override + public Map getExtensions() { + Map extensions = new HashMap<>(); + data.forEach((k, v) -> { + if (k.startsWith("x-")) { + extensions.put(k, v); + } + }); + return extensions.isEmpty() && !explicitSetExtensions ? null : extensions; + } + + @Override + public Schema addExtension(String name, Object value) { + setProperty(name, value); + explicitSetExtensions = true; + return this; + } + + @Override + public void removeExtension(String name) { + setProperty(name, null); + } + + @Override + public void setExtensions(Map extensions) { + assertObjectSchema(); + + // Remove all extension fields + data.keySet().removeIf(k -> k.startsWith("x-")); + + // Add all the new extensions + if (extensions != null) { + explicitSetExtensions = true; + extensions.forEach((k, v) -> { + k = k.startsWith("x-") ? k : "x-" + k; + setProperty(k, v); + }); + } else { + explicitSetExtensions = false; + } + } + + @Override + public String getSchemaDialect() { + return getProperty(PROP_SCHEMA_DIALECT, String.class); + } + + @Override + public void setSchemaDialect(String schemaDialect) { + setProperty(PROP_SCHEMA_DIALECT, schemaDialect); + } + + @Override + public String getComment() { + return getProperty(PROP_COMMENT, String.class); + } + + @Override + public void setComment(String comment) { + setProperty(PROP_COMMENT, comment); + } + + @Override + public Schema getIfSchema() { + return getProperty(PROP_IF, Schema.class); + } + + @Override + public void setIfSchema(Schema ifSchema) { + setProperty(PROP_IF, ifSchema); + } + + @Override + public Schema getThenSchema() { + return getProperty(PROP_THEN, Schema.class); + } + + @Override + public void setThenSchema(Schema thenSchema) { + setProperty(PROP_THEN, thenSchema); + } + + @Override + public Schema getElseSchema() { + return getProperty(PROP_ELSE, Schema.class); + } + + @Override + public void setElseSchema(Schema elseSchema) { + setProperty(PROP_ELSE, elseSchema); + } + + @Override + public Map getDependentSchemas() { + return getMapProperty(PROP_DEPENDENT_SCHEMAS); + } + + @Override + public void setDependentSchemas(Map dependentSchemas) { + setMapProperty(PROP_DEPENDENT_SCHEMAS, dependentSchemas); + } + + @Override + public Schema addDependentSchema(String propertyName, Schema schema) { + addToMapProperty(PROP_DEPENDENT_SCHEMAS, propertyName, schema); + return this; + } + + @Override + public void removeDependentSchema(String propertyName) { + removeFromMapProperty(PROP_DEPENDENT_SCHEMAS, propertyName); + } + + @Override + public List getPrefixItems() { + return getListProperty(PROP_PREFIX_ITEMS); + } + + @Override + public void setPrefixItems(List prefixItems) { + setListProperty(PROP_PREFIX_ITEMS, prefixItems); + } + + @Override + public Schema addPrefixItem(Schema prefixItem) { + addToListProperty(PROP_PREFIX_ITEMS, prefixItem); + return this; + } + + @Override + public void removePrefixItem(Schema prefixItem) { + removeFromListProperty(PROP_PREFIX_ITEMS, prefixItem); + } + + @Override + public Schema getContains() { + return getProperty(PROP_CONTAINS, Schema.class); + } + + @Override + public void setContains(Schema contains) { + setProperty(PROP_CONTAINS, contains); + } + + @Override + public Map getPatternProperties() { + return getMapProperty(PROP_PATTERN_PROPERTIES); + } + + @Override + public void setPatternProperties(Map patternProperties) { + setMapProperty(PROP_PATTERN_PROPERTIES, patternProperties); + } + + @Override + public Schema addPatternProperty(String regularExpression, Schema schema) { + addToMapProperty(PROP_PATTERN_PROPERTIES, regularExpression, schema); + return this; + } + + @Override + public void removePatternProperty(String regularExpression) { + removeFromMapProperty(PROP_PATTERN_PROPERTIES, regularExpression); + } + + @Override + public Schema getPropertyNames() { + return getProperty(PROP_PROPERTY_NAMES, Schema.class); + } + + @Override + public void setPropertyNames(Schema propertyNameSchema) { + setProperty(PROP_PROPERTY_NAMES, propertyNameSchema); + } + + @Override + public Schema getUnevaluatedItems() { + return getProperty(PROP_UNEVALUATED_ITEMS, Schema.class); + } + + @Override + public void setUnevaluatedItems(Schema unevaluatedItems) { + setProperty(PROP_UNEVALUATED_ITEMS, unevaluatedItems); + } + + @Override + public Schema getUnevaluatedProperties() { + return getProperty(PROP_UNEVALUATED_PROPERTIES, Schema.class); + } + + @Override + public void setUnevaluatedProperties(Schema unevaluatedProperties) { + setProperty(PROP_UNEVALUATED_PROPERTIES, unevaluatedProperties); + } + + @Override + public Object getConstValue() { + return getProperty(PROP_CONST, Object.class); + } + + @Override + public void setConstValue(Object constValue) { + setProperty(PROP_CONST, constValue); + } + + @Override + public Integer getMaxContains() { + return getProperty(PROP_MAX_CONTAINS, Integer.class); + } + + @Override + public void setMaxContains(Integer maxContains) { + setProperty(PROP_MAX_CONTAINS, maxContains); + } + + @Override + public Integer getMinContains() { + return getProperty(PROP_MIN_CONTAINS, Integer.class); + } + + @Override + public void setMinContains(Integer minContains) { + setProperty(PROP_MIN_CONTAINS, minContains); + } + + @Override + public Map> getDependentRequired() { + return getMapProperty(PROP_DEPENDENT_REQUIRED); + } + + @Override + public void setDependentRequired(Map> dependentRequired) { + setMapProperty(PROP_DEPENDENT_REQUIRED, dependentRequired); + } + + @Override + public Schema addDependentRequired(String propertyName, List additionalRequiredPropertyNames) { + addToMapProperty(PROP_DEPENDENT_REQUIRED, propertyName, additionalRequiredPropertyNames); + return this; + } + + @Override + public void removeDependentRequired(String propertyName) { + removeFromMapProperty(PROP_DEPENDENT_REQUIRED, propertyName); + } + + @Override + public String getContentEncoding() { + return getProperty(PROP_CONTENT_ENCODING, String.class); + } + + @Override + public void setContentEncoding(String contentEncoding) { + setProperty(PROP_CONTENT_ENCODING, contentEncoding); + } + + @Override + public String getContentMediaType() { + return getProperty(PROP_CONTENT_MEDIA_TYPE, String.class); + } + + @Override + public void setContentMediaType(String contentMediaType) { + setProperty(PROP_CONTENT_MEDIA_TYPE, contentMediaType); + } + + @Override + public Schema getContentSchema() { + return getProperty(PROP_CONTENT_SCHEMA, Schema.class); + } + + @Override + public void setContentSchema(Schema contentSchema) { + setProperty(PROP_CONTENT_SCHEMA, contentSchema); + } + + @Override + public Boolean getBooleanSchema() { + return booleanValue; + } + + @Override + public void setBooleanSchema(Boolean booleanSchema) { + incrementModCount(); + booleanValue = booleanSchema; + } + + @Override + public List getExamples() { + return getListProperty(PROP_EXAMPLES); + } + + @Override + public void setExamples(List examples) { + setListProperty(PROP_EXAMPLES, examples); + } + + @Override + public Schema addExample(Object example) { + addToListProperty(PROP_EXAMPLES, example); + return this; + } + + @Override + public void removeExample(Object example) { + removeFromListProperty(PROP_EXAMPLES, example); + } + + private boolean isBooleanSchema() { + return booleanValue != null; + } + + /** + * Asserts that the schema is not a boolean schema + * + * @throws UnsupportedOperationException if this schema is a boolean schema + */ + private void assertObjectSchema() throws UnsupportedOperationException { + if (isBooleanSchema()) { + throw new UnsupportedOperationException("Schema has a boolean value"); + } + } + + @Override + protected void setProperty(String propertyName, T value) { + assertObjectSchema(); + incrementModCount(); + super.setProperty(propertyName, value); + } + + @Override + protected T getProperty(String propertyName, Class clazz) { + if (isBooleanSchema()) { + return null; + } + return super.getProperty(propertyName, clazz); + } + + @Override + protected List getListProperty(String propertyName) { + if (isBooleanSchema()) { + return null; + } + return super.getListProperty(propertyName); + } + + @Override + protected void setListProperty(String propertyName, List value) { + assertObjectSchema(); + incrementModCount(); + super.setListProperty(propertyName, value); + } + + @Override + protected void addToListProperty(String propertyName, T value) { + assertObjectSchema(); incrementModCount(); - ModelUtil.remove(this.oneOf, oneOf); + super.addToListProperty(propertyName, value); + } + + @Override + protected void removeFromListProperty(String propertyName, T toRemove) { + if (!isBooleanSchema()) { + incrementModCount(); + super.removeFromListProperty(propertyName, toRemove); + } + } + + @Override + protected void setMapProperty(String propertyName, Map value) { + assertObjectSchema(); + incrementModCount(); + super.setMapProperty(propertyName, value); + } + + @Override + protected Map getMapProperty(String propertyName) { + if (isBooleanSchema()) { + return null; + } + return super.getMapProperty(propertyName); + } + + @Override + protected void addToMapProperty(String propertyName, String key, T value) { + assertObjectSchema(); + incrementModCount(); + super.addToMapProperty(propertyName, key, value); + } + + @Override + protected void removeFromMapProperty(String propertyName, String key) { + if (!isBooleanSchema()) { + incrementModCount(); + super.removeFromMapProperty(propertyName, key); + } + } + + @Override + public Object get(String propertyName) { + return getProperty(propertyName, Object.class); + } + + @Override + public Schema set(String propertyName, Object value) { + setProperty(propertyName, value); + return this; + } + + @Override + public Map getAll() { + return Collections.unmodifiableMap(data); + } + + @Override + public void setAll(Map allProperties) { + incrementModCount(); + data.clear(); + if (allProperties != null) { + allProperties.forEach(this::setProperty); + } } } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/parameters/RequestBodyImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/parameters/RequestBodyImpl.java index e140a7842..905016e9c 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/parameters/RequestBodyImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/parameters/RequestBodyImpl.java @@ -16,6 +16,8 @@ public class RequestBodyImpl extends ExtensibleImpl implements Requ private String description; private Content content; private Boolean required; + private Boolean requiredDefault; + private boolean isRequiredSet = false; /** * @see org.eclipse.microprofile.openapi.models.Reference#getRef() @@ -73,7 +75,11 @@ public void setContent(Content content) { */ @Override public Boolean getRequired() { - return this.required; + if (isRequiredSet) { + return this.required; + } else { + return this.requiredDefault; + } } /** @@ -82,6 +88,35 @@ public Boolean getRequired() { @Override public void setRequired(Boolean required) { this.required = required; + isRequiredSet = true; + } + + /** + * Sets the value to use for {@code required} if {@link #setRequired(Boolean)} has not been called. + *

    + * If this method is called, {@link #getRequired()} will return this value unless {@link #setRequired(Boolean)} is called. + * + * @param requiredDefault the default value for {@code required} + * @return this instance + */ + public RequestBodyImpl setRequiredDefault(Boolean requiredDefault) { + this.requiredDefault = requiredDefault; + return this; } + /** + * Returns whether {@link #setRequired(Boolean)} has been called on a request body. + *

    + * Always returns {@code true} if the request body is not a {@code RequestBodyImpl} + * + * @param requestBody the request body + * @return {@code true} if {@code setRequired} has been called + */ + public static boolean isRequiredSet(RequestBody requestBody) { + if (requestBody instanceof RequestBodyImpl) { + return ((RequestBodyImpl) requestBody).isRequiredSet; + } else { + return true; + } + } } diff --git a/core/src/main/java/io/smallrye/openapi/api/models/security/SecurityRequirementImpl.java b/core/src/main/java/io/smallrye/openapi/api/models/security/SecurityRequirementImpl.java index 56c139ee4..0154e1d02 100644 --- a/core/src/main/java/io/smallrye/openapi/api/models/security/SecurityRequirementImpl.java +++ b/core/src/main/java/io/smallrye/openapi/api/models/security/SecurityRequirementImpl.java @@ -73,7 +73,9 @@ public Map> getSchemes() { @Override public void setSchemes(Map> items) { this.clear(); - items.forEach(this::addScheme); + if (items != null) { + items.forEach(this::addScheme); + } } } diff --git a/core/src/main/java/io/smallrye/openapi/api/util/ConfigUtil.java b/core/src/main/java/io/smallrye/openapi/api/util/ConfigUtil.java index b9ce10814..404e9c6cd 100644 --- a/core/src/main/java/io/smallrye/openapi/api/util/ConfigUtil.java +++ b/core/src/main/java/io/smallrye/openapi/api/util/ConfigUtil.java @@ -66,6 +66,7 @@ protected static final void configureInfo(OpenApiConfig config, OpenAPI oai) { setIfPresent(config.getInfoTitle(), oai.getInfo()::setTitle); setIfPresent(config.getInfoVersion(), oai.getInfo()::setVersion); setIfPresent(config.getInfoDescription(), oai.getInfo()::setDescription); + setIfPresent(config.getInfoSummary(), oai.getInfo()::setSummary); setIfPresent(config.getInfoTermsOfService(), oai.getInfo()::setTermsOfService); // Contact @@ -83,6 +84,7 @@ protected static final void configureInfo(OpenApiConfig config, OpenAPI oai) { config.getInfoLicenseName(), config.getInfoLicenseUrl())) { setIfPresent(config.getInfoLicenseName(), oai.getInfo().getLicense()::setName); + setIfPresent(config.getInfoLicenseIdentifier(), oai.getInfo().getLicense()::setIdentifier); setIfPresent(config.getInfoLicenseUrl(), oai.getInfo().getLicense()::setUrl); } } diff --git a/core/src/main/java/io/smallrye/openapi/api/util/MergeUtil.java b/core/src/main/java/io/smallrye/openapi/api/util/MergeUtil.java index 0d1c62bff..de671bf96 100644 --- a/core/src/main/java/io/smallrye/openapi/api/util/MergeUtil.java +++ b/core/src/main/java/io/smallrye/openapi/api/util/MergeUtil.java @@ -27,6 +27,7 @@ import org.eclipse.microprofile.openapi.models.servers.Server; import org.eclipse.microprofile.openapi.models.tags.Tag; +import io.smallrye.openapi.api.models.MapBasedModelImpl; import io.smallrye.openapi.api.models.ModelImpl; import io.smallrye.openapi.runtime.OpenApiRuntimeException; @@ -94,6 +95,12 @@ public static T mergeObjects(T object1, T object2) { return object2; } + // Some model objects are just wrappers around a map of properties and need merged differently + if (object1 instanceof MapBasedModelImpl) { + ((MapBasedModelImpl) object1).mergeFrom((MapBasedModelImpl) object2); + return object1; + } + try { Arrays.stream(Introspector.getBeanInfo(object1.getClass()).getPropertyDescriptors()) .filter(descriptor -> !EXCLUDED_PROPERTIES.contains(descriptor.getName())) diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/ComponentsIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/ComponentsIO.java index 1fe6fb3e4..77e87b972 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/ComponentsIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/ComponentsIO.java @@ -6,16 +6,8 @@ import org.jboss.jandex.AnnotationInstance; import io.smallrye.openapi.api.models.ComponentsImpl; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.callbacks.CallbackIO; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.headers.HeaderIO; -import io.smallrye.openapi.runtime.io.links.LinkIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.media.ExampleObjectIO; -import io.smallrye.openapi.runtime.io.media.SchemaIO; -import io.smallrye.openapi.runtime.io.parameters.ParameterIO; -import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; -import io.smallrye.openapi.runtime.io.responses.APIResponseIO; import io.smallrye.openapi.runtime.io.security.SecuritySchemeIO; public class ComponentsIO extends ModelIO { @@ -29,55 +21,35 @@ public class ComponentsIO extends ModelIO responseIO; - private final HeaderIO headerIO; - private final SchemaIO schemaIO; - private final ExampleObjectIO exampleObjectIO; - private final CallbackIO callbackIO; - private final LinkIO linkIO; - private final ParameterIO parameterIO; - private final RequestBodyIO requestBodyIO; - private final SecuritySchemeIO securitySchemeIO; - private final ExtensionIO extensionIO; - - public ComponentsIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public ComponentsIO(IOContext context) { super(context, Names.COMPONENTS, Names.create(Components.class)); - responseIO = new APIResponseIO<>(context, contentIO, extensionIO); - headerIO = new HeaderIO<>(context, contentIO, extensionIO); - schemaIO = new SchemaIO<>(context, extensionIO); - exampleObjectIO = new ExampleObjectIO<>(context, extensionIO); - callbackIO = new CallbackIO<>(context, contentIO, extensionIO); - linkIO = new LinkIO<>(context, extensionIO); - parameterIO = new ParameterIO<>(context, contentIO, extensionIO); - requestBodyIO = new RequestBodyIO<>(context, contentIO, extensionIO); - securitySchemeIO = new SecuritySchemeIO<>(context, extensionIO); - this.extensionIO = extensionIO; } public CallbackIO callbacks() { - return callbackIO; + return callbackIO(); } public SecuritySchemeIO securitySchemes() { - return securitySchemeIO; + return securitySchemeIO(); } @Override public Components read(AnnotationInstance annotation) { IoLogging.logger.singleAnnotation("@Components"); Components components = new ComponentsImpl(); - components.setCallbacks(callbackIO.readMap(annotation.value(PROP_CALLBACKS))); - components.setExamples(exampleObjectIO.readMap(annotation.value(PROP_EXAMPLES))); - components.setHeaders(headerIO.readMap(annotation.value(PROP_HEADERS))); - components.setLinks(linkIO.readMap(annotation.value(PROP_LINKS))); - components.setParameters(parameterIO.readMap(annotation.value(PROP_PARAMETERS))); - components.setRequestBodies(requestBodyIO.readMap(annotation.value(PROP_REQUEST_BODIES))); - components.setResponses(responseIO.readMap(annotation.value(PROP_RESPONSES))); - components.setSchemas(schemaIO.readMap(annotation.value(PROP_SCHEMAS))); - components.setSecuritySchemes(securitySchemeIO.readMap(annotation.value(PROP_SECURITY_SCHEMES))); - components.setExtensions(extensionIO.readExtensible(annotation)); + components.setCallbacks(callbackIO().readMap(annotation.value(PROP_CALLBACKS))); + components.setExamples(exampleObjectIO().readMap(annotation.value(PROP_EXAMPLES))); + components.setHeaders(headerIO().readMap(annotation.value(PROP_HEADERS))); + components.setLinks(linkIO().readMap(annotation.value(PROP_LINKS))); + components.setParameters(parameterIO().readMap(annotation.value(PROP_PARAMETERS))); + components.setPathItems(pathItemIO().readMap(annotation.value(PROP_PATH_ITEMS))); + components.setRequestBodies(requestBodyIO().readMap(annotation.value(PROP_REQUEST_BODIES))); + components.setResponses(apiResponseIO().readMap(annotation.value(PROP_RESPONSES))); + components.setSchemas(schemaIO().readMap(annotation.value(PROP_SCHEMAS))); + components.setSecuritySchemes(securitySchemeIO().readMap(annotation.value(PROP_SECURITY_SCHEMES))); + components.setExtensions(extensionIO().readExtensible(annotation)); return components; } @@ -86,31 +58,37 @@ public Components read(AnnotationInstance annotation) { public Components readObject(O node) { IoLogging.logger.singleJsonNode("Components"); Components components = new ComponentsImpl(); - components.setCallbacks(callbackIO.readMap(jsonIO().getValue(node, PROP_CALLBACKS))); - components.setExamples(exampleObjectIO.readMap(jsonIO().getValue(node, PROP_EXAMPLES))); - components.setHeaders(headerIO.readMap(jsonIO().getValue(node, PROP_HEADERS))); - components.setLinks(linkIO.readMap(jsonIO().getValue(node, PROP_LINKS))); - components.setParameters(parameterIO.readMap(jsonIO().getValue(node, PROP_PARAMETERS))); - components.setRequestBodies(requestBodyIO.readMap(jsonIO().getValue(node, PROP_REQUEST_BODIES))); - components.setResponses(responseIO.readMap(jsonIO().getValue(node, PROP_RESPONSES))); - components.setSchemas(schemaIO.readMap(jsonIO().getValue(node, PROP_SCHEMAS))); - components.setSecuritySchemes(securitySchemeIO.readMap(jsonIO().getValue(node, PROP_SECURITY_SCHEMES))); - components.setExtensions(extensionIO.readMap(node)); + components.setCallbacks(callbackIO().readMap(jsonIO().getValue(node, PROP_CALLBACKS))); + components.setExamples(exampleObjectIO().readMap(jsonIO().getValue(node, PROP_EXAMPLES))); + components.setHeaders(headerIO().readMap(jsonIO().getValue(node, PROP_HEADERS))); + components.setLinks(linkIO().readMap(jsonIO().getValue(node, PROP_LINKS))); + components.setParameters(parameterIO().readMap(jsonIO().getValue(node, PROP_PARAMETERS))); + components.setRequestBodies(requestBodyIO().readMap(jsonIO().getValue(node, PROP_REQUEST_BODIES))); + components.setResponses(apiResponseIO().readMap(jsonIO().getValue(node, PROP_RESPONSES))); + components.setSchemas(schemaIO().readMap(jsonIO().getValue(node, PROP_SCHEMAS))); + components.setSecuritySchemes(securitySchemeIO().readMap(jsonIO().getValue(node, PROP_SECURITY_SCHEMES))); + if (openApiVersion() == OpenApiVersion.V3_1) { + components.setPathItems(pathItemIO().readMap(jsonIO().getValue(node, PROP_PATH_ITEMS))); + } + components.setExtensions(extensionIO().readMap(node)); return components; } public Optional write(Components model) { return optionalJsonObject(model).map(node -> { - setIfPresent(node, PROP_SCHEMAS, schemaIO.write(model.getSchemas())); - setIfPresent(node, PROP_RESPONSES, responseIO.write(model.getResponses())); - setIfPresent(node, PROP_PARAMETERS, parameterIO.write(model.getParameters())); - setIfPresent(node, PROP_EXAMPLES, exampleObjectIO.write(model.getExamples())); - setIfPresent(node, PROP_REQUEST_BODIES, requestBodyIO.write(model.getRequestBodies())); - setIfPresent(node, PROP_HEADERS, headerIO.write(model.getHeaders())); - setIfPresent(node, PROP_SECURITY_SCHEMES, securitySchemeIO.write(model.getSecuritySchemes())); - setIfPresent(node, PROP_LINKS, linkIO.write(model.getLinks())); - setIfPresent(node, PROP_CALLBACKS, callbackIO.write(model.getCallbacks())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_SCHEMAS, schemaIO().write(model.getSchemas())); + setIfPresent(node, PROP_RESPONSES, apiResponseIO().write(model.getResponses())); + setIfPresent(node, PROP_PARAMETERS, parameterIO().write(model.getParameters())); + setIfPresent(node, PROP_EXAMPLES, exampleObjectIO().write(model.getExamples())); + setIfPresent(node, PROP_REQUEST_BODIES, requestBodyIO().write(model.getRequestBodies())); + setIfPresent(node, PROP_HEADERS, headerIO().write(model.getHeaders())); + setIfPresent(node, PROP_SECURITY_SCHEMES, securitySchemeIO().write(model.getSecuritySchemes())); + setIfPresent(node, PROP_LINKS, linkIO().write(model.getLinks())); + setIfPresent(node, PROP_CALLBACKS, callbackIO().write(model.getCallbacks())); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_PATH_ITEMS, pathItemIO().write(model.getPathItems())); + } + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/ExternalDocumentationIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/ExternalDocumentationIO.java index 9df85c0bc..17c908b46 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/ExternalDocumentationIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/ExternalDocumentationIO.java @@ -6,7 +6,6 @@ import org.jboss.jandex.AnnotationInstance; import io.smallrye.openapi.api.models.ExternalDocumentationImpl; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class ExternalDocumentationIO extends ModelIO { @@ -14,11 +13,8 @@ public class ExternalDocumentationIO private static final String PROP_DESCRIPTION = "description"; private static final String PROP_URL = "url"; - private final ExtensionIO extensionIO; - - public ExternalDocumentationIO(IOContext context, ExtensionIO extensionIO) { + public ExternalDocumentationIO(IOContext context) { super(context, Names.EXTERNAL_DOCUMENTATION, Names.create(ExternalDocumentation.class)); - this.extensionIO = extensionIO; } @Override @@ -27,7 +23,7 @@ public ExternalDocumentation read(AnnotationInstance annotation) { ExternalDocumentation model = new ExternalDocumentationImpl(); model.setDescription(value(annotation, PROP_DESCRIPTION)); model.setUrl(value(annotation, PROP_URL)); - model.setExtensions(extensionIO.readExtensible(annotation)); + model.setExtensions(extensionIO().readExtensible(annotation)); return model; } @@ -37,7 +33,7 @@ public ExternalDocumentation readObject(O node) { jsonIO().getString(node, PROP_DESCRIPTION); model.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); model.setUrl(jsonIO().getString(node, PROP_URL)); - model.setExtensions(extensionIO.readMap(node)); + model.setExtensions(extensionIO().readMap(node)); return model; } @@ -45,7 +41,7 @@ public Optional write(ExternalDocumentation model) { return optionalJsonObject(model).map(node -> { setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, PROP_URL, jsonIO().toJson(model.getUrl())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/IOContext.java b/core/src/main/java/io/smallrye/openapi/runtime/io/IOContext.java index 8ea50e3a9..4c46cc8e4 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/IOContext.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/IOContext.java @@ -1,12 +1,99 @@ package io.smallrye.openapi.runtime.io; +import java.util.Optional; + +import io.smallrye.openapi.api.OpenApiConfig; +import io.smallrye.openapi.runtime.io.callbacks.CallbackIO; +import io.smallrye.openapi.runtime.io.callbacks.CallbackOperationIO; +import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; +import io.smallrye.openapi.runtime.io.headers.HeaderIO; +import io.smallrye.openapi.runtime.io.info.ContactIO; +import io.smallrye.openapi.runtime.io.info.InfoIO; +import io.smallrye.openapi.runtime.io.info.LicenseIO; +import io.smallrye.openapi.runtime.io.links.LinkIO; +import io.smallrye.openapi.runtime.io.links.LinkParameterIO; +import io.smallrye.openapi.runtime.io.media.ContentIO; +import io.smallrye.openapi.runtime.io.media.DiscriminatorIO; +import io.smallrye.openapi.runtime.io.media.EncodingIO; +import io.smallrye.openapi.runtime.io.media.ExampleObjectIO; +import io.smallrye.openapi.runtime.io.media.MediaTypeIO; +import io.smallrye.openapi.runtime.io.media.SchemaIO; +import io.smallrye.openapi.runtime.io.parameters.ParameterIO; +import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; +import io.smallrye.openapi.runtime.io.responses.APIResponseIO; +import io.smallrye.openapi.runtime.io.responses.APIResponsesIO; +import io.smallrye.openapi.runtime.io.security.OAuthFlowIO; +import io.smallrye.openapi.runtime.io.security.OAuthFlowsIO; +import io.smallrye.openapi.runtime.io.security.OAuthScopeIO; +import io.smallrye.openapi.runtime.io.security.SecurityIO; +import io.smallrye.openapi.runtime.io.security.SecurityRequirementIO; +import io.smallrye.openapi.runtime.io.security.SecurityRequirementsSetIO; +import io.smallrye.openapi.runtime.io.security.SecuritySchemeIO; +import io.smallrye.openapi.runtime.io.servers.ServerIO; +import io.smallrye.openapi.runtime.io.servers.ServerVariableIO; +import io.smallrye.openapi.runtime.io.tags.TagIO; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; public class IOContext { + /** + * The major.minor version of OpenAPI being used for (de-)serizalization + */ + public enum OpenApiVersion { + V3_0, + V3_1; + + public static OpenApiVersion fromString(String version) { + if (version != null && version.startsWith("3.0")) { + return V3_0; + } else { + return V3_1; + } + } + } + private AnnotationScannerContext scannerContext; private JsonIO jsonIO; + private OpenApiVersion openApiVersion; + + private final ComponentsIO componentsIO = new ComponentsIO<>(this); + private final ExternalDocumentationIO extDocIO = new ExternalDocumentationIO<>(this); + private final OpenAPIDefinitionIO openApiDefinitionIO = new OpenAPIDefinitionIO<>(this); + private final OperationIO operationIO = new OperationIO<>(this); + private final CallbackOperationIO callbackOperationIO = new CallbackOperationIO<>(this); + private final PathItemOperationIO pathItemOperationIO = new PathItemOperationIO<>(this); + private final PathItemIO pathItemIO = new PathItemIO<>(this); + private final PathsIO pathsIO = new PathsIO<>(this); + private final CallbackIO callbackIO = new CallbackIO<>(this); + private final ExtensionIO extensionIO = new ExtensionIO<>(this); + private final HeaderIO headerIO = new HeaderIO<>(this); + private final ContactIO contactIO = new ContactIO<>(this); + private final InfoIO infoIO = new InfoIO<>(this); + private final LicenseIO licenseIO = new LicenseIO<>(this); + private final LinkIO linkIO = new LinkIO<>(this); + private final LinkParameterIO linkParameterIO = new LinkParameterIO<>(this); + private final ContentIO contentIO = new ContentIO<>(this); + private final DiscriminatorIO discriminatorIO = new DiscriminatorIO<>(this); + private final EncodingIO encodingIO = new EncodingIO<>(this); + private final ExampleObjectIO exampleObjectIO = new ExampleObjectIO<>(this); + private final MediaTypeIO mediaTypeIO = new MediaTypeIO<>(this); + private final SchemaIO schemaIO = new SchemaIO<>(this); + private final ParameterIO parameterIO = new ParameterIO<>(this); + private final RequestBodyIO requestBodyIO = new RequestBodyIO<>(this); + private final APIResponseIO apiResponseIO = new APIResponseIO<>(this); + private final APIResponsesIO apiResponsesIO = new APIResponsesIO<>(this); + private final OAuthFlowIO oauthFlowIO = new OAuthFlowIO<>(this); + private final OAuthFlowsIO oauthFlowsIO = new OAuthFlowsIO<>(this); + private final OAuthScopeIO oauthScopeIO = new OAuthScopeIO<>(this); + private final SecurityIO securityIO = new SecurityIO<>(this); + private final SecurityRequirementIO securityRequirementIO = new SecurityRequirementIO<>(this); + private final SecurityRequirementsSetIO securityRequirementsSetIO = new SecurityRequirementsSetIO<>(this); + private final SecuritySchemeIO securitySchemeIO = new SecuritySchemeIO<>(this); + private final ServerIO serverIO = new ServerIO<>(this); + private final ServerVariableIO serverVariableIO = new ServerVariableIO<>(this); + private final TagIO tagIO = new TagIO<>(this); + public static IOContext empty() { return new IOContext<>(null, null); } @@ -24,6 +111,19 @@ private IOContext(AnnotationScannerContext context, JsonIO json this.jsonIO = jsonIO; } + public OpenApiVersion openApiVersion() { + return Optional.ofNullable(openApiVersion) + .orElseGet(() -> Optional.ofNullable(scannerContext) + .map(AnnotationScannerContext::getConfig) + .map(OpenApiConfig::getOpenApiVersion) + .map(OpenApiVersion::fromString) + .orElse(OpenApiVersion.V3_1)); + } + + public void setOpenApiVersion(OpenApiVersion version) { + this.openApiVersion = version; + } + public AnnotationScannerContext scannerContext() { return scannerContext; } @@ -40,4 +140,148 @@ public void jsonIO(JsonIO jsonIO) { this.jsonIO = jsonIO; } + public ComponentsIO componentsIO() { + return componentsIO; + } + + public ExternalDocumentationIO extDocIO() { + return extDocIO; + } + + public OpenAPIDefinitionIO openApiDefinitionIO() { + return openApiDefinitionIO; + } + + public OperationIO operationIO() { + return operationIO; + } + + public PathItemOperationIO pathItemOperationIO() { + return pathItemOperationIO; + } + + public PathItemIO pathItemIO() { + return pathItemIO; + } + + public PathsIO pathsIO() { + return pathsIO; + } + + public CallbackIO callbackIO() { + return callbackIO; + } + + public CallbackOperationIO callbackOperationIO() { + return callbackOperationIO; + } + + public ExtensionIO extensionIO() { + return extensionIO; + } + + public HeaderIO headerIO() { + return headerIO; + } + + public ContactIO contactIO() { + return contactIO; + } + + public InfoIO infoIO() { + return infoIO; + } + + public LicenseIO licenseIO() { + return licenseIO; + } + + public LinkIO linkIO() { + return linkIO; + } + + public LinkParameterIO linkParameterIO() { + return linkParameterIO; + } + + public ContentIO contentIO() { + return contentIO; + } + + public DiscriminatorIO discriminatorIO() { + return discriminatorIO; + } + + public EncodingIO encodingIO() { + return encodingIO; + } + + public ExampleObjectIO exampleObjectIO() { + return exampleObjectIO; + } + + public MediaTypeIO mediaTypeIO() { + return mediaTypeIO; + } + + public SchemaIO schemaIO() { + return schemaIO; + } + + public ParameterIO parameterIO() { + return parameterIO; + } + + public RequestBodyIO requestBodyIO() { + return requestBodyIO; + } + + public APIResponseIO apiResponseIO() { + return apiResponseIO; + } + + public APIResponsesIO apiResponsesIO() { + return apiResponsesIO; + } + + public OAuthFlowIO oauthFlowIO() { + return oauthFlowIO; + } + + public OAuthFlowsIO oauthFlowsIO() { + return oauthFlowsIO; + } + + public OAuthScopeIO oauthScopeIO() { + return oauthScopeIO; + } + + public SecurityIO securityIO() { + return securityIO; + } + + public SecurityRequirementIO securityRequirementIO() { + return securityRequirementIO; + } + + public SecurityRequirementsSetIO securityRequirementsSetIO() { + return securityRequirementsSetIO; + } + + public SecuritySchemeIO securitySchemeIO() { + return securitySchemeIO; + } + + public ServerIO serverIO() { + return serverIO; + } + + public ServerVariableIO serverVariableIO() { + return serverVariableIO; + } + + public TagIO tagIO() { + return tagIO; + } + } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/JacksonJsonIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/JacksonJsonIO.java index fa22a6beb..eaca002b2 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/JacksonJsonIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/JacksonJsonIO.java @@ -117,6 +117,16 @@ public String asString(JsonNode value) { return value != null && value.isValueNode() ? value.asText() : null; } + @Override + public boolean isBoolean(JsonNode value) { + return value != null && value.isBoolean(); + } + + @Override + public Boolean asBoolean(JsonNode value) { + return value != null && value.isBoolean() ? value.asBoolean() : null; + } + @Override public Integer getJsonInt(ObjectNode object, String key) { JsonNode value = object.get(key); @@ -208,10 +218,14 @@ public JsonNode toJson(Object value, JsonNode defaultValue) { return factory.numberNode((Double) value); } else if (value instanceof Float) { return factory.numberNode((Float) value); + } else if (value instanceof Short) { + return factory.numberNode((short) value); } else if (value instanceof Integer) { return factory.numberNode((Integer) value); } else if (value instanceof Long) { return factory.numberNode((Long) value); + } else if (value instanceof Character) { + return factory.textNode(((Character) value).toString()); } else if (value instanceof List) { ArrayNode array = createArray(); ((List) value).stream() @@ -271,6 +285,29 @@ public Object fromJson(JsonNode value) { return null; } + @Override + public T fromJson(JsonNode object, Class desiredType) { + if (desiredType == String.class) { + return (T) object.asText(); + } + if (desiredType == Integer.class && object.canConvertToInt()) { + return (T) Integer.valueOf(object.asInt()); + } + if (desiredType == BigInteger.class && object.canConvertToExactIntegral()) { + return (T) object.bigIntegerValue(); + } + if (desiredType == Long.class && object.canConvertToLong()) { + return (T) Long.valueOf(object.asLong()); + } + if (desiredType == BigDecimal.class && object.isNumber()) { + return (T) object.decimalValue(); + } + if (desiredType == Boolean.class && object.isBoolean()) { + return (T) Boolean.valueOf(object.booleanValue()); + } + return null; + } + @Override public String toString(JsonNode value, Format format) { try { diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/JakartaJsonIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/JakartaJsonIO.java index 387b36f39..4d102eee3 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/JakartaJsonIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/JakartaJsonIO.java @@ -101,6 +101,27 @@ public JsonObject asObject(JsonValue value) { return (JsonObject) value; } + @Override + public boolean isBoolean(JsonValue value) { + if (value == null) { + return false; + } + ValueType type = value.getValueType(); + return type == ValueType.TRUE || type == ValueType.FALSE; + } + + @Override + public Boolean asBoolean(JsonValue value) { + ValueType type = value.getValueType(); + if (type == ValueType.TRUE) { + return Boolean.TRUE; + } else if (type == ValueType.FALSE) { + return Boolean.FALSE; + } else { + return null; + } + } + @Override public boolean hasKey(JsonObject object, String key) { return object.containsKey(key); @@ -199,10 +220,14 @@ public JsonValue toJson(Object value, JsonValue defaultValue) { return json.createValue((Double) value); } else if (value instanceof Float) { return json.createValue((Float) value); + } else if (value instanceof Short) { + return json.createValue((short) value); } else if (value instanceof Integer) { return json.createValue((Integer) value); } else if (value instanceof Long) { return json.createValue((Long) value); + } else if (value instanceof Character) { + return json.createValue(((Character) value).toString()); } else if (value instanceof List) { JsonArrayBuilder array = createArray(); ((List) value).stream() @@ -251,6 +276,48 @@ public Object fromJson(JsonValue value) { } } + @Override + public T fromJson(JsonValue object, Class desiredType) { + ValueType type = object.getValueType(); + if (desiredType == String.class) { + if (type == ValueType.STRING) { + return (T) ((JsonString) object).getString(); + } else if (type == ValueType.NUMBER) { + return (T) ((JsonNumber) object).numberValue().toString(); + } else if (type == ValueType.TRUE) { + return (T) "true"; + } else if (type == ValueType.FALSE) { + return (T) "false"; + } + } + if (type == ValueType.NUMBER) { + JsonNumber number = (JsonNumber) object; + try { + if (desiredType == Integer.class) { + return (T) Integer.valueOf(number.intValueExact()); + } else if (desiredType == Long.class) { + return (T) Long.valueOf(number.longValueExact()); + } else if (desiredType == BigInteger.class) { + return (T) number.bigIntegerValueExact(); + } else if (desiredType == BigDecimal.class) { + return (T) number.bigDecimalValue(); + } + } catch (ArithmeticException e) { + // thrown if conversion cannot be done losslessly + // fall through to return null later + } + } + if (desiredType == Boolean.class) { + if (type == ValueType.TRUE) { + return (T) Boolean.TRUE; + } else if (type == ValueType.FALSE) { + return (T) Boolean.FALSE; + } + } + // Nothing matched + return null; + } + @Override public String toString(JsonValue value, Format format) { Writer output = new StringWriter(); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java index 223ed8e71..0d8f4b99b 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java @@ -7,6 +7,7 @@ import java.io.StringReader; import java.io.UncheckedIOException; import java.math.BigDecimal; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.Optional; @@ -16,6 +17,15 @@ import io.smallrye.openapi.api.OpenApiConfig; +/** + * Abstraction layer around a library for reading and writing JSON. (E.g. Jakarta JSON-P or Jackson). + * + * @param the type for a JSON value + * @param the type for a JSON array + * @param the type of a JSON object + * @param the type used to build a JSON array + * @param the type used to build a JSON object + */ public interface JsonIO { public static JsonIO newInstance(OpenApiConfig config) { @@ -76,24 +86,107 @@ default Object parseValue(String value) { return value; } + /** + * Check whether a JSON value is an array + * + * @param value the JSON value to check + * @return {@code true} if {@code value} is a JSON array, otherwise {@code false} + */ boolean isArray(V value); + /** + * Cast a JSON value to a JSON array + * + * @param value the JSON value, which must represent a JSON array + * @return the JSON array + * @throws ClassCastException if {@code value} is not a JSON array + */ A asArray(V value); + /** + * Get the list of JSON values contained by a JSON array + * + * @param array the JSON array + * @return the list of JSON values in the array + */ List entries(A array); + /** + * Check whether a JSON value is a JSON object + * + * @param value the JSON value to check + * @return {@code true} if {@code value} is a JSON object, otherwise {@code false} + */ boolean isObject(V value); + /** + * Cast a JSON value to a JSON object + * + * @param value the JSON value, which must represent a JSON object + * @return the JSON object + * @throws ClassCastException if {@code value} is not a JSON object + */ O asObject(V value); + /** + * Check whether a JSON object contains a particular key + * + * @param object the JSON object to check + * @param key the key to look for + * @return {@code true} if {@code object} contains key {@code key}, otherwise {@code false} + */ boolean hasKey(O object, String key); + /** + * Get all the properties (keys and values) of a JSON object. + *

    + * This is a similar operation to {@link Map#entrySet()}. + * + * @param object the JSON object + * @return the set of key-value pairs + */ Set> properties(O object); + /** + * Check whether a JSON value is a JSON string. + * + * @param value the JSON value to check + * @return {@code true} if {@code value} is a string, otherwise {@code false} + */ boolean isString(V value); + /** + * Convert a JSON string, number or boolean to a {@code String}. + * + * @param value the JSON value, must be a string + * @return the String value, or {@code null} if the JSON value does not represent a string, number or boolean + */ String asString(V value); + /** + * Check whether a JSON value is a JSON boolean. + * + * @param value the JSON value to check + * @return {@code true} if {@code value} is a boolean, otherwise {@code false} + */ + boolean isBoolean(V value); + + /** + * Convert a JSON boolean to a {@code Boolean}. + * + * @param value the JSON value, must be a boolean + * @return the Boolean value, or {@code null} if the JSON value does not represent a boolean + */ + Boolean asBoolean(V value); + + /** + * Get a property from a JSON object as a string. The same conversions are performed as {@link #asString(Object)}. + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if {@code object} is not a JSON object, the property is not present, or the + * property value is not a string, number or boolean + */ default String getString(V object, String key) { if (isObject(object)) { return getJsonString(asObject(object), key); @@ -101,6 +194,14 @@ default String getString(V object, String key) { return null; } + /** + * Get an integer property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if {@code object} is not a JSON object, the property is not present, or the + * property value is not an integer + */ default Integer getInt(V object, String key) { if (isObject(object)) { return getJsonInt(asObject(object), key); @@ -108,6 +209,14 @@ default Integer getInt(V object, String key) { return null; } + /** + * Get an boolean property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if {@code object} is not a JSON object, the property is not present, or the + * property value is not a boolean + */ default Boolean getBoolean(V object, String key) { if (isObject(object)) { return getJsonBoolean(asObject(object), key); @@ -115,6 +224,14 @@ default Boolean getBoolean(V object, String key) { return null; // NOSONAR } + /** + * Get an number property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if {@code object} is not a JSON object, the property is not present, or the + * property value is not a number + */ default BigDecimal getBigDecimal(V object, String key) { if (isObject(object)) { return getJsonBigDecimal(asObject(object), key); @@ -122,34 +239,161 @@ default BigDecimal getBigDecimal(V object, String key) { return null; } + /** + * Get an integer property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if the property is not present or is not an integer + */ Integer getJsonInt(O object, String key); + /** + * Get a property from a JSON object as a string. The same conversions are performed as {@link #asString(Object)}. + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if the property is not present or is not a string, number or boolean + */ String getJsonString(O object, String key); + /** + * Get an boolean property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if the property is not present or is not a boolean + */ Boolean getJsonBoolean(O object, String key); + /** + * Get an number property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if the property is not present or is not a number + */ BigDecimal getJsonBigDecimal(O object, String key); + /** + * Get a property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return the property value, or {@code null} if the property is not present + */ V getValue(O object, String key); + /** + * Get an JSON array property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return an {@code Optional} containing the property value, or an empty {@code Optional} if the property is not present, + * or the property is not an array + */ Optional getArray(O object, String key); + /** + * Get an JSON array property from a JSON object and convert it into a list of Java objects + * + * @param the type that each value in the JSON array should be converted into + * @param object the JSON object + * @param key the property key + * @param valueMapper a function to convert a value within the JSON array into a Java object + * @return an {@code Optional} containing the list of Java objects, or an empty {@code Optional} if the property is not + * present, or the property is not an array + */ default Optional> getArray(O object, String key, Function valueMapper) { return getArray(object, key) .map(this::entries) .map(entries -> entries.stream().map(valueMapper).collect(Collectors.toList())); } + /** + * Get an JSON object property from a JSON object + * + * @param object the JSON object + * @param key the property key + * @return an {@code Optional} containing the property value, or an empty {@code Optional} if the property is not present, + * or the property is not an object + */ Optional getObject(O object, String key); + /** + * Convert a Java object to JSON. See {@link #toJson(Object, Object)} for the list of supported types + * + * @param object the JSON object + * @return an {@code Optional} containing the JSON value, or an empty {@code Optional} if {@code object} is not one of the + * supported types + */ default Optional toJson(Object object) { return Optional.ofNullable(toJson(object, null)); } + /** + * Convert a JSON value into a Java object. + * + * @param object the JSON value + * @return the Java object, which may be {@code null} if {@code object} is {@code null} or represents a JSON null value + */ Object fromJson(V object); + /** + * Convert a basic JSON value into a Java object of the desired type. This method cannot be used to convert JSON arrays or + * objects. + *

    + * The supported values for {@code desiredType} are: + *

    + * + * @param the desired Java type + * @param object the JSON object + * @param desiredType the desired Java type + * @return the JSON object, or {@code null} if {@code object} cannot be converted to the desired type + */ + T fromJson(V object, Class desiredType); + + /** + * Convert a Java object to JSON. + *

    + * The following types are supported: + *

      + *
    • {@code V} (the JSON value type) + *
    • {@code String} + *
    • {@code BigDecimal} + *
    • {@code BigInteger} + *
    • {@code Boolean} + *
    • {@code Double} + *
    • {@code Float} + *
    • {@code Short} + *
    • {@code Integer} + *
    • {@code Long} + *
    • {@code Character} + *
    • {@code Enum} + *
    • {@code List} where each item is a supported type + *
    • {@code Map} where each key is a {@code String} and each value is a supported type + *
    + * + * @param object the JSON object + * @param defaultValue the default value to return if {@code value} cannot be converted to JSON + * @return the JSON value, or {@code defaultValue} if {@code value} cannot be converted to JSON + */ V toJson(Object object, V defaultValue); + /** + * Read a JSON or YAML document from a {@code String} + * + * @param value the JSON or YAML document + * @param format the format + * @return the root JSON value from the document + */ default V fromString(String value, Format format) { try (Reader reader = new StringReader(value)) { return fromReader(reader, format); @@ -158,6 +402,14 @@ default V fromString(String value, Format format) { } } + /** + * Read a JSON or YAML document from an {@code InputStream}. The stream is read using the {@link Charset#defaultCharset() + * default charset}. + * + * @param stream the input stream to read the JSON or YAML document from + * @param format the format + * @return the root JSON value from the document + */ default V fromStream(InputStream stream, Format format) { try (Reader reader = new InputStreamReader(stream)) { return fromReader(reader, format); @@ -166,25 +418,109 @@ default V fromStream(InputStream stream, Format format) { } } + /** + * Read a YAML document from a {@code Reader}. + * + * @param reader the reader to read the YAML document from + * @return the root JSON value from the document + */ default V fromReader(Reader reader) throws IOException { return fromReader(reader, Format.YAML); } + /** + * Read a JSON or YAML document from a {@code Reader}. + * + * @param reader the reader to read the JSON or YAML document from + * @param format the format + * @return the root JSON value from the document + */ V fromReader(Reader reader, Format format) throws IOException; + /** + * Serialize a JSON value to a JSON or YAML string + * + * @param object the JSON value + * @param format the desired format + * @return the serialization of {@code object} + */ String toString(V object, Format format); + /** + * Create a JSON array builder which can be used to build a JSON array. + * + * Example: + * + *
    {@code
    +     * AB builder = jsonIO().createArray();
    +     * jsonIO().add(builder, value1);
    +     * jsonIO().add(builder, value2);
    +     * A array = jsonIO().buildArray(builder);
    +     * }
    + * + * @return the JSON array builder + */ AB createArray(); + /** + * Add a JSON value to a JSON array builder. + * + * @param array the array builder + * @param value the value to add + * @see #createArray() + */ void add(AB array, V value); + /** + * Convert a JSON array builder into a JSON array. + * + * @param array the JSON array builder + * @return the JSON array + * @see #createArray() + */ A buildArray(AB array); + /** + * Create a JSON object builder which can be used to build a JSON object. + * + * Example: + * + *
    {@code
    +     * OB builder = jsonIO().createObject();
    +     * jsonIO().set(builder, "key1", value1);
    +     * jsonIO().set(builder, "key2", value2);
    +     * O object = jsonIO().buildObject(builder);
    +     * }
    + * + * @return the JSON object builder + */ OB createObject(); + /** + * Set a property on a JSON object builder + * + * @param object the JSON object builder + * @param key the property key + * @param value the property value + * @see #createObject() + */ void set(OB object, String key, V value); + /** + * Copy all properties from a JSON object to a JSON object builder. + * + * @param object the JSON object builder + * @param valueSource the JSON object + * @see #createObject() + */ void setAll(OB object, O valueSource); + /** + * Convert a JSON object builder into a JSON object. + * + * @param object the JSON object builder + * @return the JSON object + * @see #createObject() + */ O buildObject(OB object); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/MapModelIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/MapModelIO.java index 789cc4c67..6dffb28b1 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/MapModelIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/MapModelIO.java @@ -107,7 +107,7 @@ public Map readObjectMap(O node) { public Optional write(Map models) { return optionalJsonObject(models).map(node -> { models.forEach((key, value) -> { - Optional jsonValue = write(value); + Optional jsonValue = write(value); if (jsonValue.isPresent()) { jsonIO().set(node, key, jsonValue.get()); } else { diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java index ac49bfc7c..920a7d16b 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java @@ -6,15 +6,46 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; import java.util.function.Predicate; import java.util.stream.Collector; -import java.util.stream.Collectors; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.DotName; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; +import io.smallrye.openapi.runtime.io.callbacks.CallbackIO; +import io.smallrye.openapi.runtime.io.callbacks.CallbackOperationIO; +import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; +import io.smallrye.openapi.runtime.io.headers.HeaderIO; +import io.smallrye.openapi.runtime.io.info.ContactIO; +import io.smallrye.openapi.runtime.io.info.InfoIO; +import io.smallrye.openapi.runtime.io.info.LicenseIO; +import io.smallrye.openapi.runtime.io.links.LinkIO; +import io.smallrye.openapi.runtime.io.links.LinkParameterIO; +import io.smallrye.openapi.runtime.io.media.ContentIO; +import io.smallrye.openapi.runtime.io.media.DiscriminatorIO; +import io.smallrye.openapi.runtime.io.media.EncodingIO; +import io.smallrye.openapi.runtime.io.media.ExampleObjectIO; +import io.smallrye.openapi.runtime.io.media.MediaTypeIO; +import io.smallrye.openapi.runtime.io.media.SchemaIO; +import io.smallrye.openapi.runtime.io.parameters.ParameterIO; +import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; +import io.smallrye.openapi.runtime.io.responses.APIResponseIO; +import io.smallrye.openapi.runtime.io.responses.APIResponsesIO; +import io.smallrye.openapi.runtime.io.security.OAuthFlowIO; +import io.smallrye.openapi.runtime.io.security.OAuthFlowsIO; +import io.smallrye.openapi.runtime.io.security.OAuthScopeIO; +import io.smallrye.openapi.runtime.io.security.SecurityIO; +import io.smallrye.openapi.runtime.io.security.SecurityRequirementIO; +import io.smallrye.openapi.runtime.io.security.SecurityRequirementsSetIO; +import io.smallrye.openapi.runtime.io.security.SecuritySchemeIO; +import io.smallrye.openapi.runtime.io.servers.ServerIO; +import io.smallrye.openapi.runtime.io.servers.ServerVariableIO; +import io.smallrye.openapi.runtime.io.tags.TagIO; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; import io.smallrye.openapi.runtime.util.JandexUtil; @@ -109,8 +140,40 @@ protected static Predicate not(Predicate predicate) { return (Predicate) predicate.negate(); } + /** + * Creates a Collector for a stream of Map.Entry where the entry keys are Strings. + * + * Null map entry values are allowed, but duplicate keys will result in an + * IllegalStateException being thrown. + * + * This method is the equivalent of + * {@link java.util.stream.Collectors#toMap(java.util.function.Function, java.util.function.Function)} + * where the given key and value mapping functions are simply {@code Map.Entry.getKey()} and + * {@code Map.Entry.getValue()}, and where null values are tolerated. + * + * @param the type of the map entry values + * @return a collector allowing null values but forbidding duplicate keys. + */ protected static Collector, ?, Map> toLinkedMap() { - return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new); + BiConsumer, Map.Entry> accumulator = (map, entry) -> { + String k = entry.getKey(); + T v = entry.getValue(); + + if (map.containsKey(k)) { + throw new IllegalStateException(String.format( + "Duplicate key %s (attempted merging values %s and %s)", + k, map.get(k), v)); + } + + map.put(k, v); + }; + + BinaryOperator> combiner = (m1, m2) -> { + m2.entrySet().forEach(entry -> accumulator.accept(m1, entry)); + return m1; + }; + + return Collector.of(LinkedHashMap::new, accumulator, combiner); } public AnnotationInstance getAnnotation(AnnotationTarget target) { @@ -151,5 +214,158 @@ public T readValue(V node) { public abstract T readObject(O node); - public abstract Optional write(T model); + public abstract Optional write(T model); + + public OpenApiVersion openApiVersion() { + return context.openApiVersion(); + } + + public void setOpenApiVersion(OpenApiVersion version) { + context.setOpenApiVersion(version); + } + + public ComponentsIO componentsIO() { + return context.componentsIO(); + } + + public ExternalDocumentationIO extDocIO() { + return context.extDocIO(); + } + + public OpenAPIDefinitionIO openApiDefinitionIO() { + return context.openApiDefinitionIO(); + } + + public OperationIO operationIO() { + return context.operationIO(); + } + + public PathItemOperationIO pathItemOperationIO() { + return context.pathItemOperationIO(); + } + + public PathItemIO pathItemIO() { + return context.pathItemIO(); + } + + public PathsIO pathsIO() { + return context.pathsIO(); + } + + public CallbackIO callbackIO() { + return context.callbackIO(); + } + + public CallbackOperationIO callbackOperationIO() { + return context.callbackOperationIO(); + } + + public ExtensionIO extensionIO() { + return context.extensionIO(); + } + + public HeaderIO headerIO() { + return context.headerIO(); + } + + public ContactIO contactIO() { + return context.contactIO(); + } + + public InfoIO infoIO() { + return context.infoIO(); + } + + public LicenseIO licenseIO() { + return context.licenseIO(); + } + + public LinkIO linkIO() { + return context.linkIO(); + } + + public LinkParameterIO linkParameterIO() { + return context.linkParameterIO(); + } + + public ContentIO contentIO() { + return context.contentIO(); + } + + public DiscriminatorIO discriminatorIO() { + return context.discriminatorIO(); + } + + public EncodingIO encodingIO() { + return context.encodingIO(); + } + + public ExampleObjectIO exampleObjectIO() { + return context.exampleObjectIO(); + } + + public MediaTypeIO mediaTypeIO() { + return context.mediaTypeIO(); + } + + public SchemaIO schemaIO() { + return context.schemaIO(); + } + + public ParameterIO parameterIO() { + return context.parameterIO(); + } + + public RequestBodyIO requestBodyIO() { + return context.requestBodyIO(); + } + + public APIResponseIO apiResponseIO() { + return context.apiResponseIO(); + } + + public APIResponsesIO apiResponsesIO() { + return context.apiResponsesIO(); + } + + public OAuthFlowIO oauthFlowIO() { + return context.oauthFlowIO(); + } + + public OAuthFlowsIO oauthFlowsIO() { + return context.oauthFlowsIO(); + } + + public OAuthScopeIO oauthScopeIO() { + return context.oauthScopeIO(); + } + + public SecurityIO securityIO() { + return context.securityIO(); + } + + public SecurityRequirementIO securityRequirementIO() { + return context.securityRequirementIO(); + } + + public SecurityRequirementsSetIO securityRequirementsSetIO() { + return context.securityRequirementsSetIO(); + } + + public SecuritySchemeIO securitySchemeIO() { + return context.securitySchemeIO(); + } + + public ServerIO serverIO() { + return context.serverIO(); + } + + public ServerVariableIO serverVariableIO() { + return context.serverVariableIO(); + } + + public TagIO tagIO() { + return context.tagIO(); + } + } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/Names.java b/core/src/main/java/io/smallrye/openapi/runtime/io/Names.java index c17591fbe..005ecf5ea 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/Names.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/Names.java @@ -7,6 +7,8 @@ import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.PathItem; +import org.eclipse.microprofile.openapi.annotations.PathItemOperation; import org.eclipse.microprofile.openapi.annotations.callbacks.Callback; import org.eclipse.microprofile.openapi.annotations.callbacks.CallbackOperation; import org.eclipse.microprofile.openapi.annotations.callbacks.Callbacks; @@ -88,6 +90,8 @@ public static DotName containerOf(DotName repeatable) { public static final DotName OPERATION = create(Operation.class); public static final DotName PARAMETER = create(Parameter.class); public static final DotName PARAMETERS = create(Parameters.class); + public static final DotName PATH_ITEM = create(PathItem.class); + public static final DotName PATH_ITEM_OPERATION = create(PathItemOperation.class); public static final DotName REQUEST_BODY = create(RequestBody.class); public static final DotName REQUEST_BODY_SCHEMA = create(RequestBodySchema.class); public static final DotName SCHEMA = create(Schema.class); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/OpenAPIDefinitionIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/OpenAPIDefinitionIO.java index b45cb44ce..a6f7e663c 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/OpenAPIDefinitionIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/OpenAPIDefinitionIO.java @@ -7,16 +7,7 @@ import io.smallrye.openapi.api.SmallRyeOASConfig; import io.smallrye.openapi.api.models.OpenAPIImpl; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.info.InfoIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.media.SchemaIO; -import io.smallrye.openapi.runtime.io.parameters.ParameterIO; -import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; -import io.smallrye.openapi.runtime.io.responses.APIResponsesIO; -import io.smallrye.openapi.runtime.io.security.SecurityIO; -import io.smallrye.openapi.runtime.io.servers.ServerIO; -import io.smallrye.openapi.runtime.io.tags.TagIO; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; public class OpenAPIDefinitionIO extends ModelIO { @@ -29,81 +20,10 @@ public class OpenAPIDefinitionIO extends Mo public static final String PROP_SECURITY_SETS = "securitySets"; public static final String PROP_SERVERS = "servers"; public static final String PROP_TAGS = "tags"; - - private final InfoIO infoIO; - private final TagIO tagIO; - private final ServerIO serverIO; - private final SecurityIO securityIO; - private final PathsIO pathsIO; - private final OperationIO operationIO; - private final ComponentsIO componentIO; - private final APIResponsesIO responsesIO; - private final ExternalDocumentationIO externalDocIO; - private final ParameterIO parameterIO; - private final RequestBodyIO requestBodyIO; - private final SchemaIO schemaIO; - private final ExtensionIO extensionIO; + public static final String PROP_WEBHOOKS = "webhooks"; public OpenAPIDefinitionIO(IOContext context) { super(context, Names.OPENAPI_DEFINITION, Names.create(OpenAPI.class)); - extensionIO = new ExtensionIO<>(context); - ContentIO contentIO = new ContentIO<>(context, extensionIO); - infoIO = new InfoIO<>(context, extensionIO); - tagIO = new TagIO<>(context, extensionIO); - serverIO = new ServerIO<>(context, extensionIO); - securityIO = new SecurityIO<>(context, extensionIO); - operationIO = new OperationIO<>(context, contentIO, extensionIO); - pathsIO = new PathsIO<>(context, operationIO, contentIO, extensionIO); - componentIO = new ComponentsIO<>(context, contentIO, extensionIO); - responsesIO = new APIResponsesIO<>(context, contentIO, extensionIO); - externalDocIO = new ExternalDocumentationIO<>(context, extensionIO); - parameterIO = new ParameterIO<>(context, contentIO, extensionIO); - requestBodyIO = new RequestBodyIO<>(context, contentIO, extensionIO); - schemaIO = new SchemaIO<>(context, extensionIO); - } - - public TagIO tags() { - return tagIO; - } - - public ServerIO servers() { - return serverIO; - } - - public SecurityIO security() { - return securityIO; - } - - public OperationIO operations() { - return operationIO; - } - - public ComponentsIO components() { - return componentIO; - } - - public APIResponsesIO responses() { - return responsesIO; - } - - public ExternalDocumentationIO externalDocumentation() { - return externalDocIO; - } - - public ParameterIO parameters() { - return parameterIO; - } - - public RequestBodyIO requestBodies() { - return requestBodyIO; - } - - public SchemaIO schemas() { - return schemaIO; - } - - public ExtensionIO extensions() { - return extensionIO; } @Override @@ -112,13 +32,15 @@ public OpenAPI read(AnnotationInstance annotation) { OpenAPI openApi = new OpenAPIImpl(); openApi.setOpenapi(SmallRyeOASConfig.Defaults.VERSION); - openApi.setInfo(infoIO.read(annotation.value(PROP_INFO))); - openApi.setTags(tagIO.readList(annotation.value(PROP_TAGS))); - openApi.setServers(serverIO.readList(annotation.value(PROP_SERVERS))); - openApi.setSecurity(securityIO.readRequirements(annotation.value(PROP_SECURITY), annotation.value(PROP_SECURITY_SETS))); - openApi.setExternalDocs(externalDocIO.read(annotation.value(PROP_EXTERNAL_DOCS))); - openApi.setComponents(componentIO.read(annotation.value(PROP_COMPONENTS))); - openApi.setExtensions(extensionIO.readExtensible(annotation)); + openApi.setInfo(infoIO().read(annotation.value(PROP_INFO))); + openApi.setTags(tagIO().readList(annotation.value(PROP_TAGS))); + openApi.setServers(serverIO().readList(annotation.value(PROP_SERVERS))); + openApi.setSecurity( + securityIO().readRequirements(annotation.value(PROP_SECURITY), annotation.value(PROP_SECURITY_SETS))); + openApi.setExternalDocs(extDocIO().read(annotation.value(PROP_EXTERNAL_DOCS))); + openApi.setWebhooks(pathItemIO().readMap(annotation.value(PROP_WEBHOOKS))); + openApi.setComponents(componentsIO().read(annotation.value(PROP_COMPONENTS))); + openApi.setExtensions(extensionIO().readExtensible(annotation)); return openApi; } @@ -132,31 +54,44 @@ public OpenAPI read(AnnotationInstance annotation) { @Override public OpenAPI readObject(O node) { IoLogging.logger.jsonNode("OpenAPIDefinition"); + + String version = jsonIO().getString(node, PROP_OPENAPI); + setOpenApiVersion(OpenApiVersion.fromString(version)); + OpenAPI openApi = new OpenAPIImpl(); - openApi.setOpenapi(jsonIO().getString(node, PROP_OPENAPI)); - openApi.setInfo(infoIO.readValue(jsonIO().getValue(node, PROP_INFO))); - openApi.setTags(tagIO.readList(jsonIO().getValue(node, PROP_TAGS))); - openApi.setServers(serverIO.readList(jsonIO().getValue(node, PROP_SERVERS))); - openApi.setSecurity(securityIO.readRequirements(jsonIO().getValue(node, PROP_SECURITY))); - openApi.setExternalDocs(externalDocIO.readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); - openApi.setComponents(componentIO.readValue(jsonIO().getValue(node, PROP_COMPONENTS))); - openApi.setPaths(pathsIO.readValue(jsonIO().getValue(node, PROP_PATHS))); - openApi.setExtensions(extensionIO.readMap(node)); + openApi.setOpenapi(version); + openApi.setInfo(infoIO().readValue(jsonIO().getValue(node, PROP_INFO))); + openApi.setTags(tagIO().readList(jsonIO().getValue(node, PROP_TAGS))); + openApi.setServers(serverIO().readList(jsonIO().getValue(node, PROP_SERVERS))); + openApi.setSecurity(securityIO().readRequirements(jsonIO().getValue(node, PROP_SECURITY))); + openApi.setExternalDocs(extDocIO().readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); + openApi.setComponents(componentsIO().readValue(jsonIO().getValue(node, PROP_COMPONENTS))); + openApi.setPaths(pathsIO().readValue(jsonIO().getValue(node, PROP_PATHS))); + if (openApiVersion() == OpenApiVersion.V3_1) { + openApi.setWebhooks(pathItemIO().readMap(jsonIO().getValue(node, PROP_WEBHOOKS))); + } + openApi.setExtensions(extensionIO().readMap(node)); return openApi; } @Override public Optional write(OpenAPI model) { + String version = model.getOpenapi(); + setOpenApiVersion(OpenApiVersion.fromString(version)); + return optionalJsonObject(model).map(node -> { - setIfPresent(node, PROP_OPENAPI, jsonIO().toJson(model.getOpenapi())); - setIfPresent(node, PROP_INFO, infoIO.write(model.getInfo())); - setIfPresent(node, PROP_EXTERNAL_DOCS, externalDocIO.write(model.getExternalDocs())); - setIfPresent(node, PROP_SERVERS, serverIO.write(model.getServers())); - setIfPresent(node, PROP_SECURITY, securityIO.write(model.getSecurity())); - setIfPresent(node, PROP_TAGS, tagIO.write(model.getTags())); - setIfPresent(node, PROP_PATHS, pathsIO.write(model.getPaths())); - setIfPresent(node, PROP_COMPONENTS, componentIO.write(model.getComponents())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_OPENAPI, jsonIO().toJson(version)); + setIfPresent(node, PROP_INFO, infoIO().write(model.getInfo())); + setIfPresent(node, PROP_EXTERNAL_DOCS, extDocIO().write(model.getExternalDocs())); + setIfPresent(node, PROP_SERVERS, serverIO().write(model.getServers())); + setIfPresent(node, PROP_SECURITY, securityIO().write(model.getSecurity())); + setIfPresent(node, PROP_TAGS, tagIO().write(model.getTags())); + setIfPresent(node, PROP_PATHS, pathsIO().write(model.getPaths())); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_WEBHOOKS, pathItemIO().write(model.getWebhooks())); + } + setIfPresent(node, PROP_COMPONENTS, componentsIO().write(model.getComponents())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/OpenApiParser.java b/core/src/main/java/io/smallrye/openapi/runtime/io/OpenApiParser.java index 0274bb0ca..b800a67cb 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/OpenApiParser.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/OpenApiParser.java @@ -11,8 +11,6 @@ import io.smallrye.openapi.api.OpenApiConfig; import io.smallrye.openapi.runtime.OpenApiRuntimeException; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.SchemaIO; /** * A class used to parse an OpenAPI document (either YAML or JSON) into a Microprofile OpenAPI model tree. @@ -106,7 +104,7 @@ public static Schema parseSchema(String schemaJson) { private static Schema parseSchema(String schemaJson, JsonIO jsonIO) { IOContext context = IOContext.forJson(jsonIO); V schemaValue = jsonIO.fromString(schemaJson, Format.JSON); - return new SchemaIO<>(context, new ExtensionIO<>(context)).readValue(schemaValue); + return context.schemaIO().readValue(schemaValue); } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/OperationIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/OperationIO.java index 5ce1a56fd..4ebae6059 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/OperationIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/OperationIO.java @@ -8,14 +8,6 @@ import org.jboss.jandex.DotName; import io.smallrye.openapi.api.models.OperationImpl; -import io.smallrye.openapi.runtime.io.callbacks.CallbackIO; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.parameters.ParameterIO; -import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; -import io.smallrye.openapi.runtime.io.responses.APIResponsesIO; -import io.smallrye.openapi.runtime.io.security.SecurityRequirementIO; -import io.smallrye.openapi.runtime.io.servers.ServerIO; public class OperationIO extends ModelIO { @@ -34,36 +26,12 @@ public class OperationIO extends ModelIO responsesIO; - private final CallbackIO callbackIO; - private final ServerIO serverIO; - protected final ExternalDocumentationIO externalDocIO; - private final ParameterIO parameterIO; - private final RequestBodyIO requestBodyIO; - private final SecurityRequirementIO securityRequirementIO; - protected final ExtensionIO extensionIO; - - public OperationIO(IOContext context, ContentIO contentIO, - CallbackIO callbackIO, ExtensionIO extensionIO) { - this(context, Names.OPERATION, contentIO, callbackIO, extensionIO); + public OperationIO(IOContext context) { + this(context, Names.OPERATION); } - public OperationIO(IOContext context, DotName annotationName, ContentIO contentIO, - CallbackIO callbackIO, ExtensionIO extensionIO) { + public OperationIO(IOContext context, DotName annotationName) { super(context, annotationName, Names.create(Operation.class)); - responsesIO = new APIResponsesIO<>(context, contentIO, extensionIO); - this.callbackIO = callbackIO != null ? callbackIO : new CallbackIO<>(context, contentIO, extensionIO); - serverIO = new ServerIO<>(context, extensionIO); - externalDocIO = new ExternalDocumentationIO<>(context, extensionIO); - parameterIO = new ParameterIO<>(context, contentIO, extensionIO); - requestBodyIO = new RequestBodyIO<>(context, contentIO, extensionIO); - securityRequirementIO = new SecurityRequirementIO<>(context); - this.extensionIO = extensionIO; - } - - public OperationIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { - this(context, contentIO, null, extensionIO); } public boolean isHidden(AnnotationTarget target) { @@ -80,7 +48,7 @@ public Operation read(AnnotationInstance annotationInstance) { operation.setDescription(value(annotationInstance, PROP_DESCRIPTION)); operation.setOperationId(value(annotationInstance, PROP_OPERATION_ID)); operation.setDeprecated(value(annotationInstance, PROP_DEPRECATED)); - operation.setExtensions(extensionIO.readExtensible(annotationInstance)); + operation.setExtensions(extensionIO().readExtensible(annotationInstance)); return operation; } @@ -91,16 +59,16 @@ public Operation readObject(O node) { model.setTags(jsonIO().getArray(node, PROP_TAGS, jsonIO()::asString).orElse(null)); model.setSummary(jsonIO().getString(node, PROP_SUMMARY)); model.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - model.setExternalDocs(externalDocIO.readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); + model.setExternalDocs(extDocIO().readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); model.setOperationId(jsonIO().getString(node, PROP_OPERATION_ID)); - model.setParameters(parameterIO.readList(jsonIO().getValue(node, PROP_PARAMETERS))); - model.setRequestBody(requestBodyIO.readValue(jsonIO().getValue(node, PROP_REQUEST_BODY))); - model.setResponses(responsesIO.readValue(jsonIO().getValue(node, PROP_RESPONSES))); - model.setCallbacks(callbackIO.readMap(jsonIO().getValue(node, PROP_CALLBACKS))); + model.setParameters(parameterIO().readList(jsonIO().getValue(node, PROP_PARAMETERS))); + model.setRequestBody(requestBodyIO().readValue(jsonIO().getValue(node, PROP_REQUEST_BODY))); + model.setResponses(apiResponsesIO().readValue(jsonIO().getValue(node, PROP_RESPONSES))); + model.setCallbacks(callbackIO().readMap(jsonIO().getValue(node, PROP_CALLBACKS))); model.setDeprecated(jsonIO().getBoolean(node, PROP_DEPRECATED)); - model.setSecurity(securityRequirementIO.readList(jsonIO().getValue(node, PROP_SECURITY))); - model.setServers(serverIO.readList(jsonIO().getValue(node, PROP_SERVERS))); - extensionIO.readMap(node).forEach(model::addExtension); + model.setSecurity(securityRequirementIO().readList(jsonIO().getValue(node, PROP_SECURITY))); + model.setServers(serverIO().readList(jsonIO().getValue(node, PROP_SERVERS))); + extensionIO().readMap(node).forEach(model::addExtension); return model; } @@ -109,16 +77,16 @@ public Optional write(Operation model) { setIfPresent(node, PROP_TAGS, jsonIO().toJson(model.getTags())); setIfPresent(node, PROP_SUMMARY, jsonIO().toJson(model.getSummary())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_EXTERNAL_DOCS, externalDocIO.write(model.getExternalDocs())); + setIfPresent(node, PROP_EXTERNAL_DOCS, extDocIO().write(model.getExternalDocs())); setIfPresent(node, PROP_OPERATION_ID, jsonIO().toJson(model.getOperationId())); - setIfPresent(node, PROP_PARAMETERS, parameterIO.write(model.getParameters())); - setIfPresent(node, PROP_REQUEST_BODY, requestBodyIO.write(model.getRequestBody())); - setIfPresent(node, PROP_RESPONSES, responsesIO.write(model.getResponses())); - setIfPresent(node, PROP_CALLBACKS, callbackIO.write(model.getCallbacks())); + setIfPresent(node, PROP_PARAMETERS, parameterIO().write(model.getParameters())); + setIfPresent(node, PROP_REQUEST_BODY, requestBodyIO().write(model.getRequestBody())); + setIfPresent(node, PROP_RESPONSES, apiResponsesIO().write(model.getResponses())); + setIfPresent(node, PROP_CALLBACKS, callbackIO().write(model.getCallbacks())); setIfPresent(node, PROP_DEPRECATED, jsonIO().toJson(model.getDeprecated())); - setIfPresent(node, PROP_SECURITY, securityRequirementIO.write(model.getSecurity())); - setIfPresent(node, PROP_SERVERS, serverIO.write(model.getServers())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_SECURITY, securityRequirementIO().write(model.getSecurity())); + setIfPresent(node, PROP_SERVERS, serverIO().write(model.getServers())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemIO.java index 05b830316..a6dba2153 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemIO.java @@ -7,18 +7,16 @@ import java.util.Set; import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.annotations.callbacks.CallbackOperation; import org.eclipse.microprofile.openapi.models.Operation; import org.eclipse.microprofile.openapi.models.PathItem; import org.eclipse.microprofile.openapi.models.PathItem.HttpMethod; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; import io.smallrye.openapi.api.models.PathItemImpl; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.parameters.ParameterIO; -import io.smallrye.openapi.runtime.io.servers.ServerIO; -public class PathItemIO extends ModelIO +public class PathItemIO extends MapModelIO implements ReferenceIO { private static final String PROP_DESCRIPTION = "description"; @@ -31,38 +29,56 @@ public class PathItemIO extends ModelIO serverIO; - protected final OperationIO operationIO; - private final ParameterIO parameterIO; - protected final ExtensionIO extensionIO; - - public PathItemIO(IOContext context, OperationIO operationIO, - ContentIO contentIO, ExtensionIO extensionIO) { - super(context, null, Names.create(PathItem.class)); - serverIO = new ServerIO<>(context, extensionIO); - this.operationIO = operationIO; - parameterIO = new ParameterIO<>(context, contentIO, extensionIO); - this.extensionIO = extensionIO; + // Annotation properties + private static final String PROP_OPERATIONS = "operations"; + + public PathItemIO(IOContext context) { + super(context, Names.PATH_ITEM, Names.create(PathItem.class)); } @Override public PathItem read(AnnotationInstance annotation) { - throw new UnsupportedOperationException("@PathItem annotation does not exist"); + IoLogging.logger.singleAnnotation("@PathItem"); + PathItem pathItem = new PathItemImpl(); + + pathItem.setRef(ReferenceType.PATH_ITEM.refValue(annotation)); + pathItem.setDescription(value(annotation, PROP_DESCRIPTION)); + pathItem.setSummary(value(annotation, PROP_SUMMARY)); + pathItem.setServers(serverIO().readList(annotation.value(PROP_SERVERS))); + pathItem.setParameters(parameterIO().readList(annotation.value(PROP_PARAMETERS))); + + Optional.ofNullable(annotation.value(PROP_OPERATIONS)) + .map(AnnotationValue::asNestedArray) + .ifPresent(annotations -> readOperationsInto(pathItem, annotations, pathItemOperationIO())); + + pathItem.setExtensions(extensionIO().readExtensible(annotation)); + return pathItem; } - public PathItem read(AnnotationInstance[] annotations) { + /** + * Convert an array of {@link CallbackOperation} annotations into a {@code PathItem}. + * + * @param annotations the {@code CallbackOperation} annotation instances + * @return the path item + */ + public PathItem readCallbackOperations(AnnotationInstance[] annotations) { PathItem pathItem = new PathItemImpl(); + readOperationsInto(pathItem, annotations, callbackOperationIO()); + + return pathItem; + } + + private void readOperationsInto(PathItem pathItem, AnnotationInstance[] annotations, + OperationIO operationIO) { Arrays.stream(annotations) .filter(annotation -> Objects.nonNull(value(annotation, "method"))) .forEach(annotation -> { String method = value(annotation, "method"); Operation operation = operationIO.read(annotation); - operation.setExtensions(extensionIO.readExtensible(annotation)); + operation.setExtensions(extensionIO().readExtensible(annotation)); pathItem.setOperation(HttpMethod.valueOf(method.toUpperCase(Locale.ROOT)), operation); }); - - return pathItem; } @Override @@ -78,13 +94,13 @@ public PathItem readObject(O node) { .filter(entry -> OPERATION_PROPS.contains(entry.getKey())) .forEach(entry -> { HttpMethod method = HttpMethod.valueOf(entry.getKey().toUpperCase(Locale.ROOT)); - Operation operation = operationIO.readValue(entry.getValue()); + Operation operation = operationIO().readValue(entry.getValue()); pathItem.setOperation(method, operation); }); - pathItem.setParameters(parameterIO.readList(jsonIO().getValue(node, PROP_PARAMETERS))); - pathItem.setServers(serverIO.readList(jsonIO().getValue(node, PROP_SERVERS))); - pathItem.setExtensions(extensionIO.readObjectMap(node)); + pathItem.setParameters(parameterIO().readList(jsonIO().getValue(node, PROP_PARAMETERS))); + pathItem.setServers(serverIO().readList(jsonIO().getValue(node, PROP_SERVERS))); + pathItem.setExtensions(extensionIO().readObjectMap(node)); return pathItem; } @@ -100,11 +116,12 @@ private OB write(PathItem model, OB node) { setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); model.getOperations() - .forEach((method, operation) -> setIfPresent(node, method.name().toLowerCase(), operationIO.write(operation))); + .forEach( + (method, operation) -> setIfPresent(node, method.name().toLowerCase(), operationIO().write(operation))); - setIfPresent(node, PROP_PARAMETERS, parameterIO.write(model.getParameters())); - setIfPresent(node, PROP_SERVERS, serverIO.write(model.getServers())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_PARAMETERS, parameterIO().write(model.getParameters())); + setIfPresent(node, PROP_SERVERS, serverIO().write(model.getServers())); + setAllIfPresent(node, extensionIO().write(model)); return node; } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemOperationIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemOperationIO.java new file mode 100644 index 000000000..ae413a761 --- /dev/null +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/PathItemOperationIO.java @@ -0,0 +1,76 @@ +package io.smallrye.openapi.runtime.io; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import org.eclipse.microprofile.openapi.models.Operation; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; + +import io.smallrye.openapi.api.models.OperationImpl; +import io.smallrye.openapi.runtime.util.ModelUtil; + +public class PathItemOperationIO extends OperationIO { + + public PathItemOperationIO(IOContext context) { + super(context, Names.PATH_ITEM_OPERATION); + } + + @Override + public Operation read(AnnotationInstance annotation) { + IoLogging.logger.singleAnnotation("@PathItemOperation"); + Operation operation = new OperationImpl(); + + operation.setTags(processTags(annotation.value(PROP_TAGS))); + operation.setSummary(value(annotation, PROP_SUMMARY)); + operation.setDescription(value(annotation, PROP_DESCRIPTION)); + operation.setExternalDocs(extDocIO().read(annotation.value(PROP_EXTERNAL_DOCS))); + operation.setOperationId(value(annotation, PROP_OPERATION_ID)); + operation.setParameters(parameterIO().readList(annotation.value(PROP_PARAMETERS))); + operation.setRequestBody(requestBodyIO().read(annotation.value(PROP_REQUEST_BODY))); + operation.setResponses(apiResponsesIO().read(annotation.value(PROP_RESPONSES))); + operation.setCallbacks(callbackIO().readMap(annotation.value(PROP_CALLBACKS))); + operation.setDeprecated(value(annotation, PROP_DEPRECATED)); + operation.setSecurity(securityIO().readRequirements( + annotation.value(PROP_SECURITY), + annotation.value(PROP_SECURITY_SETS))); + operation.setServers(serverIO().readList(annotation.value(PROP_SERVERS))); + operation.setExtensions(extensionIO().readExtensible(annotation)); + + return operation; + } + + private List processTags(AnnotationValue tagAnnotations) { + return Optional.ofNullable(tagAnnotations) + .map(AnnotationValue::asNestedArray) + .map(this::processTags) + .orElse(null); + } + + /** + * Read an array of {@code Tag} annotations, collecting the names and adding any new definitions to the top-level OpenAPI + * object. + * + * @param tagAnnotations the annotations + * @return the list of tag names + */ + private List processTags(AnnotationInstance[] tagAnnotations) { + Set tagNames = new LinkedHashSet<>(); + + tagIO().readList(tagAnnotations) + .stream() + .filter(tag -> Objects.nonNull(tag.getName())) + .forEach(tag -> { + tagNames.add(tag.getName()); + ModelUtil.addTag(scannerContext().getOpenApi(), tag); + }); + + tagIO().readReferences(tagAnnotations).forEach(tagNames::add); + + return new ArrayList<>(tagNames); + } +} diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/PathsIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/PathsIO.java index 82832a28a..132e11f65 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/PathsIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/PathsIO.java @@ -7,18 +7,11 @@ import io.smallrye.openapi.api.models.PathsImpl; import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; public class PathsIO extends ModelIO { - private final PathItemIO pathItemIO; - private final ExtensionIO extensionIO; - - public PathsIO(IOContext context, OperationIO operationIO, - ContentIO contentIO, ExtensionIO extensionIO) { + public PathsIO(IOContext context) { super(context, null, Names.create(Paths.class)); - pathItemIO = new PathItemIO<>(context, operationIO, contentIO, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -35,19 +28,19 @@ public Paths readObject(O node) { .stream() .filter(not(ExtensionIO::isExtension)) .filter(property -> jsonIO().isObject(property.getValue())) - .map(property -> entry(property.getKey(), pathItemIO.readObject(jsonIO().asObject(property.getValue())))) + .map(property -> entry(property.getKey(), pathItemIO().readObject(jsonIO().asObject(property.getValue())))) .forEach(pathItem -> paths.addPathItem(pathItem.getKey(), pathItem.getValue())); - extensionIO.readMap(node).forEach(paths::addExtension); + extensionIO().readMap(node).forEach(paths::addExtension); return paths; } public Optional write(Paths paths) { return optionalJsonObject(paths).map(pathsNode -> { if (paths.getPathItems() != null) { - paths.getPathItems().forEach((path, pathItem) -> setIfPresent(pathsNode, path, pathItemIO.write(pathItem))); + paths.getPathItems().forEach((path, pathItem) -> setIfPresent(pathsNode, path, pathItemIO().write(pathItem))); } - setAllIfPresent(pathsNode, extensionIO.write(paths)); + setAllIfPresent(pathsNode, extensionIO().write(paths)); return pathsNode; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/ReferenceType.java b/core/src/main/java/io/smallrye/openapi/runtime/io/ReferenceType.java index 444b85ef7..b2956babf 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/ReferenceType.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/ReferenceType.java @@ -20,7 +20,8 @@ public enum ReferenceType { RESPONSE("responses"), PARAMETER("parameters"), EXAMPLE("examples"), - REQUEST_BODY("requestBodies"); + REQUEST_BODY("requestBodies"), + PATH_ITEM("pathItems"); private static final Pattern COMPONENT_KEY_PATTERN = Pattern.compile("^[a-zA-Z0-9\\.\\-_]+$"); public static final String PROP_ANNOTATION = "ref"; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackIO.java index d15764a99..ad9c03295 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackIO.java @@ -6,33 +6,25 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.DotName; +import io.smallrye.openapi.api.models.PathItemImpl; import io.smallrye.openapi.api.models.callbacks.CallbackImpl; import io.smallrye.openapi.runtime.io.IOContext; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.PathItemIO; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; public class CallbackIO extends MapModelIO implements ReferenceIO { private static final String PROP_OPERATIONS = "operations"; private static final String PROP_CALLBACK_URL_EXPRESSION = "callbackUrlExpression"; + private static final String PROP_PATH_ITEM_REF = "pathItemRef"; - private final CallbackOperationIO callbackOperationIO; - private final PathItemIO pathItemIO; - private final ExtensionIO extensionIO; - - public CallbackIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public CallbackIO(IOContext context) { super(context, Names.CALLBACK, DotName.createSimple(Callback.class)); - callbackOperationIO = new CallbackOperationIO<>(context, contentIO, this, extensionIO); - pathItemIO = new PathItemIO<>(context, callbackOperationIO, contentIO, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -41,14 +33,20 @@ public Callback read(AnnotationInstance annotation) { Callback callback = new CallbackImpl(); callback.setRef(ReferenceType.CALLBACK.refValue(annotation)); + Optional.ofNullable(this. value(annotation, PROP_PATH_ITEM_REF)) + .map(ReferenceType.PATH_ITEM::referenceOf) + .ifPresent(ref -> callback.addPathItem( + value(annotation, PROP_CALLBACK_URL_EXPRESSION), + new PathItemImpl().ref(ref))); + Optional.ofNullable(value(annotation, PROP_OPERATIONS)) .map(AnnotationInstance[].class::cast) - .map(pathItemIO::read) + .map(pathItemIO()::readCallbackOperations) .ifPresent(pathItem -> callback.addPathItem( value(annotation, PROP_CALLBACK_URL_EXPRESSION), pathItem)); - callback.setExtensions(extensionIO.readExtensible(annotation)); + callback.setExtensions(extensionIO().readExtensible(annotation)); return callback; } @@ -63,10 +61,10 @@ public Callback readObject(O node) { .filter(not(ExtensionIO::isExtension)) .filter(not(this::isReference)) .filter(property -> jsonIO().isObject(property.getValue())) - .map(property -> entry(property.getKey(), pathItemIO.readValue(property.getValue()))) + .map(property -> entry(property.getKey(), pathItemIO().readValue(property.getValue()))) .forEach(pathItem -> callback.addPathItem(pathItem.getKey(), pathItem.getValue())); - extensionIO.readMap(node).forEach(callback::addExtension); + extensionIO().readMap(node).forEach(callback::addExtension); return callback; } @@ -78,9 +76,10 @@ public Optional write(Callback model) { setReference(node, model); } else { Optional.ofNullable(model.getPathItems()) - .ifPresent(items -> items.forEach((key, value) -> setIfPresent(node, key, pathItemIO.write(value)))); + .ifPresent(items -> items + .forEach((key, value) -> setIfPresent(node, key, pathItemIO().write(value)))); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); } return node; }).map(jsonIO()::buildObject); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackOperationIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackOperationIO.java index b801dd9c4..5cc58e912 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackOperationIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/callbacks/CallbackOperationIO.java @@ -8,24 +8,11 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.OperationIO; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.parameters.ParameterIO; -import io.smallrye.openapi.runtime.io.parameters.RequestBodyIO; -import io.smallrye.openapi.runtime.io.security.SecurityIO; public class CallbackOperationIO extends OperationIO { - private final RequestBodyIO requestBodyIO; - private final ParameterIO parameterIO; - private final SecurityIO securityIO; - - public CallbackOperationIO(IOContext context, ContentIO contentIO, - CallbackIO callbackIO, ExtensionIO extensionIO) { - super(context, Names.CALLBACK_OPERATION, contentIO, callbackIO, extensionIO); - parameterIO = new ParameterIO<>(context, contentIO, extensionIO); - requestBodyIO = new RequestBodyIO<>(context, contentIO, extensionIO); - securityIO = new SecurityIO<>(context, extensionIO); + public CallbackOperationIO(IOContext context) { + super(context, Names.CALLBACK_OPERATION); } @Override @@ -34,14 +21,14 @@ public Operation read(AnnotationInstance annotation) { Operation operation = new OperationImpl(); operation.setSummary(value(annotation, PROP_SUMMARY)); operation.setDescription(value(annotation, PROP_DESCRIPTION)); - operation.setExternalDocs(externalDocIO.read(annotation.value(PROP_EXTERNAL_DOCS))); - operation.setParameters(parameterIO.readList(annotation.value(PROP_PARAMETERS))); - operation.setRequestBody(requestBodyIO.read(annotation.value(PROP_REQUEST_BODY))); - operation.setResponses(responsesIO.read(annotation.value(PROP_RESPONSES))); - operation.setSecurity(securityIO.readRequirements( + operation.setExternalDocs(extDocIO().read(annotation.value(PROP_EXTERNAL_DOCS))); + operation.setParameters(parameterIO().readList(annotation.value(PROP_PARAMETERS))); + operation.setRequestBody(requestBodyIO().read(annotation.value(PROP_REQUEST_BODY))); + operation.setResponses(apiResponsesIO().read(annotation.value(PROP_RESPONSES))); + operation.setSecurity(securityIO().readRequirements( annotation.value(PROP_SECURITY), annotation.value(PROP_SECURITY_SETS))); - operation.setExtensions(extensionIO.readExtensible(annotation)); + operation.setExtensions(extensionIO().readExtensible(annotation)); operation.setOperationId(value(annotation, PROP_OPERATION_ID)); operation.setDeprecated(value(annotation, PROP_DEPRECATED)); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java index a29728b38..289538054 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java @@ -12,10 +12,6 @@ import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.media.ExampleObjectIO; -import io.smallrye.openapi.runtime.io.media.SchemaIO; public class HeaderIO extends MapModelIO implements ReferenceIO { @@ -31,18 +27,8 @@ public class HeaderIO extends MapModelIO schemaIO; - private final ContentIO contentIO; - private final ExampleObjectIO exampleObjectIO; - private final ExtensionIO extensionIO; - - public HeaderIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public HeaderIO(IOContext context) { super(context, Names.HEADER, Names.create(Header.class)); - this.contentIO = contentIO; - exampleObjectIO = new ExampleObjectIO<>(context, extensionIO); - schemaIO = new SchemaIO<>(context, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -51,11 +37,11 @@ public Header read(AnnotationInstance annotation) { Header header = new HeaderImpl(); header.setRef(ReferenceType.HEADER.refValue(annotation)); header.setDescription(value(annotation, PROP_DESCRIPTION)); - header.setSchema(schemaIO.read(annotation.value(PROP_SCHEMA))); + header.setSchema(schemaIO().read(annotation.value(PROP_SCHEMA))); header.setRequired(value(annotation, PROP_REQUIRED)); header.setDeprecated(value(annotation, PROP_DEPRECATED)); header.setAllowEmptyValue(value(annotation, PROP_ALLOW_EMPTY_VALUE)); - header.setExtensions(extensionIO.readExtensible(annotation)); + header.setExtensions(extensionIO().readExtensible(annotation)); return header; } @@ -65,16 +51,16 @@ public Header readObject(O node) { Header header = new HeaderImpl(); header.setRef(readReference(node)); header.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - header.setSchema(schemaIO.readValue(jsonIO().getValue(node, PROP_SCHEMA))); + header.setSchema(schemaIO().readValue(jsonIO().getValue(node, PROP_SCHEMA))); header.setRequired(jsonIO().getBoolean(node, PROP_REQUIRED)); header.setDeprecated(jsonIO().getBoolean(node, PROP_DEPRECATED)); header.setAllowEmptyValue(jsonIO().getBoolean(node, PROP_ALLOW_EMPTY_VALUE)); header.setStyle(enumValue(jsonIO().getValue(node, PROP_STYLE), Header.Style.class)); header.setExplode(jsonIO().getBoolean(node, PROP_EXPLODE)); header.setExample(jsonIO().fromJson(jsonIO().getValue(node, PROP_EXAMPLE))); - header.setExamples(exampleObjectIO.readMap(jsonIO().getValue(node, PROP_EXAMPLES))); - header.setContent(contentIO.readValue(jsonIO().getValue(node, PROP_CONTENT))); - header.setExtensions(extensionIO.readMap(node)); + header.setExamples(exampleObjectIO().readMap(jsonIO().getValue(node, PROP_EXAMPLES))); + header.setContent(contentIO().readValue(jsonIO().getValue(node, PROP_CONTENT))); + header.setExtensions(extensionIO().readMap(node)); return header; } @@ -83,6 +69,7 @@ public Optional write(Header model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); } else { setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, PROP_REQUIRED, jsonIO().toJson(model.getRequired())); @@ -90,11 +77,11 @@ public Optional write(Header model) { setIfPresent(node, PROP_ALLOW_EMPTY_VALUE, jsonIO().toJson(model.getAllowEmptyValue())); setIfPresent(node, PROP_STYLE, jsonIO().toJson(model.getStyle())); setIfPresent(node, PROP_EXPLODE, jsonIO().toJson(model.getExplode())); - setIfPresent(node, PROP_SCHEMA, schemaIO.write(model.getSchema())); + setIfPresent(node, PROP_SCHEMA, schemaIO().write(model.getSchema())); setIfPresent(node, PROP_EXAMPLE, jsonIO().toJson(model.getExample())); - setIfPresent(node, PROP_EXAMPLES, exampleObjectIO.write(model.getExamples())); - setIfPresent(node, PROP_CONTENT, contentIO.write(model.getContent())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_EXAMPLES, exampleObjectIO().write(model.getExamples())); + setIfPresent(node, PROP_CONTENT, contentIO().write(model.getContent())); + setAllIfPresent(node, extensionIO().write(model)); } return node; }).map(jsonIO()::buildObject); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/info/ContactIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/info/ContactIO.java index 875907284..2b8ee9df5 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/info/ContactIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/info/ContactIO.java @@ -10,7 +10,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class ContactIO extends ModelIO { @@ -18,11 +17,8 @@ public class ContactIO extends ModelIO extensionIO; - - public ContactIO(IOContext context, ExtensionIO extensionIO) { + public ContactIO(IOContext context) { super(context, Names.CONTACT, Names.create(Contact.class)); - this.extensionIO = extensionIO; } @Override @@ -32,7 +28,7 @@ public Contact read(AnnotationInstance annotation) { contact.setName(value(annotation, PROP_NAME)); contact.setUrl(value(annotation, PROP_URL)); contact.setEmail(value(annotation, PROP_EMAIL)); - contact.setExtensions(extensionIO.readExtensible(annotation)); + contact.setExtensions(extensionIO().readExtensible(annotation)); return contact; } @@ -43,7 +39,7 @@ public Contact readObject(O node) { contact.setName(jsonIO().getString(node, PROP_NAME)); contact.setUrl(jsonIO().getString(node, PROP_URL)); contact.setEmail(jsonIO().getString(node, PROP_EMAIL)); - extensionIO.readMap(node).forEach(contact::addExtension); + extensionIO().readMap(node).forEach(contact::addExtension); return contact; } @@ -53,7 +49,7 @@ public Optional write(Contact model) { setIfPresent(node, PROP_NAME, jsonIO().toJson(model.getName())); setIfPresent(node, PROP_URL, jsonIO().toJson(model.getUrl())); setIfPresent(node, PROP_EMAIL, jsonIO().toJson(model.getEmail())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/info/InfoIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/info/InfoIO.java index 6ac2b7787..d71ea1917 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/info/InfoIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/info/InfoIO.java @@ -7,10 +7,10 @@ import io.smallrye.openapi.api.models.info.InfoImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class InfoIO extends ModelIO { @@ -20,16 +20,10 @@ public class InfoIO extends ModelIO contact; - private final LicenseIO license; - private final ExtensionIO extensionIO; - - public InfoIO(IOContext context, ExtensionIO extensionIO) { + public InfoIO(IOContext context) { super(context, Names.INFO, Names.create(Info.class)); - contact = new ContactIO<>(context, extensionIO); - license = new LicenseIO<>(context, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -38,11 +32,12 @@ public Info read(AnnotationInstance annotation) { Info info = new InfoImpl(); info.setTitle(value(annotation, PROP_TITLE)); info.setDescription(value(annotation, PROP_DESCRIPTION)); + info.setSummary(value(annotation, PROP_SUMMARY)); info.setTermsOfService(value(annotation, PROP_TERMS_OF_SERVICE)); - info.setContact(contact.read(annotation.value(PROP_CONTACT))); - info.setLicense(license.read(annotation.value(PROP_LICENSE))); + info.setContact(contactIO().read(annotation.value(PROP_CONTACT))); + info.setLicense(licenseIO().read(annotation.value(PROP_LICENSE))); info.setVersion(value(annotation, PROP_VERSION)); - info.setExtensions(extensionIO.readExtensible(annotation)); + info.setExtensions(extensionIO().readExtensible(annotation)); return info; } @@ -58,11 +53,14 @@ public Info readObject(O node) { Info info = new InfoImpl(); info.setTitle(jsonIO().getString(node, PROP_TITLE)); info.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); + if (openApiVersion() == OpenApiVersion.V3_1) { + info.setSummary(jsonIO().getString(node, PROP_SUMMARY)); + } info.setTermsOfService(jsonIO().getString(node, PROP_TERMS_OF_SERVICE)); - info.setContact(contact.readValue(jsonIO().getValue(node, PROP_CONTACT))); - info.setLicense(license.readValue(jsonIO().getValue(node, PROP_LICENSE))); + info.setContact(contactIO().readValue(jsonIO().getValue(node, PROP_CONTACT))); + info.setLicense(licenseIO().readValue(jsonIO().getValue(node, PROP_LICENSE))); info.setVersion(jsonIO().getString(node, PROP_VERSION)); - info.setExtensions(extensionIO.readMap(node)); + info.setExtensions(extensionIO().readMap(node)); return info; } @@ -70,11 +68,14 @@ public Optional write(Info model) { return optionalJsonObject(model).map(node -> { setIfPresent(node, PROP_TITLE, jsonIO().toJson(model.getTitle())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_SUMMARY, jsonIO().toJson(model.getSummary())); + } setIfPresent(node, PROP_TERMS_OF_SERVICE, jsonIO().toJson(model.getTermsOfService())); - setIfPresent(node, PROP_CONTACT, contact.write(model.getContact())); - setIfPresent(node, PROP_LICENSE, license.write(model.getLicense())); + setIfPresent(node, PROP_CONTACT, contactIO().write(model.getContact())); + setIfPresent(node, PROP_LICENSE, licenseIO().write(model.getLicense())); setIfPresent(node, PROP_VERSION, jsonIO().toJson(model.getVersion())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/info/LicenseIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/info/LicenseIO.java index 3815fc888..6381e415b 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/info/LicenseIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/info/LicenseIO.java @@ -7,21 +7,19 @@ import io.smallrye.openapi.api.models.info.LicenseImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class LicenseIO extends ModelIO { private static final String PROP_NAME = "name"; private static final String PROP_URL = "url"; + private static final String PROP_IDENTIFIER = "identifier"; - private final ExtensionIO extensionIO; - - public LicenseIO(IOContext context, ExtensionIO extensionIO) { + public LicenseIO(IOContext context) { super(context, Names.LICENSE, Names.create(License.class)); - this.extensionIO = extensionIO; } @Override @@ -30,7 +28,8 @@ public License read(AnnotationInstance annotation) { License license = new LicenseImpl(); license.setName(value(annotation, PROP_NAME)); license.setUrl(value(annotation, PROP_URL)); - license.setExtensions(extensionIO.readExtensible(annotation)); + license.setIdentifier(value(annotation, PROP_IDENTIFIER)); + license.setExtensions(extensionIO().readExtensible(annotation)); return license; } @@ -40,7 +39,10 @@ public License readObject(O node) { License license = new LicenseImpl(); license.setName(jsonIO().getString(node, PROP_NAME)); license.setUrl(jsonIO().getString(node, PROP_URL)); - license.setExtensions(extensionIO.readMap(node)); + if (openApiVersion() == OpenApiVersion.V3_1) { + license.setIdentifier(jsonIO().getString(node, PROP_IDENTIFIER)); + } + license.setExtensions(extensionIO().readMap(node)); return license; } @@ -48,7 +50,10 @@ public Optional write(License model) { return optionalJsonObject(model).map(node -> { setIfPresent(node, PROP_NAME, jsonIO().toJson(model.getName())); setIfPresent(node, PROP_URL, jsonIO().toJson(model.getUrl())); - setAllIfPresent(node, extensionIO.write(model)); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_IDENTIFIER, jsonIO().toJson(model.getIdentifier())); + } + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkIO.java index 12f895717..dcfee530d 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkIO.java @@ -7,13 +7,12 @@ import io.smallrye.openapi.api.models.links.LinkImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.servers.ServerIO; public class LinkIO extends MapModelIO implements ReferenceIO { @@ -25,15 +24,8 @@ public class LinkIO extends MapModelIO serverIO; - private final LinkParameterIO linkParameterIO; - private final ExtensionIO extensionIO; - - public LinkIO(IOContext context, ExtensionIO extensionIO) { + public LinkIO(IOContext context) { super(context, Names.LINK, Names.create(Link.class)); - serverIO = new ServerIO<>(context, extensionIO); - linkParameterIO = new LinkParameterIO<>(context); - this.extensionIO = extensionIO; } @Override @@ -42,12 +34,12 @@ public Link read(AnnotationInstance annotationInstance) { Link link = new LinkImpl(); link.setOperationRef(value(annotationInstance, PROP_OPERATION_REF)); link.setOperationId(value(annotationInstance, PROP_OPERATION_ID)); - link.setParameters(linkParameterIO.readMap(annotationInstance.value(PROP_PARAMETERS))); + link.setParameters(linkParameterIO().readMap(annotationInstance.value(PROP_PARAMETERS))); link.setDescription(value(annotationInstance, PROP_DESCRIPTION)); link.setRequestBody(value(annotationInstance, PROP_REQUEST_BODY)); - link.setServer(serverIO.read(annotationInstance.value(PROP_SERVER))); + link.setServer(serverIO().read(annotationInstance.value(PROP_SERVER))); link.setRef(ReferenceType.LINK.refValue(annotationInstance)); - link.setExtensions(extensionIO.readExtensible(annotationInstance)); + link.setExtensions(extensionIO().readExtensible(annotationInstance)); return link; } @@ -58,11 +50,11 @@ public Link readObject(O node) { link.setRef(readReference(node)); link.setOperationRef(jsonIO().getString(node, PROP_OPERATION_REF)); link.setOperationId(jsonIO().getString(node, PROP_OPERATION_ID)); - link.setParameters(linkParameterIO.readMap(jsonIO().getValue(node, PROP_PARAMETERS))); + link.setParameters(linkParameterIO().readMap(jsonIO().getValue(node, PROP_PARAMETERS))); link.setRequestBody(jsonIO().fromJson(jsonIO().getValue(node, PROP_REQUEST_BODY))); link.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - link.setServer(serverIO.readValue(jsonIO().getValue(node, PROP_SERVER))); - extensionIO.readMap(node).forEach(link::addExtension); + link.setServer(serverIO().readValue(jsonIO().getValue(node, PROP_SERVER))); + extensionIO().readMap(node).forEach(link::addExtension); return link; } @@ -70,14 +62,17 @@ public Optional write(Link model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_OPERATION_REF, jsonIO().toJson(model.getOperationRef())); setIfPresent(node, PROP_OPERATION_ID, jsonIO().toJson(model.getOperationId())); - setIfPresent(node, PROP_PARAMETERS, linkParameterIO.write(model.getParameters())); + setIfPresent(node, PROP_PARAMETERS, linkParameterIO().write(model.getParameters())); setIfPresent(node, PROP_REQUEST_BODY, jsonIO().toJson(model.getRequestBody())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_SERVER, serverIO.write(model.getServer())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_SERVER, serverIO().write(model.getServer())); + setAllIfPresent(node, extensionIO().write(model)); } return node; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkParameterIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkParameterIO.java index 649d1b79d..de0733f07 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkParameterIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/links/LinkParameterIO.java @@ -14,7 +14,7 @@ public class LinkParameterIO extends MapMod private static final String PROP_EXPRESSION = "expression"; - protected LinkParameterIO(IOContext context) { + public LinkParameterIO(IOContext context) { super(context, Names.OAUTH_SCOPE, Names.create(String.class)); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/media/ContentIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/media/ContentIO.java index bc3057a46..e6c8b29c9 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/media/ContentIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/media/ContentIO.java @@ -12,7 +12,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class ContentIO extends ModelIO { @@ -35,11 +34,8 @@ public static String[] defaultMediaTypes() { return new String[] { "*/*" }; } - private final MediaTypeIO mediaTypeIO; - - public ContentIO(IOContext context, ExtensionIO extensionIO) { + public ContentIO(IOContext context) { super(context, Names.CONTENT, Names.create(Content.class)); - mediaTypeIO = new MediaTypeIO<>(context, this, extensionIO); } public Content read(AnnotationValue annotations, Direction direction) { @@ -55,7 +51,7 @@ private Content read(AnnotationInstance[] annotations, Direction direction) { for (AnnotationInstance annotation : annotations) { String contentType = value(annotation, PROP_MEDIA_TYPE); - MediaType mediaTypeModel = mediaTypeIO.read(annotation); + MediaType mediaTypeModel = mediaTypeIO().read(annotation); if (contentType == null) { for (String mimeType : getDefaultMimeTypes(direction)) { @@ -96,7 +92,7 @@ public Content readObject(O node) { Content content = new ContentImpl(); jsonIO().properties(node) - .forEach(property -> content.addMediaType(property.getKey(), mediaTypeIO.readValue(property.getValue()))); + .forEach(property -> content.addMediaType(property.getKey(), mediaTypeIO().readValue(property.getValue()))); return content; } @@ -105,7 +101,7 @@ public Content readObject(O node) { public Optional write(Content model) { return optionalJsonObject(model).map(node -> { if (model.getMediaTypes() != null) { - model.getMediaTypes().forEach((key, mediaType) -> setIfPresent(node, key, mediaTypeIO.write(mediaType))); + model.getMediaTypes().forEach((key, mediaType) -> setIfPresent(node, key, mediaTypeIO().write(mediaType))); } return node; }).map(jsonIO()::buildObject); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/media/EncodingIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/media/EncodingIO.java index d0ceed974..273d5dfcd 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/media/EncodingIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/media/EncodingIO.java @@ -13,8 +13,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.headers.HeaderIO; public class EncodingIO extends MapModelIO { @@ -24,14 +22,8 @@ public class EncodingIO extends MapModelIO< private static final String PROP_EXPLODE = "explode"; private static final String PROP_STYLE = "style"; - private final HeaderIO headerIO; - private final ExtensionIO extensionIO; - - public EncodingIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public EncodingIO(IOContext context) { super(context, Names.ENCODING, Names.create(Encoding.class)); - headerIO = new HeaderIO<>(context, contentIO, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -42,8 +34,8 @@ public Encoding read(AnnotationInstance annotation) { encoding.setStyle(readStyle(annotation)); encoding.setExplode(value(annotation, PROP_EXPLODE)); encoding.setAllowReserved(value(annotation, PROP_ALLOW_RESERVED)); - encoding.setHeaders(headerIO.readMap(annotation.value(PROP_HEADERS))); - encoding.setExtensions(extensionIO.readExtensible(annotation)); + encoding.setHeaders(headerIO().readMap(annotation.value(PROP_HEADERS))); + encoding.setExtensions(extensionIO().readExtensible(annotation)); return encoding; } @@ -52,11 +44,11 @@ public Encoding readObject(O node) { IoLogging.logger.singleJsonNode("Encoding"); Encoding encoding = new EncodingImpl(); encoding.setContentType(jsonIO().getString(node, PROP_CONTENT_TYPE)); - encoding.setHeaders(headerIO.readMap(jsonIO().getValue(node, PROP_HEADERS))); + encoding.setHeaders(headerIO().readMap(jsonIO().getValue(node, PROP_HEADERS))); encoding.setStyle(readStyle(jsonIO().getValue(node, PROP_STYLE))); encoding.setExplode(jsonIO().getBoolean(node, PROP_EXPLODE)); encoding.setAllowReserved(jsonIO().getBoolean(node, PROP_ALLOW_RESERVED)); - encoding.setExtensions(extensionIO.readMap(node)); + encoding.setExtensions(extensionIO().readMap(node)); return encoding; } @@ -64,11 +56,11 @@ public Encoding readObject(O node) { public Optional write(Encoding model) { return optionalJsonObject(model).map(node -> { setIfPresent(node, PROP_CONTENT_TYPE, jsonIO().toJson(model.getContentType())); - setIfPresent(node, PROP_HEADERS, headerIO.write(model.getHeaders())); + setIfPresent(node, PROP_HEADERS, headerIO().write(model.getHeaders())); setIfPresent(node, PROP_STYLE, jsonIO().toJson(model.getStyle())); setIfPresent(node, PROP_EXPLODE, jsonIO().toJson(model.getExplode())); setIfPresent(node, PROP_ALLOW_RESERVED, jsonIO().toJson(model.getAllowReserved())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/media/ExampleObjectIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/media/ExampleObjectIO.java index f2350622e..0184ce48f 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/media/ExampleObjectIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/media/ExampleObjectIO.java @@ -7,12 +7,12 @@ import io.smallrye.openapi.api.models.examples.ExampleImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; import io.smallrye.openapi.runtime.scanner.AnnotationScannerExtension; public class ExampleObjectIO extends MapModelIO @@ -23,11 +23,8 @@ public class ExampleObjectIO extends MapMod private static final String PROP_EXTERNAL_VALUE = "externalValue"; private static final String PROP_DESCRIPTION = "description"; - private final ExtensionIO extensionIO; - - public ExampleObjectIO(IOContext context, ExtensionIO extensionIO) { + public ExampleObjectIO(IOContext context) { super(context, Names.EXAMPLE_OBJECT, Names.create(Example.class)); - this.extensionIO = extensionIO; } @Override @@ -39,7 +36,7 @@ public Example read(AnnotationInstance annotation) { example.setDescription(value(annotation, PROP_DESCRIPTION)); example.setValue(parseValue(value(annotation, PROP_VALUE))); example.setExternalValue(value(annotation, PROP_EXTERNAL_VALUE)); - example.setExtensions(extensionIO.readExtensible(annotation)); + example.setExtensions(extensionIO().readExtensible(annotation)); return example; } @@ -52,7 +49,7 @@ public Example readObject(O node) { example.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); example.setValue(jsonIO().fromJson(jsonIO().getValue(node, PROP_VALUE))); example.setExternalValue(jsonIO().getString(node, PROP_EXTERNAL_VALUE)); - example.setExtensions(extensionIO.readMap(node)); + example.setExtensions(extensionIO().readMap(node)); return example; } @@ -60,12 +57,16 @@ public Optional write(Example model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_SUMMARY, jsonIO().toJson(model.getSummary())); + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_SUMMARY, jsonIO().toJson(model.getSummary())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, PROP_VALUE, jsonIO().toJson(model.getValue())); setIfPresent(node, PROP_EXTERNAL_VALUE, jsonIO().toJson(model.getExternalValue())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); } return node; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/media/MediaTypeIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/media/MediaTypeIO.java index 422642f8e..35f7f651e 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/media/MediaTypeIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/media/MediaTypeIO.java @@ -10,7 +10,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class MediaTypeIO extends ModelIO { @@ -19,29 +18,19 @@ public class MediaTypeIO extends ModelIO schemaIO; - private final ExampleObjectIO exampleObjectIO; - private final EncodingIO encodingIO; - private final ExtensionIO extensionIO; - - public MediaTypeIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public MediaTypeIO(IOContext context) { super(context, null, Names.create(MediaType.class)); - schemaIO = new SchemaIO<>(context, extensionIO); - exampleObjectIO = new ExampleObjectIO<>(context, extensionIO); - encodingIO = new EncodingIO<>(context, contentIO, extensionIO); - this.extensionIO = extensionIO; } @Override public MediaType read(AnnotationInstance annotation) { IoLogging.logger.singleAnnotationAs("@Content", "MediaType"); MediaType mediaType = new MediaTypeImpl(); - mediaType.setExamples(exampleObjectIO.readMap(annotation.value(PROP_EXAMPLES))); - mediaType.setExample(exampleObjectIO.parseValue(value(annotation, PROP_EXAMPLE))); - mediaType.setSchema(schemaIO.read(annotation.value(PROP_SCHEMA))); - mediaType.setEncoding(encodingIO.readMap(annotation.value(PROP_ENCODING))); - mediaType.setExtensions(extensionIO.readExtensible(annotation)); + mediaType.setExamples(exampleObjectIO().readMap(annotation.value(PROP_EXAMPLES))); + mediaType.setExample(exampleObjectIO().parseValue(value(annotation, PROP_EXAMPLE))); + mediaType.setSchema(schemaIO().read(annotation.value(PROP_SCHEMA))); + mediaType.setEncoding(encodingIO().readMap(annotation.value(PROP_ENCODING))); + mediaType.setExtensions(extensionIO().readExtensible(annotation)); return mediaType; } @@ -49,21 +38,21 @@ public MediaType read(AnnotationInstance annotation) { public MediaType readObject(O node) { IoLogging.logger.singleJsonNode("Content"); MediaType mediaType = new MediaTypeImpl(); - mediaType.setSchema(schemaIO.readValue(jsonIO().getValue(node, PROP_SCHEMA))); + mediaType.setSchema(schemaIO().readValue(jsonIO().getValue(node, PROP_SCHEMA))); mediaType.setExample(jsonIO().fromJson(jsonIO().getValue(node, PROP_EXAMPLE))); - mediaType.setExamples(exampleObjectIO.readMap(jsonIO().getValue(node, PROP_EXAMPLES))); - mediaType.setEncoding(encodingIO.readMap(jsonIO().getValue(node, PROP_ENCODING))); - extensionIO.readMap(node).forEach(mediaType::addExtension); + mediaType.setExamples(exampleObjectIO().readMap(jsonIO().getValue(node, PROP_EXAMPLES))); + mediaType.setEncoding(encodingIO().readMap(jsonIO().getValue(node, PROP_ENCODING))); + extensionIO().readMap(node).forEach(mediaType::addExtension); return mediaType; } public Optional write(MediaType model) { return optionalJsonObject(model).map(node -> { - setIfPresent(node, PROP_SCHEMA, schemaIO.write(model.getSchema())); + setIfPresent(node, PROP_SCHEMA, schemaIO().write(model.getSchema())); setIfPresent(node, PROP_EXAMPLE, jsonIO().toJson(model.getExample())); - setIfPresent(node, PROP_EXAMPLES, exampleObjectIO.write(model.getExamples())); - setIfPresent(node, PROP_ENCODING, encodingIO.write(model.getEncoding())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_EXAMPLES, exampleObjectIO().write(model.getExamples())); + setIfPresent(node, PROP_ENCODING, encodingIO().write(model.getEncoding())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/media/SchemaIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/media/SchemaIO.java index cd0d6302e..1f292f3ab 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/media/SchemaIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/media/SchemaIO.java @@ -1,24 +1,72 @@ package io.smallrye.openapi.runtime.io.media; +import static io.smallrye.openapi.runtime.io.schema.DataType.listOf; +import static io.smallrye.openapi.runtime.io.schema.DataType.type; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROPERTIES_DATA_TYPES; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXCLUSIVE_MAXIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_EXCLUSIVE_MINIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MAXIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_MINIMUM; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_NULLABLE; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_REF; +import static io.smallrye.openapi.runtime.io.schema.SchemaConstant.PROP_TYPE; + +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; +import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.models.Components; +import org.eclipse.microprofile.openapi.models.Constructible; +import org.eclipse.microprofile.openapi.models.ExternalDocumentation; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.Operation; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.eclipse.microprofile.openapi.models.Paths; +import org.eclipse.microprofile.openapi.models.callbacks.Callback; +import org.eclipse.microprofile.openapi.models.examples.Example; +import org.eclipse.microprofile.openapi.models.headers.Header; +import org.eclipse.microprofile.openapi.models.info.Contact; +import org.eclipse.microprofile.openapi.models.info.Info; +import org.eclipse.microprofile.openapi.models.info.License; +import org.eclipse.microprofile.openapi.models.links.Link; +import org.eclipse.microprofile.openapi.models.media.Content; +import org.eclipse.microprofile.openapi.models.media.Discriminator; +import org.eclipse.microprofile.openapi.models.media.Encoding; +import org.eclipse.microprofile.openapi.models.media.MediaType; import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; import org.eclipse.microprofile.openapi.models.media.XML; +import org.eclipse.microprofile.openapi.models.parameters.Parameter; +import org.eclipse.microprofile.openapi.models.parameters.RequestBody; +import org.eclipse.microprofile.openapi.models.responses.APIResponse; +import org.eclipse.microprofile.openapi.models.responses.APIResponses; +import org.eclipse.microprofile.openapi.models.security.OAuthFlow; +import org.eclipse.microprofile.openapi.models.security.OAuthFlows; +import org.eclipse.microprofile.openapi.models.security.SecurityRequirement; +import org.eclipse.microprofile.openapi.models.security.SecurityScheme; +import org.eclipse.microprofile.openapi.models.servers.Server; +import org.eclipse.microprofile.openapi.models.servers.ServerVariable; +import org.eclipse.microprofile.openapi.models.tags.Tag; import org.jboss.jandex.AnnotationInstance; import io.smallrye.openapi.api.models.media.SchemaImpl; import io.smallrye.openapi.api.models.media.XMLImpl; -import io.smallrye.openapi.runtime.io.ExternalDocumentationIO; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; +import io.smallrye.openapi.runtime.io.schema.DataType; import io.smallrye.openapi.runtime.io.schema.SchemaConstant; import io.smallrye.openapi.runtime.io.schema.SchemaFactory; +import io.smallrye.openapi.runtime.util.ModelUtil; public class SchemaIO extends MapModelIO implements ReferenceIO { @@ -29,19 +77,8 @@ public class SchemaIO extends MapModelIO discriminatorIO; - private final ExternalDocumentationIO externalDocIO; - private final ExtensionIO extensionIO; - - public SchemaIO(IOContext context, ExtensionIO extensionIO) { + public SchemaIO(IOContext context) { super(context, Names.SCHEMA, Names.create(Schema.class)); - discriminatorIO = new DiscriminatorIO<>(context); - externalDocIO = new ExternalDocumentationIO<>(context, extensionIO); - this.extensionIO = extensionIO; - } - - public DiscriminatorIO discriminator() { - return discriminatorIO; } @Override @@ -54,59 +91,235 @@ protected Schema read(String name, AnnotationInstance annotation) { return SchemaFactory.readSchema(scannerContext(), new SchemaImpl(name), annotation, Collections.emptyMap()); } + @Override + public Schema readValue(V node) { + if (node == null) { + return null; + } + + if (jsonIO().isBoolean(node)) { + return new SchemaImpl().booleanSchema(jsonIO().asBoolean(node)); + } + + if (jsonIO().isObject(node)) { + return readObject(jsonIO().asObject(node)); + } + + return null; + } + + @SuppressWarnings("unchecked") @Override public Schema readObject(O node) { IoLogging.logger.singleJsonObject("Schema"); - Schema schema = new SchemaImpl(jsonIO().getString(node, SchemaConstant.PROP_NAME)); - schema.setRef(readReference(node)); - schema.setFormat(jsonIO().getString(node, SchemaConstant.PROP_FORMAT)); - schema.setTitle(jsonIO().getString(node, SchemaConstant.PROP_TITLE)); - schema.setDescription(jsonIO().getString(node, SchemaConstant.PROP_DESCRIPTION)); - schema.setDefaultValue(jsonIO().fromJson(jsonIO().getValue(node, SchemaConstant.PROP_DEFAULT))); - schema.setMultipleOf(jsonIO().getBigDecimal(node, SchemaConstant.PROP_MULTIPLE_OF)); - schema.setMaximum(jsonIO().getBigDecimal(node, SchemaConstant.PROP_MAXIMUM)); - schema.setExclusiveMaximum(jsonIO().getBoolean(node, SchemaConstant.PROP_EXCLUSIVE_MAXIMUM)); - schema.setMinimum(jsonIO().getBigDecimal(node, SchemaConstant.PROP_MINIMUM)); - schema.setExclusiveMinimum(jsonIO().getBoolean(node, SchemaConstant.PROP_EXCLUSIVE_MINIMUM)); - schema.setMaxLength(jsonIO().getInt(node, SchemaConstant.PROP_MAX_LENGTH)); - schema.setMinLength(jsonIO().getInt(node, SchemaConstant.PROP_MIN_LENGTH)); - schema.setPattern(jsonIO().getString(node, SchemaConstant.PROP_PATTERN)); - schema.setMaxItems(jsonIO().getInt(node, SchemaConstant.PROP_MAX_ITEMS)); - schema.setMinItems(jsonIO().getInt(node, SchemaConstant.PROP_MIN_ITEMS)); - schema.setUniqueItems(jsonIO().getBoolean(node, SchemaConstant.PROP_UNIQUE_ITEMS)); - schema.setMaxProperties(jsonIO().getInt(node, SchemaConstant.PROP_MAX_PROPERTIES)); - schema.setMinProperties(jsonIO().getInt(node, SchemaConstant.PROP_MIN_PROPERTIES)); - schema.setRequired(jsonIO().getArray(node, SchemaConstant.PROP_REQUIRED, jsonIO()::asString).orElse(null)); - schema.setEnumeration(jsonIO().getArray(node, SchemaConstant.PROP_ENUM, jsonIO()::fromJson).orElse(null)); - schema.setType(enumValue(jsonIO().getValue(node, SchemaConstant.PROP_TYPE), Schema.SchemaType.class)); - schema.setItems(jsonIO().getObject(node, SchemaConstant.PROP_ITEMS).map(this::readObject).orElse(null)); - schema.setNot(jsonIO().getObject(node, SchemaConstant.PROP_NOT).map(this::readObject).orElse(null)); - schema.setAllOf(jsonIO().getArray(node, SchemaConstant.PROP_ALL_OF, this::readValue).orElse(null)); - schema.setProperties(readMap(jsonIO().getValue(node, SchemaConstant.PROP_PROPERTIES))); - - V addlProperties = jsonIO().getValue(node, SchemaConstant.PROP_ADDITIONAL_PROPERTIES); - - if (jsonIO().isObject(addlProperties)) { - schema.setAdditionalPropertiesSchema(readObject(jsonIO().asObject(addlProperties))); + String name = getName(node); + SchemaImpl schema = new SchemaImpl(name); + + if (openApiVersion() == OpenApiVersion.V3_1) { + String dialect = jsonIO().getString(node, SchemaConstant.PROP_SCHEMA_DIALECT); + if (dialect == null || dialect.equals(SchemaConstant.DIALECT_OAS31) + || dialect.equals(SchemaConstant.DIALECT_JSON_2020_12)) { + populateSchemaObject(schema, node); + } else { + schema.getDataMap().putAll((Map) jsonIO().fromJson(node)); + } } else { - schema.setAdditionalPropertiesBoolean( - jsonIO().getBoolean(node, SchemaConstant.PROP_ADDITIONAL_PROPERTIES)); - } - - schema.setReadOnly(jsonIO().getBoolean(node, SchemaConstant.PROP_READ_ONLY)); - schema.setXml(readXML(jsonIO().getValue(node, SchemaConstant.PROP_XML))); - schema.setExternalDocs(externalDocIO.readValue(jsonIO().getValue(node, SchemaConstant.PROP_EXTERNAL_DOCS))); - schema.setExample(jsonIO().fromJson(jsonIO().getValue(node, SchemaConstant.PROP_EXAMPLE))); - schema.setOneOf(jsonIO().getArray(node, SchemaConstant.PROP_ONE_OF, this::readValue).orElse(null)); - schema.setAnyOf(jsonIO().getArray(node, SchemaConstant.PROP_ANY_OF, this::readValue).orElse(null)); - schema.setDiscriminator(discriminatorIO.readValue(jsonIO().getValue(node, SchemaConstant.PROP_DISCRIMINATOR))); - schema.setNullable(jsonIO().getBoolean(node, SchemaConstant.PROP_NULLABLE)); - schema.setWriteOnly(jsonIO().getBoolean(node, SchemaConstant.PROP_WRITE_ONLY)); - schema.setDeprecated(jsonIO().getBoolean(node, SchemaConstant.PROP_DEPRECATED)); - schema.setExtensions(extensionIO.readMap(node)); + populateSchemaObject30(schema, node); + } return schema; } + private void populateSchemaObject(SchemaImpl schema, O node) { + Map dataMap = schema.getDataMap(); + + // Special handling for type since it can be an array or a string and we want to convert + V typeNode = jsonIO().getValue(node, PROP_TYPE); + if (typeNode != null) { + if (jsonIO().isString(typeNode)) { + ArrayList typeList = new ArrayList<>(); + typeList.add(readJson(typeNode, type(Schema.SchemaType.class))); + dataMap.put(PROP_TYPE, typeList); + } else { + dataMap.put(PROP_TYPE, readJson(typeNode, listOf(type(Schema.SchemaType.class)))); + } + } + + // Read known fields + for (Map.Entry entry : SchemaConstant.PROPERTIES_DATA_TYPES.entrySet()) { + String key = entry.getKey(); + DataType type = entry.getValue(); + V fieldNode = jsonIO().getValue(node, key); + if (fieldNode != null) { + dataMap.put(key, readJson(fieldNode, type)); + } + } + + // Read unknown fields + for (Entry entry : jsonIO().properties(node)) { + String name = entry.getKey(); + V fieldNode = entry.getValue(); + if (!PROPERTIES_DATA_TYPES.containsKey(name) && !name.equals(PROP_TYPE) && !name.equals(PROP_NAME)) { + dataMap.put(name, jsonIO().fromJson(fieldNode)); + } + } + } + + private void populateSchemaObject30(SchemaImpl schema, O node) { + Map dataMap = schema.getDataMap(); + + // Call our internal methods for type/nullable handling + SchemaImpl.setType(schema, enumValue(jsonIO().getValue(node, PROP_TYPE), Schema.SchemaType.class)); + SchemaImpl.setNullable(schema, jsonIO().getBoolean(node, PROP_NULLABLE)); + + // Translate minimum + BigDecimal minimum = jsonIO().getBigDecimal(node, PROP_MINIMUM); + if (minimum != null) { + if (jsonIO().getBoolean(node, PROP_EXCLUSIVE_MINIMUM) == Boolean.TRUE) { + schema.setExclusiveMinimum(minimum); + } else { + schema.setMinimum(minimum); + } + } + + // Translate maximum + BigDecimal maximum = jsonIO().getBigDecimal(node, PROP_MAXIMUM); + if (maximum != null) { + if (jsonIO().getBoolean(node, PROP_EXCLUSIVE_MAXIMUM) == Boolean.TRUE) { + schema.setExclusiveMaximum(maximum); + } else { + schema.setMaximum(maximum); + } + } + + // Read known fields + for (Map.Entry entry : SchemaConstant.PROPERTIES_DATA_TYPES_3_0.entrySet()) { + String key = entry.getKey(); + DataType dataType = entry.getValue(); + V fieldNode = jsonIO().getValue(node, key); + if (fieldNode != null) { + dataMap.put(key, readJson(fieldNode, dataType)); + } + } + + // Read extensions + extensionIO().readMap(node).forEach(schema::addExtension); + + // Move allOf[{$ref=....}] to the top level + List allOf = schema.getAllOf(); + if (schema.getRef() == null && allOf != null) { + List allOfRefs = allOf.stream() + .filter(s -> isSoloRef(s)) + .collect(Collectors.toList()); + + if (allOfRefs.size() == 1) { + Schema refSchema = allOfRefs.get(0); + schema.removeAllOf(refSchema); + schema.setRef(refSchema.getRef()); + if (schema.getAllOf().isEmpty()) { + schema.setAllOf(null); + } + } + } + + // Detect {$ref=....,nullable=true} and convert to anyOf[{$ref=...}, {type=null}] + if (schema.getRef() != null && schema.getType() == null && SchemaImpl.getNullable(schema) == Boolean.TRUE) { + List newAnyOfSchemas = new ArrayList<>(); + newAnyOfSchemas.add(new SchemaImpl().ref(schema.getRef())); + newAnyOfSchemas.add(new SchemaImpl().addType(SchemaType.NULL)); + if (schema.getAnyOf() == null || schema.getAnyOf().isEmpty()) { + schema.setAnyOf(newAnyOfSchemas); + } else { + schema.addAllOf(new SchemaImpl().anyOf(newAnyOfSchemas)); + } + schema.setRef(null); + SchemaImpl.setNullable(schema, null); + } + + // Detect {enum=[null]} and convert to {type=null} + // Detect {enum=[value]} and convert to {const=value} + List enumeration = schema.getEnumeration(); + if (enumeration != null && enumeration.size() == 1) { + if (enumeration.get(0) == null) { + schema.setType(Collections.singletonList(SchemaType.NULL)); + schema.setEnumeration(null); + } else if (schema.getConstValue() == null) { + schema.setConstValue(enumeration.get(0)); + schema.setEnumeration(null); + } + } + } + + private String getName(O node) { + V name = jsonIO().getValue(node, PROP_NAME); + if (jsonIO().isString(name)) { + return jsonIO().asString(name); + } else { + return null; + } + } + + private Object readJson(V node, DataType desiredType) { + if (jsonIO().isObject(node) && desiredType.type == DataType.Type.MAP) { + Map result = new HashMap<>(); + O object = jsonIO().asObject(node); + for (Entry entry : jsonIO().properties(object)) { + result.put(entry.getKey(), readJson(entry.getValue(), desiredType.content)); + } + return result; + } else if (jsonIO().isArray(node) && desiredType.type == DataType.Type.LIST) { + List result = new ArrayList<>(); + A array = jsonIO().asArray(node); + for (V element : jsonIO().entries(array)) { + result.add(readJson(element, desiredType.content)); + } + return result; + } else if (desiredType.type == DataType.Type.OBJECT) { + return readValue(node, desiredType.clazz); + } else { + return jsonIO().fromJson(node); + } + } + + /** + * Convert JSON value node to an object when we have a desired type + *

    + * The JSON value will be converted to the desired type if possible or returned as its native type if not. + * + * @param node the JSON node + * @param desiredType the type that we want to be returned + * @return an object which represents the JSON node, which may or may not be of the desired type + */ + @SuppressWarnings("unchecked") + private Object readValue(V node, Class desiredType) { + // Handles string, number and boolean types + Object result = jsonIO().fromJson(node, desiredType); + if (result != null) { + return result; + } + + if (Enum.class.isAssignableFrom(desiredType)) { + result = enumValue(node, desiredType.asSubclass(Enum.class)); + if (result != null) { + return result; + } + } + + if (desiredType == Schema.class) { + return readValue(node); + } + if (desiredType == XML.class) { + return readXML(node); + } + if (desiredType == ExternalDocumentation.class) { + return extDocIO().readValue(node); + } + if (desiredType == Discriminator.class) { + return discriminatorIO().readValue(node); + } + + return jsonIO().fromJson(node); + } + public XML readXML(V node) { return Optional.ofNullable(node) .filter(jsonIO()::isObject) @@ -118,15 +331,39 @@ public XML readXML(V node) { xml.setPrefix(jsonIO().getString(node, PROP_PREFIX)); xml.setAttribute(jsonIO().getBoolean(node, PROP_ATTRIBUTE)); xml.setWrapped(jsonIO().getBoolean(node, PROP_WRAPPED)); - xml.setExtensions(extensionIO.readMap(node)); + xml.setExtensions(extensionIO().readMap(node)); return xml; }) .orElse(null); } - public Optional write(Schema model) { + public Optional write(Schema model) { + if (model == null) { + return Optional.empty(); + } + + if (openApiVersion() == OpenApiVersion.V3_1) { + return write31(model); + } else { + return write30(model); + } + } + + private Optional write31(Schema model) { + if (model.getBooleanSchema() != null) { + return jsonIO().toJson(model.getBooleanSchema()); + } + + SchemaImpl impl = (SchemaImpl) model; + Map data = impl.getDataMap(); + return writeMap(data); + } + + @SuppressWarnings("deprecation") + public Optional write30(Schema model) { return optionalJsonObject(model).map(node -> { - if (isReference(model)) { + ReplacementFields fields = compute30ReplacementFields(model); + if (fields.ref != null && !fields.ref.isEmpty()) { setReference(node, model); } else { setIfPresent(node, SchemaConstant.PROP_FORMAT, jsonIO().toJson(model.getFormat())); @@ -134,10 +371,10 @@ public Optional write(Schema model) { setIfPresent(node, SchemaConstant.PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, SchemaConstant.PROP_DEFAULT, jsonIO().toJson(model.getDefaultValue())); setIfPresent(node, SchemaConstant.PROP_MULTIPLE_OF, jsonIO().toJson(model.getMultipleOf())); - setIfPresent(node, SchemaConstant.PROP_MAXIMUM, jsonIO().toJson(model.getMaximum())); - setIfPresent(node, SchemaConstant.PROP_EXCLUSIVE_MAXIMUM, jsonIO().toJson(model.getExclusiveMaximum())); - setIfPresent(node, SchemaConstant.PROP_MINIMUM, jsonIO().toJson(model.getMinimum())); - setIfPresent(node, SchemaConstant.PROP_EXCLUSIVE_MINIMUM, jsonIO().toJson(model.getExclusiveMinimum())); + setIfPresent(node, SchemaConstant.PROP_MAXIMUM, jsonIO().toJson(fields.maximum)); + setIfPresent(node, SchemaConstant.PROP_EXCLUSIVE_MAXIMUM, jsonIO().toJson(fields.exclusiveMaximum)); + setIfPresent(node, SchemaConstant.PROP_MINIMUM, jsonIO().toJson(fields.minimum)); + setIfPresent(node, SchemaConstant.PROP_EXCLUSIVE_MINIMUM, jsonIO().toJson(fields.exclusiveMinimum)); setIfPresent(node, SchemaConstant.PROP_MAX_LENGTH, jsonIO().toJson(model.getMaxLength())); setIfPresent(node, SchemaConstant.PROP_MIN_LENGTH, jsonIO().toJson(model.getMinLength())); setIfPresent(node, SchemaConstant.PROP_PATTERN, jsonIO().toJson(model.getPattern())); @@ -147,11 +384,11 @@ public Optional write(Schema model) { setIfPresent(node, SchemaConstant.PROP_MAX_PROPERTIES, jsonIO().toJson(model.getMaxProperties())); setIfPresent(node, SchemaConstant.PROP_MIN_PROPERTIES, jsonIO().toJson(model.getMinProperties())); setIfPresent(node, SchemaConstant.PROP_REQUIRED, jsonIO().toJson(model.getRequired())); - setIfPresent(node, SchemaConstant.PROP_ENUM, jsonIO().toJson(model.getEnumeration())); - setIfPresent(node, SchemaConstant.PROP_TYPE, jsonIO().toJson(model.getType())); + setIfPresent(node, SchemaConstant.PROP_ENUM, jsonIO().toJson(fields.enumeration)); + setIfPresent(node, SchemaConstant.PROP_TYPE, jsonIO().toJson(fields.type)); setIfPresent(node, SchemaConstant.PROP_ITEMS, write(model.getItems())); - setIfPresent(node, SchemaConstant.PROP_ALL_OF, write(model.getAllOf())); - setIfPresent(node, SchemaConstant.PROP_PROPERTIES, write(model.getProperties())); + setIfPresent(node, SchemaConstant.PROP_ALL_OF, writeList(fields.allOf)); + setIfPresent(node, SchemaConstant.PROP_PROPERTIES, writeMap(model.getProperties())); if (model.getAdditionalPropertiesBoolean() != null) { setIfPresent(node, SchemaConstant.PROP_ADDITIONAL_PROPERTIES, jsonIO().toJson(model.getAdditionalPropertiesBoolean())); @@ -160,34 +397,210 @@ public Optional write(Schema model) { } setIfPresent(node, SchemaConstant.PROP_READ_ONLY, jsonIO().toJson(model.getReadOnly())); setIfPresent(node, SchemaConstant.PROP_XML, write(model.getXml())); - setIfPresent(node, SchemaConstant.PROP_EXTERNAL_DOCS, externalDocIO.write(model.getExternalDocs())); - setIfPresent(node, SchemaConstant.PROP_EXAMPLE, jsonIO().toJson(model.getExample())); - setIfPresent(node, SchemaConstant.PROP_ONE_OF, write(model.getOneOf())); - setIfPresent(node, SchemaConstant.PROP_ANY_OF, write(model.getAnyOf())); + setIfPresent(node, SchemaConstant.PROP_EXTERNAL_DOCS, extDocIO().write(model.getExternalDocs())); + setIfPresent(node, SchemaConstant.PROP_EXAMPLE, jsonIO().toJson(fields.example)); + setIfPresent(node, SchemaConstant.PROP_ONE_OF, writeList(model.getOneOf())); + setIfPresent(node, SchemaConstant.PROP_ANY_OF, writeList(fields.anyOf)); setIfPresent(node, SchemaConstant.PROP_NOT, write(model.getNot())); - setIfPresent(node, SchemaConstant.PROP_DISCRIMINATOR, discriminatorIO.write(model.getDiscriminator())); - setIfPresent(node, SchemaConstant.PROP_NULLABLE, jsonIO().toJson(model.getNullable())); + setIfPresent(node, SchemaConstant.PROP_DISCRIMINATOR, discriminatorIO().write(model.getDiscriminator())); + setIfPresent(node, SchemaConstant.PROP_NULLABLE, jsonIO().toJson(fields.nullable)); setIfPresent(node, SchemaConstant.PROP_WRITE_ONLY, jsonIO().toJson(model.getWriteOnly())); setIfPresent(node, SchemaConstant.PROP_DEPRECATED, jsonIO().toJson(model.getDeprecated())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); } return node; }).map(jsonIO()::buildObject); } - /** - * Writes a list of {@link Schema} to the JSON tree. - * - * @param parent - * @param models - * @param propertyName - */ - private Optional write(List models) { - return optionalJsonArray(models).map(array -> { - models.forEach(model -> write(model).ifPresent(v -> jsonIO().add(array, v))); - return array; - }).map(jsonIO()::buildArray); + @SuppressWarnings("deprecation") + private ReplacementFields compute30ReplacementFields(Schema schema31) { + ReplacementFields result = new ReplacementFields(); + + // Transform types and nullable + List types = schema31.getType(); + if (types != null) { + result.type = types.stream().filter(t -> t != SchemaType.NULL).findFirst().orElse(null); + result.nullable = SchemaImpl.getNullable(schema31); + } + + // Convert type=null to enum=[null] and const=value to enum=[value] + result.enumeration = schema31.getEnumeration(); + if (result.type == null && result.nullable == Boolean.TRUE) { + result.nullable = null; + result.enumeration = Collections.singletonList(null); + } else if (schema31.getConstValue() != null) { + result.enumeration = Collections.singletonList(schema31.getConstValue()); + } + + // Convert numeric exclusiveMinimum to boolean + BigDecimal oldMinimum = schema31.getMinimum(); + BigDecimal oldExclusiveMinimum = schema31.getExclusiveMinimum(); + if (oldMinimum != null) { + result.minimum = oldMinimum; + if (oldExclusiveMinimum != null && oldExclusiveMinimum.compareTo(oldMinimum) >= 0) { + result.minimum = oldExclusiveMinimum; + result.exclusiveMinimum = Boolean.TRUE; + } + } else if (oldExclusiveMinimum != null) { + result.minimum = oldExclusiveMinimum; + result.exclusiveMinimum = Boolean.TRUE; + } + + // Convert numeric exclusiveMaximum to boolean + BigDecimal oldMaximum = schema31.getMaximum(); + BigDecimal oldExclusiveMaximum = schema31.getExclusiveMaximum(); + if (oldMaximum != null) { + result.maximum = oldMaximum; + if (oldExclusiveMaximum != null && oldExclusiveMaximum.compareTo(oldMaximum) <= 0) { + result.maximum = oldExclusiveMaximum; + result.exclusiveMaximum = Boolean.TRUE; + } + } else if (oldExclusiveMaximum != null) { + result.maximum = oldExclusiveMaximum; + result.exclusiveMaximum = Boolean.TRUE; + } + + // Transform example + result.example = schema31.getExample(); + if (result.example == null) { + result.example = Optional.ofNullable(schema31.getExamples()) + .flatMap(l -> l.stream().findFirst()) + .orElse(null); + } + + result.ref = schema31.getRef(); + result.allOf = schema31.getAllOf(); + result.anyOf = schema31.getAnyOf(); + + // If $ref is used with any other properties, move it to an allOf + if (result.ref != null && !isSoloRef(schema31)) { + result.ref = null; + Schema refSchema = new SchemaImpl().ref(schema31.getRef()); + result.allOf = ModelUtil.replace(result.allOf, ArrayList::new); // replace first because result.allOf may be immutable + result.allOf = ModelUtil.add(refSchema, result.allOf, ArrayList::new); + } + + // If we have anyOf = [{type=null}, {$ref=...}], remove it and set nullable and allOf = [{$ref=...}] + if (result.anyOf != null && result.anyOf.size() == 2 && result.ref == null && result.type == null) { + Optional typeNullSchema = result.anyOf.stream().filter(s -> isSoloTypeNull(s)).findFirst(); + Optional refSchema = result.anyOf.stream().filter(s -> isSoloRef(s)).findFirst(); + if (typeNullSchema.isPresent() && refSchema.isPresent()) { + result.anyOf = null; + result.nullable = Boolean.TRUE; + result.allOf = ModelUtil.replace(result.allOf, ArrayList::new); // replace first because result.allOf may be immutable + result.allOf = ModelUtil.add(refSchema.get(), result.allOf, ArrayList::new); + } + } + + return result; + } + + private Optional writeObject(Object value) { + if (value instanceof Schema) { + return write((Schema) value); + } else if (value instanceof XML) { + return write((XML) value); + } else if (value instanceof Constructible) { + return writeConstructible((Constructible) value); + } else if (value instanceof List) { + return writeList((List) value); + } else if (value instanceof Map) { + return writeMap((Map) value); + } else { + return jsonIO().toJson(value); + } + } + + private Optional writeConstructible(Constructible value) { + // Java 21 cannot come soon enough + if (value instanceof ExternalDocumentation) { + return extDocIO().write((ExternalDocumentation) value); + } else if (value instanceof Discriminator) { + return discriminatorIO().write((Discriminator) value); + } else if (value instanceof Components) { + return componentsIO().write((Components) value); + } else if (value instanceof OpenAPI) { + return openApiDefinitionIO().write((OpenAPI) value); + } else if (value instanceof Operation) { + return operationIO().write((Operation) value); + } else if (value instanceof PathItem) { + return pathItemIO().write((PathItem) value); + } else if (value instanceof Paths) { + return pathsIO().write((Paths) value); + } else if (value instanceof Callback) { + return callbackIO().write((Callback) value); + } else if (value instanceof Header) { + return headerIO().write((Header) value); + } else if (value instanceof Contact) { + return contactIO().write((Contact) value); + } else if (value instanceof Info) { + return infoIO().write((Info) value); + } else if (value instanceof License) { + return licenseIO().write((License) value); + } else if (value instanceof Link) { + return linkIO().write((Link) value); + } else if (value instanceof Content) { + return contentIO().write((Content) value); + } else if (value instanceof Encoding) { + return encodingIO().write((Encoding) value); + } else if (value instanceof Example) { + return exampleObjectIO().write((Example) value); + } else if (value instanceof MediaType) { + return mediaTypeIO().write((MediaType) value); + } else if (value instanceof Parameter) { + return parameterIO().write((Parameter) value); + } else if (value instanceof RequestBody) { + return requestBodyIO().write((RequestBody) value); + } else if (value instanceof APIResponse) { + return apiResponseIO().write((APIResponse) value); + } else if (value instanceof APIResponses) { + return apiResponsesIO().write((APIResponses) value); + } else if (value instanceof OAuthFlow) { + return oauthFlowIO().write((OAuthFlow) value); + } else if (value instanceof OAuthFlows) { + return oauthFlowsIO().write((OAuthFlows) value); + } else if (value instanceof SecurityRequirement) { + return securityRequirementIO().write((SecurityRequirement) value); + } else if (value instanceof SecurityScheme) { + return securitySchemeIO().write((SecurityScheme) value); + } else if (value instanceof Server) { + return serverIO().write((Server) value); + } else if (value instanceof ServerVariable) { + return serverVariableIO().write((ServerVariable) value); + } else if (value instanceof Tag) { + return tagIO().write((Tag) value); + } else { + return jsonIO().toJson(value); + } + } + + private Optional writeMap(Map map) { + return optionalJsonObject(map).map(result -> { + for (Map.Entry entry : map.entrySet()) { + if (!(entry.getKey() instanceof String)) + continue; + String key = (String) entry.getKey(); + Object value = entry.getValue(); + if (PROP_TYPE.equals(key)) { + // Flatten one-entry type lists + if (value instanceof List && ((List) value).size() == 1) { + value = ((List) value).get(0); + } + } + setIfPresent(result, key, writeObject(value)); + } + return result; + }).map(jsonIO()::buildObject); + } + + private Optional writeList(List list) { + return optionalJsonArray(list).map(result -> { + for (Object entry : list) { + writeObject(entry).ifPresent(v -> jsonIO().add(result, v)); + } + return jsonIO().buildArray(result); + }); } public Optional write(XML model) { @@ -197,8 +610,61 @@ public Optional write(XML model) { setIfPresent(node, PROP_PREFIX, jsonIO().toJson(model.getPrefix())); setIfPresent(node, PROP_ATTRIBUTE, jsonIO().toJson(model.getAttribute())); setIfPresent(node, PROP_WRAPPED, jsonIO().toJson(model.getWrapped())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } + + /** + * Checks whether a schema has only the {@code $ref} property set + * + * @param schema the schema to check + * @return {@code true} if {@code schema} has one property and it's named {@code $ref}, otherwise {@code false} + */ + private static boolean isSoloRef(Schema schema) { + if (!(schema instanceof SchemaImpl)) { + return false; + } + SchemaImpl s = (SchemaImpl) schema; + Map data = s.getDataMap(); + return data.size() == 1 && data.containsKey(PROP_REF); + } + + /** + * Checks whether a schema has only the {@code type} property set with the value {@code [null]} + * + * @param schema the schema to check + * @return {@code true} if {@code schema} has one property and it's named {@code type} and has value {@code [null]}, + * otherwise {@code false} + */ + private static boolean isSoloTypeNull(Schema schema) { + if (!(schema instanceof SchemaImpl)) { + return false; + } + SchemaImpl s = (SchemaImpl) schema; + Map data = s.getDataMap(); + return data.size() == 1 && s.getType() != null && s.getType().equals(Collections.singletonList(SchemaType.NULL)); + } + + /** + * Replacement field values which should be used when writing a Schema in 3.0 format. + *

    + * All fields which may need to change value between 3.1 and 3.0 have an entry in here. + *

    + * This is written by compute30ReplacementFields and read by populateSchemaObject30 + */ + private static class ReplacementFields { + private SchemaType type; + private Boolean nullable; + private BigDecimal minimum; + private Boolean exclusiveMinimum; + private BigDecimal maximum; + private Boolean exclusiveMaximum; + private Object example; + private String ref; + private List allOf; + private List anyOf; + private List enumeration; + } + } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/ParameterIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/ParameterIO.java index 728ea4368..616f61908 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/ParameterIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/ParameterIO.java @@ -14,15 +14,13 @@ import io.smallrye.openapi.api.models.parameters.ParameterImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; import io.smallrye.openapi.runtime.io.media.ContentIO; -import io.smallrye.openapi.runtime.io.media.ExampleObjectIO; -import io.smallrye.openapi.runtime.io.media.SchemaIO; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; import io.smallrye.openapi.runtime.util.JandexUtil; @@ -44,18 +42,8 @@ public class ParameterIO extends MapModelIO private static final String PROP_SCHEMA = "schema"; private static final String PROP_STYLE = "style"; - private final SchemaIO schemaIO; - private final ContentIO contentIO; - private final ExampleObjectIO exampleObjectIO; - private final ExtensionIO extensionIO; - - public ParameterIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public ParameterIO(IOContext context) { super(context, Names.PARAMETER, Names.create(Parameter.class)); - this.contentIO = contentIO; - exampleObjectIO = new ExampleObjectIO<>(context, extensionIO); - schemaIO = new SchemaIO<>(context, extensionIO); - this.extensionIO = extensionIO; } public List readList(AnnotationValue annotations) { @@ -96,10 +84,10 @@ public Parameter read(AnnotationInstance annotation) { parameter.setStyle(enumValue(annotation, PROP_STYLE, Parameter.Style.class)); parameter.setExplode(readExplode(scannerContext(), annotation)); parameter.setAllowReserved(value(annotation, PROP_ALLOW_RESERVED)); - parameter.setSchema(schemaIO.read(annotation.value(PROP_SCHEMA))); - parameter.setContent(contentIO.read(annotation.value(PROP_CONTENT), ContentIO.Direction.PARAMETER)); - parameter.setExamples(exampleObjectIO.readMap(annotation.value(PROP_EXAMPLES))); - parameter.setExample(exampleObjectIO.parseValue(value(annotation, PROP_EXAMPLE))); + parameter.setSchema(schemaIO().read(annotation.value(PROP_SCHEMA))); + parameter.setContent(contentIO().read(annotation.value(PROP_CONTENT), ContentIO.Direction.PARAMETER)); + parameter.setExamples(exampleObjectIO().readMap(annotation.value(PROP_EXAMPLES))); + parameter.setExample(exampleObjectIO().parseValue(value(annotation, PROP_EXAMPLE))); parameter.setRef(ReferenceType.PARAMETER.refValue(annotation)); if (annotation.target() != null) { @@ -111,7 +99,7 @@ public Parameter read(AnnotationInstance annotation) { * instead to the operation. * */ - parameter.setExtensions(extensionIO.readExtensible(annotation)); + parameter.setExtensions(extensionIO().readExtensible(annotation)); break; default: break; @@ -152,12 +140,12 @@ public Parameter readObject(O node) { parameter.setStyle(enumValue(jsonIO().getValue(node, PROP_STYLE), Parameter.Style.class)); parameter.setExplode(jsonIO().getBoolean(node, PROP_EXPLODE)); parameter.setAllowReserved(jsonIO().getBoolean(node, PROP_ALLOW_RESERVED)); - parameter.setSchema(schemaIO.readValue(jsonIO().getValue(node, PROP_SCHEMA))); - parameter.setContent(contentIO.readValue(jsonIO().getValue(node, PROP_CONTENT))); - parameter.setExamples(exampleObjectIO.readMap(jsonIO().getValue(node, PROP_EXAMPLES))); + parameter.setSchema(schemaIO().readValue(jsonIO().getValue(node, PROP_SCHEMA))); + parameter.setContent(contentIO().readValue(jsonIO().getValue(node, PROP_CONTENT))); + parameter.setExamples(exampleObjectIO().readMap(jsonIO().getValue(node, PROP_EXAMPLES))); parameter.setExample(jsonIO().fromJson(jsonIO().getValue(node, PROP_EXAMPLE))); parameter.setRef(readReference(node)); - parameter.setExtensions(extensionIO.readMap(node)); + parameter.setExtensions(extensionIO().readMap(node)); return parameter; } @@ -178,21 +166,24 @@ public Optional write(Parameter model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_NAME, jsonIO().toJson(model.getName())); setIfPresent(node, PROP_IN, jsonIO().toJson(model.getIn())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, PROP_REQUIRED, jsonIO().toJson(model.getRequired())); - setIfPresent(node, PROP_SCHEMA, schemaIO.write(model.getSchema())); + setIfPresent(node, PROP_SCHEMA, schemaIO().write(model.getSchema())); setIfPresent(node, PROP_ALLOW_EMPTY_VALUE, jsonIO().toJson(model.getAllowEmptyValue())); setIfPresent(node, PROP_DEPRECATED, jsonIO().toJson(model.getDeprecated())); setIfPresent(node, PROP_STYLE, jsonIO().toJson(model.getStyle())); setIfPresent(node, PROP_EXPLODE, jsonIO().toJson(model.getExplode())); setIfPresent(node, PROP_ALLOW_RESERVED, jsonIO().toJson(model.getAllowReserved())); setIfPresent(node, PROP_EXAMPLE, jsonIO().toJson(model.getExample())); - setIfPresent(node, PROP_EXAMPLES, exampleObjectIO.write(model.getExamples())); - setIfPresent(node, PROP_CONTENT, contentIO.write(model.getContent())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_EXAMPLES, exampleObjectIO().write(model.getExamples())); + setIfPresent(node, PROP_CONTENT, contentIO().write(model.getContent())); + setAllIfPresent(node, extensionIO().write(model)); } return node; }).map(jsonIO()::buildObject); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/RequestBodyIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/RequestBodyIO.java index 32393cd84..594c7a836 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/RequestBodyIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/parameters/RequestBodyIO.java @@ -20,12 +20,12 @@ import io.smallrye.openapi.api.models.media.MediaTypeImpl; import io.smallrye.openapi.api.models.parameters.RequestBodyImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; import io.smallrye.openapi.runtime.io.media.ContentIO; import io.smallrye.openapi.runtime.io.schema.SchemaFactory; @@ -37,14 +37,8 @@ public class RequestBodyIO extends MapModel private static final String PROP_CONTENT = "content"; private static final String PROP_VALUE = "value"; - private final ContentIO contentIO; - private final ExtensionIO extensionIO; - - public RequestBodyIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public RequestBodyIO(IOContext context) { super(context, Names.REQUEST_BODY, Names.create(RequestBody.class)); - this.contentIO = contentIO; - this.extensionIO = extensionIO; } Stream getAnnotations(MethodInfo method, DotName annotation) { @@ -68,12 +62,17 @@ public List getRepeatableAnnotations(AnnotationTarget target @Override public RequestBody read(AnnotationInstance annotation) { IoLogging.logger.singleAnnotation("@RequestBody"); - RequestBody requestBody = new RequestBodyImpl(); + RequestBodyImpl requestBody = new RequestBodyImpl(); requestBody.setDescription(value(annotation, PROP_DESCRIPTION)); - requestBody.setContent(contentIO.read(annotation.value(PROP_CONTENT), ContentIO.Direction.INPUT)); - requestBody.setRequired(value(annotation, PROP_REQUIRED)); + requestBody.setContent(contentIO().read(annotation.value(PROP_CONTENT), ContentIO.Direction.INPUT)); requestBody.setRef(ReferenceType.REQUEST_BODY.refValue(annotation)); - requestBody.setExtensions(extensionIO.readExtensible(annotation)); + requestBody.setExtensions(extensionIO().readExtensible(annotation)); + Boolean required = value(annotation, PROP_REQUIRED); + if (required != null) { + requestBody.setRequired(required); + } else { + requestBody.setRequiredDefault(Boolean.TRUE); + } return requestBody; } @@ -109,10 +108,10 @@ private RequestBody readRequestSchema(AnnotationInstance annotation) { public RequestBody readObject(O node) { RequestBody requestBody = new RequestBodyImpl(); requestBody.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - requestBody.setContent(contentIO.readValue(jsonIO().getValue(node, PROP_CONTENT))); + requestBody.setContent(contentIO().readValue(jsonIO().getValue(node, PROP_CONTENT))); requestBody.setRequired(jsonIO().getBoolean(node, PROP_REQUIRED)); requestBody.setRef(readReference(node)); - requestBody.setExtensions(extensionIO.readMap(node)); + requestBody.setExtensions(extensionIO().readMap(node)); return requestBody; } @@ -120,11 +119,14 @@ public Optional write(RequestBody model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_CONTENT, contentIO.write(model.getContent())); + setIfPresent(node, PROP_CONTENT, contentIO().write(model.getContent())); setIfPresent(node, PROP_REQUIRED, jsonIO().toJson(model.getRequired())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); } return node; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponseIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponseIO.java index f385baaf5..986b09f93 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponseIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponseIO.java @@ -16,14 +16,12 @@ import io.smallrye.openapi.api.models.media.MediaTypeImpl; import io.smallrye.openapi.api.models.responses.APIResponseImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.headers.HeaderIO; -import io.smallrye.openapi.runtime.io.links.LinkIO; import io.smallrye.openapi.runtime.io.media.ContentIO; import io.smallrye.openapi.runtime.io.schema.SchemaFactory; import io.smallrye.openapi.runtime.util.ModelUtil; @@ -40,18 +38,8 @@ public class APIResponseIO extends MapModel private static final String PROP_RESPONSE_DESCRIPTION = "responseDescription"; private static final String PROP_VALUE = "value"; - private final LinkIO linkIO; - private final HeaderIO headerIO; - private final ContentIO contentIO; - private final ExtensionIO extensionIO; - - public APIResponseIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public APIResponseIO(IOContext context) { super(context, Names.API_RESPONSE, DotName.createSimple(APIResponse.class)); - linkIO = new LinkIO<>(context, extensionIO); - this.contentIO = contentIO; - headerIO = new HeaderIO<>(context, contentIO, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -59,10 +47,10 @@ public APIResponse read(AnnotationInstance annotation) { IoLogging.logger.singleAnnotation("@APIResponse"); APIResponseImpl response = new APIResponseImpl(); response.setDescription(value(annotation, PROP_DESCRIPTION)); - response.setHeaders(headerIO.readMap(annotation.value(PROP_HEADERS))); - response.setLinks(linkIO.readMap(annotation.value(PROP_LINKS))); - response.setContent(contentIO.read(annotation.value(PROP_CONTENT), ContentIO.Direction.OUTPUT)); - response.setExtensions(extensionIO.readExtensible(annotation)); + response.setHeaders(headerIO().readMap(annotation.value(PROP_HEADERS))); + response.setLinks(linkIO().readMap(annotation.value(PROP_LINKS))); + response.setContent(contentIO().read(annotation.value(PROP_CONTENT), ContentIO.Direction.OUTPUT)); + response.setExtensions(extensionIO().readExtensible(annotation)); response.setRef(ReferenceType.RESPONSE.refValue(annotation)); response.setResponseCode(responseCode(annotation).orElse(null)); return response; @@ -120,10 +108,10 @@ public APIResponse readObject(O node) { APIResponse model = new APIResponseImpl(); model.setRef(readReference(node)); model.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - model.setHeaders(headerIO.readMap(jsonIO().getValue(node, PROP_HEADERS))); - model.setContent(contentIO.readValue(jsonIO().getValue(node, PROP_CONTENT))); - model.setLinks(linkIO.readMap(jsonIO().getValue(node, PROP_LINKS))); - model.setExtensions(extensionIO.readMap(node)); + model.setHeaders(headerIO().readMap(jsonIO().getValue(node, PROP_HEADERS))); + model.setContent(contentIO().readValue(jsonIO().getValue(node, PROP_CONTENT))); + model.setLinks(linkIO().readMap(jsonIO().getValue(node, PROP_LINKS))); + model.setExtensions(extensionIO().readMap(node)); return model; } @@ -131,12 +119,15 @@ public Optional write(APIResponse model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_HEADERS, headerIO.write(model.getHeaders())); - setIfPresent(node, PROP_CONTENT, contentIO.write(model.getContent())); - setIfPresent(node, PROP_LINKS, linkIO.write(model.getLinks())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_HEADERS, headerIO().write(model.getHeaders())); + setIfPresent(node, PROP_CONTENT, contentIO().write(model.getContent())); + setIfPresent(node, PROP_LINKS, linkIO().write(model.getLinks())); + setAllIfPresent(node, extensionIO().write(model)); } return node; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponsesIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponsesIO.java index f8798e09e..8137d7f44 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponsesIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/responses/APIResponsesIO.java @@ -16,32 +16,24 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; -import io.smallrye.openapi.runtime.io.media.ContentIO; public class APIResponsesIO extends ModelIO { private static final String PROP_DEFAULT = "default"; - private final APIResponseIO responseIO; - private final ExtensionIO extensionIO; - - public APIResponsesIO(IOContext context, ContentIO contentIO, - ExtensionIO extensionIO) { + public APIResponsesIO(IOContext context) { super(context, Names.API_RESPONSES, Names.create(APIResponses.class)); - responseIO = new APIResponseIO<>(context, contentIO, extensionIO); - this.extensionIO = extensionIO; } public Map readSingle(AnnotationTarget target) { - return Optional.ofNullable(responseIO.getAnnotation(target)) + return Optional.ofNullable(apiResponseIO().getAnnotation(target)) .map(Collections::singleton) - .map(annotations -> responseIO.readMap(annotations, responseIO::responseCode)) + .map(annotations -> apiResponseIO().readMap(annotations, apiResponseIO()::responseCode)) .orElse(null); } public Map readAll(AnnotationTarget target) { - return responseIO.readMap(target, responseIO::responseCode); + return apiResponseIO().readMap(target, apiResponseIO()::responseCode); } @Override @@ -61,7 +53,7 @@ public APIResponses read(AnnotationInstance annotation) { .toArray(AnnotationInstance[]::new)) // End .map(this::read) - .map(responses -> responses.extensions(extensionIO.readExtensible(annotation))) + .map(responses -> responses.extensions(extensionIO().readExtensible(annotation))) .orElse(null); } @@ -75,7 +67,7 @@ public APIResponses read(AnnotationValue annotation) { public Optional> readResponseSchema(AnnotationTarget target) { return Optional.ofNullable(scannerContext().annotations().getAnnotation(target, Names.API_RESPONSE_SCHEMA)) - .map(responseIO::readResponseSchema); + .map(apiResponseIO()::readResponseSchema); } /** @@ -89,8 +81,8 @@ public APIResponses read(AnnotationInstance[] annotations) { APIResponses responses = new APIResponsesImpl(); for (AnnotationInstance nested : annotations) { - responseIO.responseCode(nested) - .ifPresent(responseCode -> responses.addAPIResponse(responseCode, responseIO.read(nested))); + apiResponseIO().responseCode(nested) + .ifPresent(responseCode -> responses.addAPIResponse(responseCode, apiResponseIO().read(nested))); } return responses; @@ -101,22 +93,22 @@ public APIResponses readObject(O node) { IoLogging.logger.jsonList("APIResponse"); APIResponses model = new APIResponsesImpl(); - model.setDefaultValue(responseIO.readValue(jsonIO().getValue(node, PROP_DEFAULT))); - model.setExtensions(extensionIO.readMap(node)); + model.setDefaultValue(apiResponseIO().readValue(jsonIO().getValue(node, PROP_DEFAULT))); + model.setExtensions(extensionIO().readMap(node)); jsonIO().properties(node) .stream() .filter(not(property -> PROP_DEFAULT.equals(property.getKey()))) - .forEach(property -> model.addAPIResponse(property.getKey(), responseIO.readValue(property.getValue()))); + .forEach(property -> model.addAPIResponse(property.getKey(), apiResponseIO().readValue(property.getValue()))); return model; } public Optional write(APIResponses model) { return optionalJsonObject(model).map(node -> { - setAllIfPresent(node, extensionIO.write(model)); - setIfPresent(node, PROP_DEFAULT, responseIO.write(model.getDefaultValue())); - setAllIfPresent(node, responseIO.write(model.getAPIResponses())); + setAllIfPresent(node, extensionIO().write(model)); + setIfPresent(node, PROP_DEFAULT, apiResponseIO().write(model.getDefaultValue())); + setAllIfPresent(node, apiResponseIO().write(model.getAPIResponses())); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/DataType.java b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/DataType.java new file mode 100644 index 000000000..87e40e74f --- /dev/null +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/DataType.java @@ -0,0 +1,35 @@ +package io.smallrye.openapi.runtime.io.schema; + +/** + * Represents a desired data type that we might want to convert a JSON node to + */ +public class DataType { + public static enum Type { + OBJECT, + LIST, + MAP + } + + public DataType.Type type; + public DataType content; + public Class clazz; + + private DataType(DataType.Type type, DataType content, Class clazz) { + super(); + this.type = type; + this.content = content; + this.clazz = clazz; + } + + public static DataType type(Class clazz) { + return new DataType(Type.OBJECT, null, clazz); + } + + public static DataType listOf(DataType content) { + return new DataType(Type.LIST, content, null); + } + + public static DataType mapOf(DataType content) { + return new DataType(Type.MAP, content, null); + } +} \ No newline at end of file diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaConstant.java b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaConstant.java index 7fe63bf76..a6629bc7a 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaConstant.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaConstant.java @@ -1,25 +1,40 @@ package io.smallrye.openapi.runtime.io.schema; +import static io.smallrye.openapi.runtime.io.schema.DataType.listOf; +import static io.smallrye.openapi.runtime.io.schema.DataType.mapOf; +import static io.smallrye.openapi.runtime.io.schema.DataType.type; + +import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; -import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.models.ExternalDocumentation; +import org.eclipse.microprofile.openapi.models.media.Discriminator; +import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.XML; import org.jboss.jandex.DotName; +import io.smallrye.openapi.runtime.io.ReferenceIO; + /** * Constants related to Schema * - * @see schemaObject + * @see schema-object * * @author Phillip Kruger (phillip.kruger@redhat.com) * @author Eric Wittmann (eric.wittmann@gmail.com) */ public class SchemaConstant { - public static final DotName DOTNAME_SCHEMA = DotName.createSimple(Schema.class.getName()); - public static final DotName DOTNAME_TRUE_SCHEMA = DotName.createSimple(Schema.class.getName() + "$True"); - public static final DotName DOTNAME_FALSE_SCHEMA = DotName.createSimple(Schema.class.getName() + "$False"); + public static final DotName DOTNAME_SCHEMA = DotName + .createSimple(org.eclipse.microprofile.openapi.annotations.media.Schema.class.getName()); + public static final DotName DOTNAME_TRUE_SCHEMA = DotName + .createSimple(org.eclipse.microprofile.openapi.annotations.media.Schema.class.getName() + "$True"); + public static final DotName DOTNAME_FALSE_SCHEMA = DotName + .createSimple(org.eclipse.microprofile.openapi.annotations.media.Schema.class.getName() + "$False"); public static final String PROP_DISCRIMINATOR = "discriminator"; public static final String PROP_XML = "xml"; public static final String PROP_NAME = "name"; @@ -30,6 +45,7 @@ public class SchemaConstant { public static final String PROP_FORMAT = "format"; public static final String PROP_PATTERN = "pattern"; public static final String PROP_EXAMPLE = "example"; + public static final String PROP_EXAMPLES = "examples"; public static final String PROP_EXTERNAL_DOCS = "externalDocs"; public static final String REF = "ref"; @@ -56,6 +72,27 @@ public class SchemaConstant { public static final String PROP_DESCRIPTION = "description"; public static final String PROP_MIN_LENGTH = "minLength"; + public static final String PROP_SCHEMA_DIALECT = "$schema"; + public static final String PROP_COMMENT = "$comment"; + public static final String PROP_REF = "$ref"; + + public static final String PROP_IF = "if"; + public static final String PROP_THEN = "then"; + public static final String PROP_ELSE = "else"; + public static final String PROP_DEPENDENT_SCHEMAS = "dependentSchemas"; + public static final String PROP_PROPERTY_NAMES = "propertyNames"; + public static final String PROP_UNEVALUATED_ITEMS = "unevaluatedItems"; + public static final String PROP_UNEVALUATED_PROPERTIES = "unevaluatedProperties"; + + public static final String PROP_CONST = "const"; + public static final String PROP_MAX_CONTAINS = "maxContains"; + public static final String PROP_MIN_CONTAINS = "minContains"; + public static final String PROP_DEPENDENT_REQUIRED = "dependentRequired"; + + public static final String PROP_CONTENT_ENCODING = "contentEncoding"; + public static final String PROP_CONTENT_MEDIA_TYPE = "contentMediaType"; + public static final String PROP_CONTENT_SCHEMA = "contentSchema"; + // for annotations (reserved words in Java) public static final String PROP_ENUMERATION = "enumeration"; public static final String PROP_ENUM = "enum"; @@ -67,16 +104,99 @@ public class SchemaConstant { public static final String PROP_ONE_OF = "oneOf"; public static final String PROP_ITEMS = "items"; public static final String PROP_MAX_PROPERTIES = "maxProperties"; + public static final String PROP_PREFIX_ITEMS = "prefixItems"; + public static final String PROP_CONTAINS = "contains"; + public static final String PROP_PATTERN_PROPERTIES = "patternProperties"; + public static final String PROP_IF_SCHEMA = "ifSchema"; + public static final String PROP_THEN_SCHEMA = "thenSchema"; + public static final String PROP_ELSE_SCHEMA = "elseSchema"; + public static final String PROP_CONST_VALUE = "constValue"; + public static final String PROP_COMMENT_FIELD = "comment"; // Only in SchemaFactory ? public static final String PROP_REQUIRED_PROPERTIES = "requiredProperties"; public static final String PROP_PROPERTIES = "properties"; public static final String PROP_NOT = "not"; + public static final String PROP_REGEX = "regex"; + public static final String PROP_REQUIRES = "requires"; + + public static final String DIALECT_OAS31 = "https://spec.openapis.org/oas/3.1/dialect/base"; + public static final String DIALECT_JSON_2020_12 = "https://json-schema.org/draft/2020-12/schema"; public static final List PROPERTIES_NONDISPLAY = Collections.unmodifiableList(Arrays.asList(PROP_IMPLEMENTATION, PROP_NAME, PROP_REQUIRED)); + /** + * A map of fields we expect to find in a Schema JSON object and their expected types + */ + public static final Map PROPERTIES_DATA_TYPES; + public static final Map PROPERTIES_DATA_TYPES_3_0; + static { + Map propertiesDataTypes30 = new HashMap<>(); + Map propertiesDataTypes = new HashMap<>(); + + propertiesDataTypes30.put(ReferenceIO.REF, type(String.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_DISCRIMINATOR, type(Discriminator.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_TITLE, type(String.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_DEFAULT, type(Object.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_ENUM, listOf(type(Object.class))); + propertiesDataTypes30.put(SchemaConstant.PROP_MULTIPLE_OF, type(BigDecimal.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MAX_LENGTH, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MIN_LENGTH, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_PATTERN, type(String.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MAX_ITEMS, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MIN_ITEMS, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_UNIQUE_ITEMS, type(Boolean.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MAX_PROPERTIES, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_MIN_PROPERTIES, type(Integer.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_REQUIRED, listOf(type(String.class))); + propertiesDataTypes30.put(SchemaConstant.PROP_NOT, type(Schema.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_PROPERTIES, mapOf(type(Schema.class))); + propertiesDataTypes30.put(SchemaConstant.PROP_ADDITIONAL_PROPERTIES, type(Schema.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_DESCRIPTION, type(String.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_FORMAT, type(String.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_READ_ONLY, type(Boolean.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_WRITE_ONLY, type(Boolean.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_EXAMPLE, type(Object.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_EXTERNAL_DOCS, type(ExternalDocumentation.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_DEPRECATED, type(Boolean.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_XML, type(XML.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_ITEMS, type(Schema.class)); + propertiesDataTypes30.put(SchemaConstant.PROP_ALL_OF, listOf(type(Schema.class))); + propertiesDataTypes30.put(SchemaConstant.PROP_ANY_OF, listOf(type(Schema.class))); + propertiesDataTypes30.put(SchemaConstant.PROP_ONE_OF, listOf(type(Schema.class))); + + propertiesDataTypes.putAll(propertiesDataTypes30); + propertiesDataTypes.put(SchemaConstant.PROP_MAXIMUM, type(BigDecimal.class)); + propertiesDataTypes.put(SchemaConstant.PROP_EXCLUSIVE_MAXIMUM, type(BigDecimal.class)); + propertiesDataTypes.put(SchemaConstant.PROP_MINIMUM, type(BigDecimal.class)); + propertiesDataTypes.put(SchemaConstant.PROP_EXCLUSIVE_MINIMUM, type(BigDecimal.class)); + propertiesDataTypes.put(SchemaConstant.PROP_SCHEMA_DIALECT, type(String.class)); + propertiesDataTypes.put(SchemaConstant.PROP_COMMENT, type(String.class)); + propertiesDataTypes.put(SchemaConstant.PROP_IF, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_THEN, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_ELSE, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_DEPENDENT_SCHEMAS, mapOf(type(Schema.class))); + propertiesDataTypes.put(SchemaConstant.PROP_PREFIX_ITEMS, listOf(type(Schema.class))); + propertiesDataTypes.put(SchemaConstant.PROP_CONTAINS, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_PATTERN_PROPERTIES, mapOf(type(Schema.class))); + propertiesDataTypes.put(SchemaConstant.PROP_PROPERTY_NAMES, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_UNEVALUATED_ITEMS, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_UNEVALUATED_PROPERTIES, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_CONST, type(Object.class)); + propertiesDataTypes.put(SchemaConstant.PROP_MAX_CONTAINS, type(Integer.class)); + propertiesDataTypes.put(SchemaConstant.PROP_MIN_CONTAINS, type(Integer.class)); + propertiesDataTypes.put(SchemaConstant.PROP_DEPENDENT_REQUIRED, mapOf(listOf(type(String.class)))); + propertiesDataTypes.put(SchemaConstant.PROP_CONTENT_ENCODING, type(String.class)); + propertiesDataTypes.put(SchemaConstant.PROP_CONTENT_MEDIA_TYPE, type(String.class)); + propertiesDataTypes.put(SchemaConstant.PROP_CONTENT_SCHEMA, type(Schema.class)); + propertiesDataTypes.put(SchemaConstant.PROP_EXAMPLES, listOf(type(Object.class))); + + PROPERTIES_DATA_TYPES_3_0 = Collections.unmodifiableMap(propertiesDataTypes30); + PROPERTIES_DATA_TYPES = Collections.unmodifiableMap(propertiesDataTypes); + } + private SchemaConstant() { } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java index 819304718..5dc12f643 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java @@ -1,5 +1,7 @@ package io.smallrye.openapi.runtime.io.schema; +import static java.util.Arrays.asList; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; @@ -138,6 +140,13 @@ public static Schema readSchema(final AnnotationScannerContext context, return schema; } + String ref = readAttr(context, annotation, SchemaConstant.REF, defaults); + if (ref != null) { + schema.setRef(ref); + // If the annotation sets a ref, ignore any defaults passed in + defaults = Collections.emptyMap(); + } + schema.setNot(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_NOT, types -> readClassSchema(context, types, true), defaults)); schema.setOneOf(SchemaFactory.> readAttr(context, annotation, SchemaConstant.PROP_ONE_OF, @@ -146,15 +155,33 @@ public static Schema readSchema(final AnnotationScannerContext context, types -> readClassSchemas(context, types, false), defaults)); schema.setAllOf(SchemaFactory.> readAttr(context, annotation, SchemaConstant.PROP_ALL_OF, types -> readClassSchemas(context, types, true), defaults)); + schema.setIfSchema(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_IF_SCHEMA, + types -> readClassSchema(context, types, true), defaults)); + schema.setThenSchema(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_THEN_SCHEMA, + types -> readClassSchema(context, types, true), defaults)); + schema.setElseSchema(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_ELSE_SCHEMA, + types -> readClassSchema(context, types, true), defaults)); schema.setTitle(readAttr(context, annotation, SchemaConstant.PROP_TITLE, defaults)); schema.setMultipleOf(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_MULTIPLE_OF, BigDecimal::valueOf, defaults)); - schema.setMaximum(SchemaFactory.readAttr(context, annotation, SchemaConstant.PROP_MAXIMUM, - SchemaFactory::tolerantParseBigDecimal, defaults)); - schema.setMinimum(SchemaFactory.readAttr(context, annotation, SchemaConstant.PROP_MINIMUM, - SchemaFactory::tolerantParseBigDecimal, defaults)); - schema.setExclusiveMaximum(readAttr(context, annotation, SchemaConstant.PROP_EXCLUSIVE_MAXIMUM, defaults)); - schema.setExclusiveMinimum(readAttr(context, annotation, SchemaConstant.PROP_EXCLUSIVE_MINIMUM, defaults)); + BigDecimal maximum = SchemaFactory.readAttr(context, annotation, SchemaConstant.PROP_MAXIMUM, + SchemaFactory::tolerantParseBigDecimal, defaults); + BigDecimal minimum = SchemaFactory.readAttr(context, annotation, SchemaConstant.PROP_MINIMUM, + SchemaFactory::tolerantParseBigDecimal, defaults); + if (maximum != null) { + if (Boolean.TRUE.equals(readAttr(context, annotation, SchemaConstant.PROP_EXCLUSIVE_MAXIMUM, defaults))) { + schema.setExclusiveMaximum(maximum); + } else { + schema.setMaximum(maximum); + } + } + if (minimum != null) { + if (Boolean.TRUE.equals(readAttr(context, annotation, SchemaConstant.PROP_EXCLUSIVE_MINIMUM, defaults))) { + schema.setExclusiveMinimum(minimum); + } else { + schema.setMinimum(minimum); + } + } schema.setMaxLength(readAttr(context, annotation, SchemaConstant.PROP_MAX_LENGTH, defaults)); schema.setMinLength(readAttr(context, annotation, SchemaConstant.PROP_MIN_LENGTH, defaults)); schema.setPattern(readAttr(context, annotation, SchemaConstant.PROP_PATTERN, defaults)); @@ -163,21 +190,40 @@ public static Schema readSchema(final AnnotationScannerContext context, schema.setRequired(readAttr(context, annotation, SchemaConstant.PROP_REQUIRED_PROPERTIES, defaults)); schema.setDescription(readAttr(context, annotation, SchemaConstant.PROP_DESCRIPTION, defaults)); schema.setFormat(readAttr(context, annotation, SchemaConstant.PROP_FORMAT, defaults)); - schema.setRef(readAttr(context, annotation, SchemaConstant.REF, defaults)); - schema.setNullable(readAttr(context, annotation, SchemaConstant.PROP_NULLABLE, defaults)); + SchemaImpl.setNullable(schema, readAttr(context, annotation, SchemaConstant.PROP_NULLABLE, defaults)); schema.setReadOnly(readAttr(context, annotation, SchemaConstant.PROP_READ_ONLY, defaults)); schema.setWriteOnly(readAttr(context, annotation, SchemaConstant.PROP_WRITE_ONLY, defaults)); - schema.setExternalDocs(context.io().externalDocumentation().read(annotation.value(SchemaConstant.PROP_EXTERNAL_DOCS))); + schema.setExternalDocs(context.io().extDocIO().read(annotation.value(SchemaConstant.PROP_EXTERNAL_DOCS))); schema.setDeprecated(readAttr(context, annotation, SchemaConstant.PROP_DEPRECATED, defaults)); - schema.setType(readSchemaType(context, annotation, schema, defaults)); - schema.setExample(parseSchemaAttr(context, annotation, SchemaConstant.PROP_EXAMPLE, defaults, schema.getType())); + + final SchemaType type = readSchemaType(context, annotation, schema, defaults); + SchemaImpl.setType(schema, type); + + Object example = parseSchemaAttr(context, annotation, SchemaConstant.PROP_EXAMPLE, defaults, type); + List examples = SchemaFactory.> readAttr(context, annotation, + SchemaConstant.PROP_EXAMPLES, + egs -> Arrays.stream(egs) + .map(e -> parseValue(context, e, type)) + .collect(Collectors.toCollection(ArrayList::new)), + defaults); + if (examples != null) { + if (example != null) { + examples.add(example); + } + schema.setExamples(examples); + } else { + schema.setExamples(wrapInList(example)); + } + schema.setDefaultValue( - parseSchemaAttr(context, annotation, SchemaConstant.PROP_DEFAULT_VALUE, defaults, schema.getType())); - schema.setDiscriminator(context.io().schemas().discriminator().read(annotation)); + parseSchemaAttr(context, annotation, SchemaConstant.PROP_DEFAULT_VALUE, defaults, type)); + schema.setDiscriminator(context.io().discriminatorIO().read(annotation)); schema.setMaxItems(readAttr(context, annotation, SchemaConstant.PROP_MAX_ITEMS, defaults)); schema.setMinItems(readAttr(context, annotation, SchemaConstant.PROP_MIN_ITEMS, defaults)); schema.setUniqueItems(readAttr(context, annotation, SchemaConstant.PROP_UNIQUE_ITEMS, defaults)); - schema.setExtensions(context.io().extensions().readExtensible(annotation)); + schema.setExtensions(context.io().extensionIO().readExtensible(annotation)); + schema.setComment(readAttr(context, annotation, SchemaConstant.PROP_COMMENT_FIELD, defaults)); + schema.setConstValue(parseSchemaAttr(context, annotation, SchemaConstant.PROP_CONST_VALUE, defaults, type)); schema.setProperties(SchemaFactory.> readAttr(context, annotation, SchemaConstant.PROP_PROPERTIES, properties -> { @@ -194,19 +240,35 @@ public static Schema readSchema(final AnnotationScannerContext context, return propertySchemas; }, defaults)); - Type additionalProperties = readAttr(context, annotation, "additionalProperties", defaults); + schema.setAdditionalPropertiesSchema( + SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_ADDITIONAL_PROPERTIES, + types -> readClassSchema(context, types, true), defaults)); - if (additionalProperties != null) { - if (additionalProperties.name().equals(SchemaConstant.DOTNAME_TRUE_SCHEMA)) { - schema.setAdditionalPropertiesBoolean(Boolean.TRUE); - } else if (additionalProperties.name().equals(SchemaConstant.DOTNAME_FALSE_SCHEMA)) { - schema.setAdditionalPropertiesBoolean(Boolean.FALSE); - } else { - schema.setAdditionalPropertiesSchema(readClassSchema(context, additionalProperties, true)); - } - } + schema.setDependentRequired(SchemaFactory.>> readAttr(context, + annotation, SchemaConstant.PROP_DEPENDENT_REQUIRED, + annos -> readDependentRequired(context, annos), defaults)); + + schema.setDependentSchemas(SchemaFactory.> readAttr(context, annotation, + SchemaConstant.PROP_DEPENDENT_SCHEMAS, + annos -> readDependentSchemas(context, annos), defaults)); - final Schema.SchemaType type = schema.getType(); + schema.setContentEncoding(readAttr(context, annotation, SchemaConstant.PROP_CONTENT_ENCODING, defaults)); + schema.setContentMediaType(readAttr(context, annotation, SchemaConstant.PROP_CONTENT_MEDIA_TYPE, defaults)); + schema.setContentSchema(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_CONTENT_SCHEMA, + types -> readClassSchema(context, types, true), defaults)); + + schema.setContains(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_CONTAINS, + types -> readClassSchema(context, types, true), defaults)); + schema.setMaxContains(readAttr(context, annotation, SchemaConstant.PROP_MAX_CONTAINS, defaults)); + schema.setMinContains(readAttr(context, annotation, SchemaConstant.PROP_MIN_CONTAINS, defaults)); + schema.setPrefixItems( + SchemaFactory.> readAttr(context, annotation, SchemaConstant.PROP_PREFIX_ITEMS, + types -> readClassSchemas(context, types, true), defaults)); + schema.setPropertyNames(SchemaFactory. readAttr(context, annotation, SchemaConstant.PROP_PROPERTY_NAMES, + types -> readClassSchema(context, types, true), defaults)); + schema.setPatternProperties(SchemaFactory.> readAttr(context, annotation, + SchemaConstant.PROP_PATTERN_PROPERTIES, + annos -> readPatternProperties(context, annos), defaults)); List enumeration = readAttr(context, annotation, SchemaConstant.PROP_ENUMERATION, (Object[] values) -> { List parsed = new ArrayList<>(values.length); @@ -256,7 +318,7 @@ public static Schema includeTypeSchema(AnnotationScannerContext context, Schema implSchema = readClassSchema(context, type, false); } - if (schema.getType() == Schema.SchemaType.ARRAY && implSchema != null) { + if (schema.getType() != null && schema.getType().contains(Schema.SchemaType.ARRAY) && implSchema != null) { // If the @Schema annotation indicates an array type, then use the Schema // generated from the implementation Class as the "items" for the array. schema.setItems(implSchema); @@ -399,7 +461,17 @@ static T readAttr(AnnotationScannerContext context, AnnotationInstance an static SchemaType readSchemaType(AnnotationScannerContext context, AnnotationInstance annotation, Schema schema, Map defaults) { SchemaType type = readAttr(context, annotation, SchemaConstant.PROP_TYPE, SchemaFactory::parseSchemaType, defaults); - return type != null ? type : schema.getType(); + if (type != null) { + return type; + } + List types = schema.getType(); + if (types != null) { + return types.stream() + .filter(t -> t != SchemaType.NULL) + .findFirst() + .orElse(null); + } + return null; } /** @@ -417,6 +489,14 @@ static SchemaType parseSchemaType(String value) { } } + static List wrapInList(T value) { + if (value == null) { + return null; + } else { + return Collections.singletonList(value); + } + } + /** * Introspect into the given Class to generate a Schema model. The boolean indicates * whether this class type should be turned into a reference. @@ -430,8 +510,12 @@ static Schema readClassSchema(final AnnotationScannerContext context, Type type, return null; } Schema schema; - if (type.kind() == Type.Kind.ARRAY) { - schema = new SchemaImpl().type(SchemaType.ARRAY); + if (type.name().equals(SchemaConstant.DOTNAME_TRUE_SCHEMA)) { + schema = new SchemaImpl().booleanSchema(true); + } else if (type.name().equals(SchemaConstant.DOTNAME_FALSE_SCHEMA)) { + schema = new SchemaImpl().booleanSchema(false); + } else if (type.kind() == Type.Kind.ARRAY) { + schema = new SchemaImpl().addType(SchemaType.ARRAY); ArrayType array = type.asArrayType(); int dimensions = array.dimensions(); Type componentType = array.component(); @@ -500,7 +584,7 @@ public static Schema typeToSchema(final AnnotationScannerContext context, Type t TypeUtil.applyTypeAttributes(type, schema); schema = schemaRegistration(context, type, schema); } else if (type.kind() == Type.Kind.ARRAY) { - schema = new SchemaImpl().type(SchemaType.ARRAY); + schema = new SchemaImpl().addType(SchemaType.ARRAY); ArrayType array = type.asArrayType(); int dimensions = array.dimensions(); Type componentType = array.component(); @@ -687,7 +771,7 @@ private static Schema otherTypeToSchema(final AnnotationScannerContext context, List extensions) { if (TypeUtil.isA(context, type, MutinyConstants.MULTI_TYPE)) { // Treat as an Array - Schema schema = new SchemaImpl().type(SchemaType.ARRAY); + Schema schema = new SchemaImpl().addType(SchemaType.ARRAY); Type componentType = type.asParameterizedType().arguments().get(0); // Recurse using the type of the array elements @@ -723,4 +807,56 @@ private static BigDecimal tolerantParseBigDecimal(String value) { return null; } } + + private static Map> readDependentRequired(AnnotationScannerContext context, + AnnotationInstance[] requireds) { + if (requireds == null || requireds.length == 0) { + return null; + } + + Map> result = new LinkedHashMap<>(); + for (AnnotationInstance required : requireds) { + String name = context.annotations().value(required, SchemaConstant.PROP_NAME); + String[] requires = context.annotations().value(required, SchemaConstant.PROP_REQUIRES); + result.put(name, new ArrayList<>(asList(requires))); + } + + return result; + } + + private static Map readDependentSchemas(AnnotationScannerContext context, + AnnotationInstance[] dependentSchemas) { + if (dependentSchemas == null || dependentSchemas.length == 0) { + return null; + } + + Map result = new LinkedHashMap<>(); + for (AnnotationInstance dependentSchema : dependentSchemas) { + String name = context.annotations().value(dependentSchema, SchemaConstant.PROP_NAME); + Type schemaClass = context.annotations().value(dependentSchema, SchemaConstant.PROP_SCHEMA); + Schema schema = readClassSchema(context, schemaClass, true); + if (schema != null) { + result.put(name, schema); + } + } + return result; + } + + private static Map readPatternProperties(AnnotationScannerContext context, + AnnotationInstance[] patternProperties) { + if (patternProperties == null || patternProperties.length == 0) { + return null; + } + + Map result = new LinkedHashMap<>(); + for (AnnotationInstance patternProperty : patternProperties) { + String regex = context.annotations().value(patternProperty, SchemaConstant.PROP_REGEX); + Type schemaClass = context.annotations().value(patternProperty, SchemaConstant.PROP_SCHEMA); + Schema schema = readClassSchema(context, schemaClass, true); + if (schema != null) { + result.put(regex, schema); + } + } + return result; + } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowIO.java index 9ac8287ea..b05c2bd0f 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowIO.java @@ -10,7 +10,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class OAuthFlowIO extends ModelIO { @@ -19,13 +18,8 @@ public class OAuthFlowIO extends ModelIO oauthScopeIO; - private final ExtensionIO extensionIO; - - protected OAuthFlowIO(IOContext context, ExtensionIO extensionIO) { + public OAuthFlowIO(IOContext context) { super(context, Names.OAUTH_FLOW, Names.create(OAuthFlow.class)); - oauthScopeIO = new OAuthScopeIO<>(context); - this.extensionIO = extensionIO; } @Override @@ -35,8 +29,8 @@ public OAuthFlow read(AnnotationInstance annotation) { flow.setAuthorizationUrl(value(annotation, PROP_AUTHORIZATION_URL)); flow.setTokenUrl(value(annotation, PROP_TOKEN_URL)); flow.setRefreshUrl(value(annotation, PROP_REFRESH_URL)); - flow.setScopes(oauthScopeIO.readMap(annotation.value(PROP_SCOPES))); - flow.setExtensions(extensionIO.readExtensible(annotation)); + flow.setScopes(oauthScopeIO().readMap(annotation.value(PROP_SCOPES))); + flow.setExtensions(extensionIO().readExtensible(annotation)); return flow; } @@ -47,8 +41,8 @@ public OAuthFlow readObject(O node) { flow.setAuthorizationUrl(jsonIO().getString(node, PROP_AUTHORIZATION_URL)); flow.setTokenUrl(jsonIO().getString(node, PROP_TOKEN_URL)); flow.setRefreshUrl(jsonIO().getString(node, PROP_REFRESH_URL)); - flow.setScopes(oauthScopeIO.readMap(jsonIO().getValue(node, PROP_SCOPES))); - flow.setExtensions(extensionIO.readMap(node)); + flow.setScopes(oauthScopeIO().readMap(jsonIO().getValue(node, PROP_SCOPES))); + flow.setExtensions(extensionIO().readMap(node)); return flow; } @@ -58,8 +52,8 @@ public Optional write(OAuthFlow model) { setIfPresent(node, PROP_AUTHORIZATION_URL, jsonIO().toJson(model.getAuthorizationUrl())); setIfPresent(node, PROP_TOKEN_URL, jsonIO().toJson(model.getTokenUrl())); setIfPresent(node, PROP_REFRESH_URL, jsonIO().toJson(model.getRefreshUrl())); - setIfPresent(node, PROP_SCOPES, oauthScopeIO.write(model.getScopes())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_SCOPES, oauthScopeIO().write(model.getScopes())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowsIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowsIO.java index 1e4a03ff6..a68d5c121 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowsIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthFlowsIO.java @@ -10,7 +10,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class OAuthFlowsIO extends ModelIO { @@ -19,24 +18,19 @@ public class OAuthFlowsIO extends ModelIO oauthFlowIO; - private final ExtensionIO extensionIO; - - protected OAuthFlowsIO(IOContext context, ExtensionIO extensionIO) { + public OAuthFlowsIO(IOContext context) { super(context, Names.OAUTH_FLOWS, Names.create(OAuthFlows.class)); - oauthFlowIO = new OAuthFlowIO<>(context, extensionIO); - this.extensionIO = extensionIO; } @Override public OAuthFlows read(AnnotationInstance annotation) { IoLogging.logger.singleAnnotation("@OAuthFlows"); OAuthFlows flows = new OAuthFlowsImpl(); - flows.setImplicit(oauthFlowIO.read(annotation.value(PROP_IMPLICIT))); - flows.setPassword(oauthFlowIO.read(annotation.value(PROP_PASSWORD))); - flows.setClientCredentials(oauthFlowIO.read(annotation.value(PROP_CLIENT_CREDENTIALS))); - flows.setAuthorizationCode(oauthFlowIO.read(annotation.value(PROP_AUTHORIZATION_CODE))); - flows.setExtensions(extensionIO.readExtensible(annotation)); + flows.setImplicit(oauthFlowIO().read(annotation.value(PROP_IMPLICIT))); + flows.setPassword(oauthFlowIO().read(annotation.value(PROP_PASSWORD))); + flows.setClientCredentials(oauthFlowIO().read(annotation.value(PROP_CLIENT_CREDENTIALS))); + flows.setAuthorizationCode(oauthFlowIO().read(annotation.value(PROP_AUTHORIZATION_CODE))); + flows.setExtensions(extensionIO().readExtensible(annotation)); return flows; } @@ -44,22 +38,22 @@ public OAuthFlows read(AnnotationInstance annotation) { public OAuthFlows readObject(O node) { IoLogging.logger.singleJsonObject("OAuthFlows"); OAuthFlows flows = new OAuthFlowsImpl(); - flows.setImplicit(oauthFlowIO.readValue(jsonIO().getValue(node, PROP_IMPLICIT))); - flows.setPassword(oauthFlowIO.readValue(jsonIO().getValue(node, PROP_PASSWORD))); - flows.setClientCredentials(oauthFlowIO.readValue(jsonIO().getValue(node, PROP_CLIENT_CREDENTIALS))); - flows.setAuthorizationCode(oauthFlowIO.readValue(jsonIO().getValue(node, PROP_AUTHORIZATION_CODE))); - flows.setExtensions(extensionIO.readMap(node)); + flows.setImplicit(oauthFlowIO().readValue(jsonIO().getValue(node, PROP_IMPLICIT))); + flows.setPassword(oauthFlowIO().readValue(jsonIO().getValue(node, PROP_PASSWORD))); + flows.setClientCredentials(oauthFlowIO().readValue(jsonIO().getValue(node, PROP_CLIENT_CREDENTIALS))); + flows.setAuthorizationCode(oauthFlowIO().readValue(jsonIO().getValue(node, PROP_AUTHORIZATION_CODE))); + flows.setExtensions(extensionIO().readMap(node)); return flows; } @Override public Optional write(OAuthFlows model) { return optionalJsonObject(model).map(node -> { - setIfPresent(node, PROP_IMPLICIT, oauthFlowIO.write(model.getImplicit())); - setIfPresent(node, PROP_PASSWORD, oauthFlowIO.write(model.getPassword())); - setIfPresent(node, PROP_CLIENT_CREDENTIALS, oauthFlowIO.write(model.getClientCredentials())); - setIfPresent(node, PROP_AUTHORIZATION_CODE, oauthFlowIO.write(model.getAuthorizationCode())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_IMPLICIT, oauthFlowIO().write(model.getImplicit())); + setIfPresent(node, PROP_PASSWORD, oauthFlowIO().write(model.getPassword())); + setIfPresent(node, PROP_CLIENT_CREDENTIALS, oauthFlowIO().write(model.getClientCredentials())); + setIfPresent(node, PROP_AUTHORIZATION_CODE, oauthFlowIO().write(model.getAuthorizationCode())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthScopeIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthScopeIO.java index 7cd0bc9b5..b25a2e0e1 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthScopeIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/OAuthScopeIO.java @@ -15,7 +15,7 @@ public class OAuthScopeIO extends MapModelI private static final String PROP_DESCRIPTION = "description"; - protected OAuthScopeIO(IOContext context) { + public OAuthScopeIO(IOContext context) { super(context, Names.OAUTH_SCOPE, Names.create(String.class)); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityIO.java index a4a25ec01..91af29fb4 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityIO.java @@ -14,32 +14,27 @@ import org.jboss.jandex.AnnotationValue; import io.smallrye.openapi.runtime.io.IOContext; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class SecurityIO { - private final SecurityRequirementIO securityRequirementIO; - private final SecurityRequirementsSetIO securityRequirementsSetIO; - private final SecuritySchemeIO securitySchemeIO; + private final IOContext context; - public SecurityIO(IOContext context, ExtensionIO extensionIO) { - securityRequirementIO = new SecurityRequirementIO<>(context); - securityRequirementsSetIO = new SecurityRequirementsSetIO<>(context); - securitySchemeIO = new SecuritySchemeIO<>(context, extensionIO); + public SecurityIO(IOContext context) { + this.context = context; } public List readRequirements(AnnotationTarget target) { return Stream.of( - securityRequirementIO.readList(target), - securityRequirementsSetIO.readList(target)) + context.securityRequirementIO().readList(target), + context.securityRequirementsSetIO().readList(target)) .flatMap(Collection::stream) .collect(Collectors.toList()); } public List readRequirements(AnnotationValue annotations, AnnotationValue setAnnotations) { List> requirements = Stream.of( - securityRequirementIO.readList(annotations), - securityRequirementsSetIO.readList(setAnnotations)) + context.securityRequirementIO().readList(annotations), + context.securityRequirementsSetIO().readList(setAnnotations)) .filter(Objects::nonNull) .collect(Collectors.toList()); @@ -53,14 +48,14 @@ public List readRequirements(AnnotationValue annotations, A } public Map readSchemes(AnnotationTarget target) { - return securitySchemeIO.readMap(target); + return context.securitySchemeIO().readMap(target); } public List readRequirements(V node) { - return securityRequirementIO.readList(node); + return context.securityRequirementIO().readList(node); } public Optional write(List models) { - return securityRequirementIO.write(models); + return context.securityRequirementIO().write(models); } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityRequirementsSetIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityRequirementsSetIO.java index b69f73271..3c3a16683 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityRequirementsSetIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecurityRequirementsSetIO.java @@ -20,11 +20,8 @@ public class SecurityRequirementsSetIO extends ModelIO { - private final SecurityRequirementIO securityRequirementIO; - public SecurityRequirementsSetIO(IOContext context) { super(context, Names.SECURITY_REQUIREMENTS_SET, Names.create(SecurityRequirement.class)); - securityRequirementIO = new SecurityRequirementIO<>(context); } public List readList(AnnotationTarget target) { @@ -56,7 +53,7 @@ SecurityRequirement readSet(AnnotationInstance[] annotations) { SecurityRequirement requirement = new SecurityRequirementImpl(); Arrays.stream(annotations) - .map(securityRequirementIO::readEntry) + .map(securityRequirementIO()::readEntry) .forEach(scheme -> requirement.addScheme(scheme.getKey(), scheme.getValue())); return requirement; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIO.java index 03852a4f9..14b0662ed 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIO.java @@ -7,12 +7,12 @@ import io.smallrye.openapi.api.models.security.SecuritySchemeImpl; import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.io.IOContext.OpenApiVersion; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; import io.smallrye.openapi.runtime.io.ReferenceType; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class SecuritySchemeIO extends MapModelIO implements ReferenceIO { @@ -28,13 +28,8 @@ public class SecuritySchemeIO extends MapMo private static final String PROP_API_KEY_NAME = "apiKeyName"; private static final String PROP_SECURITY_SCHEME_NAME = "securitySchemeName"; - private final OAuthFlowsIO oauthFlowsIO; - private final ExtensionIO extensionIO; - - public SecuritySchemeIO(IOContext context, ExtensionIO extensionIO) { + public SecuritySchemeIO(IOContext context) { super(context, Names.SECURITY_SCHEME, Names.create(SecurityScheme.class)); - oauthFlowsIO = new OAuthFlowsIO<>(context, extensionIO); - this.extensionIO = extensionIO; } @Override @@ -52,10 +47,10 @@ public SecurityScheme read(AnnotationInstance annotation) { securityScheme.setIn(enumValue(annotation, PROP_IN, SecurityScheme.In.class)); securityScheme.setScheme(value(annotation, PROP_SCHEME)); securityScheme.setBearerFormat(value(annotation, PROP_BEARER_FORMAT)); - securityScheme.setFlows(oauthFlowsIO.read(annotation.value(PROP_FLOWS))); + securityScheme.setFlows(oauthFlowsIO().read(annotation.value(PROP_FLOWS))); securityScheme.setOpenIdConnectUrl(value(annotation, PROP_OPEN_ID_CONNECT_URL)); securityScheme.setRef(ReferenceType.SECURITY_SCHEME.refValue(annotation)); - securityScheme.setExtensions(extensionIO.readExtensible(annotation)); + securityScheme.setExtensions(extensionIO().readExtensible(annotation)); return securityScheme; } @@ -69,9 +64,9 @@ public SecurityScheme readObject(O node) { model.setIn(enumValue(jsonIO().getValue(node, PROP_IN), SecurityScheme.In.class)); model.setScheme(jsonIO().getString(node, PROP_SCHEME)); model.setBearerFormat(jsonIO().getString(node, PROP_BEARER_FORMAT)); - model.setFlows(oauthFlowsIO.readValue(jsonIO().getValue(node, PROP_FLOWS))); + model.setFlows(oauthFlowsIO().readValue(jsonIO().getValue(node, PROP_FLOWS))); model.setOpenIdConnectUrl(jsonIO().getString(node, PROP_OPEN_ID_CONNECT_URL)); - model.setExtensions(extensionIO.readMap(node)); + model.setExtensions(extensionIO().readMap(node)); return model; } @@ -80,6 +75,9 @@ public Optional write(SecurityScheme model) { return optionalJsonObject(model).map(node -> { if (isReference(model)) { setReference(node, model); + if (openApiVersion() == OpenApiVersion.V3_1) { + setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); + } } else { setIfPresent(node, PROP_TYPE, jsonIO().toJson(model.getType())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); @@ -87,9 +85,9 @@ public Optional write(SecurityScheme model) { setIfPresent(node, PROP_IN, jsonIO().toJson(model.getIn())); setIfPresent(node, PROP_SCHEME, jsonIO().toJson(model.getScheme())); setIfPresent(node, PROP_BEARER_FORMAT, jsonIO().toJson(model.getBearerFormat())); - setIfPresent(node, PROP_FLOWS, oauthFlowsIO.write(model.getFlows())); + setIfPresent(node, PROP_FLOWS, oauthFlowsIO().write(model.getFlows())); setIfPresent(node, PROP_OPEN_ID_CONNECT_URL, jsonIO().toJson(model.getOpenIdConnectUrl())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); } return node; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerIO.java index 749d84bce..0c3cac739 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerIO.java @@ -17,7 +17,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class ServerIO extends ModelIO { @@ -25,13 +24,8 @@ public class ServerIO extends ModelIO serverVariableIO; - private final ExtensionIO extensionIO; - - public ServerIO(IOContext context, ExtensionIO extensionIO) { + public ServerIO(IOContext context) { super(context, Names.SERVER, Names.create(Server.class)); - serverVariableIO = new ServerVariableIO<>(context, extensionIO); - this.extensionIO = extensionIO; } public List readList(AnnotationTarget target) { @@ -62,8 +56,8 @@ public Server read(AnnotationInstance annotation) { Server server = new ServerImpl(); server.setUrl(value(annotation, PROP_URL)); server.setDescription(value(annotation, PROP_DESCRIPTION)); - server.setVariables(serverVariableIO.readMap(annotation.value(PROP_VARIABLES))); - server.setExtensions(extensionIO.readExtensible(annotation)); + server.setVariables(serverVariableIO().readMap(annotation.value(PROP_VARIABLES))); + server.setExtensions(extensionIO().readExtensible(annotation)); return server; } @@ -96,8 +90,8 @@ public Server readObject(O node) { Server server = new ServerImpl(); server.setUrl(jsonIO().getString(node, PROP_URL)); server.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - server.setVariables(serverVariableIO.readMap(jsonIO().getValue(node, PROP_VARIABLES))); - server.setExtensions(extensionIO.readMap(node)); + server.setVariables(serverVariableIO().readMap(jsonIO().getValue(node, PROP_VARIABLES))); + server.setExtensions(extensionIO().readMap(node)); return server; } @@ -122,8 +116,8 @@ public Optional write(Server model) { private void write(Server model, OB node) { setIfPresent(node, PROP_URL, jsonIO().toJson(model.getUrl())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_VARIABLES, serverVariableIO.write(model.getVariables())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_VARIABLES, serverVariableIO().write(model.getVariables())); + setAllIfPresent(node, extensionIO().write(model)); } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerVariableIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerVariableIO.java index fe1786e84..22c142450 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerVariableIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/servers/ServerVariableIO.java @@ -12,7 +12,6 @@ import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class ServerVariableIO extends MapModelIO { @@ -23,11 +22,8 @@ public class ServerVariableIO extends MapMo // for annotations (reserved words in Java) private static final String PROP_ENUMERATION = "enumeration"; - private final ExtensionIO extensionIO; - - protected ServerVariableIO(IOContext context, ExtensionIO extensionIO) { + public ServerVariableIO(IOContext context) { super(context, Names.SERVER_VARIABLE, Names.create(ServerVariable.class)); - this.extensionIO = extensionIO; } @Override @@ -40,7 +36,7 @@ public ServerVariable read(AnnotationInstance annotation) { variable.setEnumeration(new ArrayList<>(Arrays.asList(enumeration))); } variable.setDefaultValue(value(annotation, PROP_DEFAULT_VALUE)); - variable.setExtensions(extensionIO.readExtensible(annotation)); + variable.setExtensions(extensionIO().readExtensible(annotation)); return variable; } @@ -50,7 +46,7 @@ public ServerVariable readObject(O node) { variable.setEnumeration(jsonIO().getArray(node, PROP_ENUM, jsonIO()::asString).orElse(null)); variable.setDefaultValue(jsonIO().getString(node, PROP_DEFAULT)); variable.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - variable.setExtensions(extensionIO.readMap(node)); + variable.setExtensions(extensionIO().readMap(node)); return variable; } @@ -59,7 +55,7 @@ public Optional write(ServerVariable model) { setIfPresent(node, PROP_DEFAULT, jsonIO().toJson(model.getDefaultValue())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); setIfPresent(node, PROP_ENUM, jsonIO().toJson(model.getEnumeration())); - setAllIfPresent(node, extensionIO.write(model)); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/tags/TagIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/tags/TagIO.java index 4b7313be1..0a063fe6b 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/tags/TagIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/tags/TagIO.java @@ -1,5 +1,7 @@ package io.smallrye.openapi.runtime.io.tags; +import static java.util.stream.Collectors.toList; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -15,13 +17,11 @@ import org.jboss.jandex.AnnotationValue; import io.smallrye.openapi.api.models.tags.TagImpl; -import io.smallrye.openapi.runtime.io.ExternalDocumentationIO; import io.smallrye.openapi.runtime.io.IOContext; import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.ModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; public class TagIO extends ModelIO implements ReferenceIO { @@ -32,13 +32,8 @@ public class TagIO extends ModelIO externalDocIO; - private final ExtensionIO extensionIO; - - public TagIO(IOContext context, ExtensionIO extensionIO) { + public TagIO(IOContext context) { super(context, Names.TAG, Names.create(Tag.class)); - externalDocIO = new ExternalDocumentationIO<>(context, extensionIO); - this.extensionIO = extensionIO; } public List readReferences(AnnotationTarget target) { @@ -54,6 +49,20 @@ public List readReferences(AnnotationTarget target) { return Stream.concat(tagsRefs, tagRefs).collect(Collectors.toList()); } + public List readReferences(AnnotationInstance[] annotations) { + return Optional.ofNullable(annotations) + .map(Arrays::asList) + .map(this::readReferences) + .orElse(null); + } + + public List readReferences(Collection annotations) { + return annotations.stream() + .map(a -> this. value(a, PROP_REF)) + .filter(Objects::nonNull) + .collect(toList()); + } + public List readList(AnnotationTarget target) { return readList(getRepeatableAnnotations(target)); } @@ -83,8 +92,8 @@ public Tag read(AnnotationInstance annotation) { Tag tag = new TagImpl(); tag.setName(value(annotation, PROP_NAME)); tag.setDescription(value(annotation, PROP_DESCRIPTION)); - tag.setExternalDocs(externalDocIO.read(annotation.value(PROP_EXTERNAL_DOCS))); - tag.setExtensions(extensionIO.readExtensible(annotation)); + tag.setExternalDocs(extDocIO().read(annotation.value(PROP_EXTERNAL_DOCS))); + tag.setExtensions(extensionIO().readExtensible(annotation)); return tag; } @@ -111,8 +120,8 @@ public Tag readObject(O node) { Tag tag = new TagImpl(); tag.setName(jsonIO().getString(node, PROP_NAME)); tag.setDescription(jsonIO().getString(node, PROP_DESCRIPTION)); - tag.setExternalDocs(externalDocIO.readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); - tag.setExtensions(extensionIO.readMap(node)); + tag.setExternalDocs(extDocIO().readValue(jsonIO().getValue(node, PROP_EXTERNAL_DOCS))); + tag.setExtensions(extensionIO().readMap(node)); return tag; } @@ -127,8 +136,8 @@ public Optional write(Tag model) { return optionalJsonObject(model).map(node -> { setIfPresent(node, PROP_NAME, jsonIO().toJson(model.getName())); setIfPresent(node, PROP_DESCRIPTION, jsonIO().toJson(model.getDescription())); - setIfPresent(node, PROP_EXTERNAL_DOCS, externalDocIO.write(model.getExternalDocs())); - setAllIfPresent(node, extensionIO.write(model)); + setIfPresent(node, PROP_EXTERNAL_DOCS, extDocIO().write(model.getExternalDocs())); + setAllIfPresent(node, extensionIO().write(model)); return node; }).map(jsonIO()::buildObject); } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/AnnotationScannerExtension.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/AnnotationScannerExtension.java index f6614ab20..212f5e50c 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/AnnotationScannerExtension.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/AnnotationScannerExtension.java @@ -36,11 +36,11 @@ static class Default implements AnnotationScannerExtension { private Default(AnnotationScannerContext scannerContext) { this.scannerContext = scannerContext; - if (scannerContext.getIoContext().jsonIO() == null) { - scannerContext.getIoContext().jsonIO(JsonIO.newInstance(scannerContext.getConfig())); + if (scannerContext.io().jsonIO() == null) { + scannerContext.io().jsonIO(JsonIO.newInstance(scannerContext.getConfig())); } - jsonIO = scannerContext.getIoContext().jsonIO(); + jsonIO = scannerContext.io().jsonIO(); } @Override @@ -51,7 +51,7 @@ public Object parseValue(String value) { @Override public Schema parseSchema(String jsonSchema) { Object schemaModel = jsonIO.fromString(jsonSchema, Format.JSON); - return scannerContext.io().schemas().readValue(schemaModel); + return scannerContext.io().schemaIO().readValue(schemaModel); } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java index a8c4543a2..dcebfb392 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java @@ -280,7 +280,7 @@ private OpenAPI processPackageOpenAPIDefinitions(final AnnotationScannerContext .collect(Collectors.toList()); for (AnnotationInstance packageDef : packageDefs) { - OpenAPI packageOai = context.io().read(packageDef); + OpenAPI packageOai = context.io().openApiDefinitionIO().read(packageDef); oai = MergeUtil.merge(oai, packageOai); } return oai; diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScanner.java index b70bdac65..3a1720bfd 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScanner.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.io.UncheckedIOException; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.BaseStream; @@ -207,7 +208,7 @@ Schema process() { if (rootClassInfo == null && objectStack.isEmpty()) { // If there's something on the objectStack stack then pre-scanning may have found something. ScannerLogging.logger.schemaTypeNotFound(rootClassType.name()); - return new SchemaImpl().type(SchemaType.OBJECT); + return new SchemaImpl().addType(SchemaType.OBJECT); } // Create root node. @@ -251,14 +252,15 @@ private void depthFirstGraphSearch() { TypeUtil.mapDeprecated(context, currentClass, currentSchema::getDeprecated, currentSchema::setDeprecated); currentPathEntry.setSchema(currentSchema); - if (currentSchema.getType() == null) { + if (!hasNonNullType(currentSchema)) { // If not schema has yet been set, consider this an "object" - currentSchema.setType(Schema.SchemaType.OBJECT); + currentSchema.setType(Collections.singletonList(Schema.SchemaType.OBJECT)); } else { maybeRegisterSchema(currentType, currentSchema, entrySchema); } - if (currentSchema.getType() == Schema.SchemaType.OBJECT) { + List types = currentSchema.getType(); + if (types != null && types.contains(Schema.SchemaType.OBJECT)) { // Only 'object' type schemas should have properties of their own ScannerLogging.logger.gettingFields(currentType, currentClass); @@ -295,15 +297,22 @@ private void maybeRegisterSchema(Type currentType, Schema currentSchema, Schema * - the target of the ref is the schema currently being processed and using the ref would * result in a self-referencing schema. */ - if (ref != currentSchema && currentSchema.getType() != Schema.SchemaType.OBJECT) { + if (ref != currentSchema && !currentSchema.getType().contains(Schema.SchemaType.OBJECT) && ref.getRef() != null) { Schema refTarget = context.getSchemaRegistry().lookupSchema(currentType, context.getJsonViews()); if (refTarget != entrySchema) { + SchemaImpl.clear(entrySchema); entrySchema.setRef(ref.getRef()); } } } + private static boolean hasNonNullType(Schema schema) { + List types = schema.getType(); + + return types != null && types.stream().anyMatch(t -> t != SchemaType.NULL); + } + private void processClassAnnotations(Schema schema, ClassInfo classInfo) { String xmlElementName = context.annotations().getAnnotationValue(classInfo, XML_ROOTELEMENT, PROP_NAME); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/SchemaRegistry.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/SchemaRegistry.java index 4b13c90d7..622747c55 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/SchemaRegistry.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/SchemaRegistry.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; @@ -268,7 +269,7 @@ private Schema registerReference(TypeKey key) { registry.put(key, new GeneratedSchemaInfo(name, null, schemaRef)); names.add(name); - return schemaRef; + return new SchemaImpl().ref(schemaRef.getRef()); } /** @@ -295,7 +296,7 @@ private Schema register(TypeKey key, Schema schema, String schemaName) { ModelUtil.components(oai).addSchema(name, schema); - return schemaRef; + return new SchemaImpl().ref(schemaRef.getRef()); } String deriveName(TypeKey key, String schemaName) { @@ -343,7 +344,8 @@ public boolean isTypeRegistrationSupported(Type type, Schema schema) { return false; } if (!config.arrayReferencesEnable()) { - return !SchemaType.ARRAY.equals(schema.getType()); + List types = schema.getType(); + return types == null || !types.contains(SchemaType.ARRAY); } return true; } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/AnnotationTargetProcessor.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/AnnotationTargetProcessor.java index 18fb72b34..23fa572e7 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/AnnotationTargetProcessor.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/AnnotationTargetProcessor.java @@ -4,6 +4,7 @@ import static io.smallrye.openapi.api.constants.JaxbConstants.XML_ATTRIBUTE; import static io.smallrye.openapi.api.constants.JaxbConstants.XML_ELEMENT; import static io.smallrye.openapi.api.constants.JaxbConstants.XML_WRAPPERELEMENT; +import static java.util.Collections.singletonList; import java.util.Arrays; import java.util.Collections; @@ -194,8 +195,8 @@ Schema processField() { } } - if (fieldSchema.getNullable() == null && TypeUtil.isOptional(entityType)) { - fieldSchema.setNullable(Boolean.TRUE); + if (SchemaImpl.getNullable(fieldSchema) == null && TypeUtil.isOptional(entityType)) { + SchemaImpl.setNullable(fieldSchema, Boolean.TRUE); } if (fieldSchema.getReadOnly() == null && typeResolver.isReadOnly()) { @@ -224,8 +225,9 @@ Schema processField() { } else { typeProcessor.pushObjectStackInput(); Schema registeredTypeSchema; + List typeList = typeSchema.getType(); - if (typeSchema.getType() != SchemaType.ARRAY) { + if (typeList != null && !typeList.contains(SchemaType.ARRAY)) { // Only register a reference to the type schema. The full schema will be added by subsequent // items on the stack (if not already present in the registry). registeredTypeSchema = schemaRegistry.registerReference(registrationType, context.getJsonViews(), @@ -236,15 +238,32 @@ Schema processField() { typeResolver, typeSchema); } - if (fieldSchema.getAllOf() == null && (fieldAssertionsOverrideType(fieldSchema, typeSchema) + // Field schema may be replaced by a reference, so check now if it permits null + boolean fieldSchemaNullable = isNullable(fieldSchema); + + if (fieldSchema.getRef() == null && (fieldAssertionsOverrideType(fieldSchema, typeSchema) || fieldSpecifiesAnnotation(fieldSchema))) { // Field declaration overrides a schema annotation (non-validating), add referenced type to `allOf` if not user-provided TypeUtil.clearMatchingDefaultAttributes(fieldSchema, typeSchema); - fieldSchema.addAllOf(registeredTypeSchema); + fieldSchema.setRef(registeredTypeSchema.getRef()); SchemaImpl.addTypeObserver(typeSchema, fieldSchema); } else { fieldSchema = registeredTypeSchema; // Reference to the type schema } + + // If the field should allow null but the type schema doesn't, use anyOf to allow null + if (fieldSchemaNullable && !isNullable(typeSchema)) { + Schema nullSchema = new SchemaImpl().type(singletonList(Schema.SchemaType.NULL)); + // Move reference to type into its own subschema + Schema refSchema = new SchemaImpl().ref(fieldSchema.getRef()); + fieldSchema.setRef(null); + if (fieldSchema.getAnyOf() == null) { + fieldSchema.addAnyOf(refSchema).addAnyOf(nullSchema); + } else { + Schema anyOfSchema = new SchemaImpl().addAnyOf(refSchema).addAnyOf(nullSchema); + fieldSchema.addAllOf(anyOfSchema); + } + } } } else if (!JandexUtil.isRef(schemaAnnotation)) { /* @@ -262,6 +281,11 @@ Schema processField() { return fieldSchema; } + private boolean isNullable(Schema schema) { + List types = schema.getType(); + return types != null && types.contains(Schema.SchemaType.NULL); + } + private void processFieldAnnotations(Schema fieldSchema, TypeResolver typeResolver) { String name = typeResolver.getBeanPropertyName(); @@ -392,7 +416,6 @@ boolean fieldSpecifiesAnnotation(Schema fieldSchema) { * @see https://json-schema.org/draft/2020-12/json-schema-core.html#rfc.section.7.6 */ private static final List> SCHEMA_ASSERTION_PROVIDERS = Arrays.asList( - Schema::getAdditionalPropertiesBoolean, Schema::getAdditionalPropertiesSchema, Schema::getAllOf, Schema::getAnyOf, @@ -412,13 +435,11 @@ boolean fieldSpecifiesAnnotation(Schema fieldSchema) { Schema::getMinProperties, Schema::getMultipleOf, Schema::getNot, - Schema::getNullable, Schema::getOneOf, Schema::getPattern, Schema::getProperties, Schema::getRef, Schema::getRequired, - //Schema::getType, Schema::getUniqueItems, Schema::getXml); @@ -430,6 +451,7 @@ boolean fieldSpecifiesAnnotation(Schema fieldSchema) { Schema::getDeprecated, Schema::getDescription, Schema::getExample, + Schema::getExamples, Schema::getExtensions, Schema::getExternalDocs, Schema::getReadOnly, diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScanner.java index a800c18c5..fa401df30 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScanner.java @@ -3,6 +3,7 @@ import static org.jboss.jandex.DotName.createComponentized; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -18,6 +19,7 @@ import io.smallrye.openapi.api.constants.JacksonConstants; import io.smallrye.openapi.api.constants.KotlinConstants; +import io.smallrye.openapi.api.models.media.SchemaImpl; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; import io.smallrye.openapi.runtime.util.JandexUtil; @@ -165,35 +167,39 @@ public void applyConstraints(AnnotationTarget target, String propertyKey, RequirementHandler handler) { - SchemaType schemaType = schema.getType(); + List schemaTypes = schema.getType(); /* * The type be set. Attributes set in this function are not application * to $ref type schemas. */ - if (schemaType == null || schema.getRef() != null) { + if (schemaTypes == null || schemaTypes.isEmpty() || schema.getRef() != null) { return; } - switch (schemaType) { - case ARRAY: - applyArrayConstraints(target, schema, propertyKey, handler); - break; - case BOOLEAN: - applyBooleanConstraints(target, schema, propertyKey, handler); - break; - case INTEGER: - applyNumberConstraints(target, schema, propertyKey, handler); - break; - case NUMBER: - applyNumberConstraints(target, schema, propertyKey, handler); - break; - case OBJECT: - applyObjectConstraints(target, schema, propertyKey, handler); - break; - case STRING: - applyStringConstraints(target, schema, propertyKey, handler); - break; + for (SchemaType schemaType : new ArrayList<>(schemaTypes)) { + switch (schemaType) { + case ARRAY: + applyArrayConstraints(target, schema, propertyKey, handler); + break; + case BOOLEAN: + applyBooleanConstraints(target, schema, propertyKey, handler); + break; + case INTEGER: + applyNumberConstraints(target, schema, propertyKey, handler); + break; + case NUMBER: + applyNumberConstraints(target, schema, propertyKey, handler); + break; + case OBJECT: + applyObjectConstraints(target, schema, propertyKey, handler); + break; + case STRING: + applyStringConstraints(target, schema, propertyKey, handler); + break; + default: + break; + } } } @@ -270,16 +276,16 @@ private void applyBooleanConstraints(AnnotationTarget target, void decimalMax(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_DECIMAL_MAX); - if (constraint != null && schema.getMaximum() == null) { + if (constraint != null && schema.getMaximum() == null && schema.getExclusiveMaximum() == null) { String decimalValue = context.annotations().value(constraint, VALUE); + Boolean inclusive = context.annotations().value(constraint, INCLUSIVE); try { BigDecimal decimal = new BigDecimal(decimalValue); - schema.setMaximum(decimal); - - Boolean inclusive = context.annotations().value(constraint, INCLUSIVE); - if (schema.getExclusiveMaximum() == null && Boolean.FALSE.equals(inclusive)) { - schema.setExclusiveMaximum(Boolean.TRUE); + if (Boolean.FALSE.equals(inclusive)) { + schema.setExclusiveMaximum(decimal); + } else { + schema.setMaximum(decimal); } } catch (@SuppressWarnings("unused") NumberFormatException e) { DataObjectLogging.logger.invalidAnnotationFormat(decimalValue); @@ -290,15 +296,16 @@ void decimalMax(AnnotationTarget target, Schema schema) { void decimalMin(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_DECIMAL_MIN); - if (constraint != null && schema.getMinimum() == null) { + if (constraint != null && schema.getMinimum() == null && schema.getExclusiveMinimum() == null) { String decimalValue = context.annotations().value(constraint, VALUE); + Boolean inclusive = context.annotations().value(constraint, INCLUSIVE); try { BigDecimal decimal = new BigDecimal(decimalValue); - schema.setMinimum(decimal); - Boolean inclusive = context.annotations().value(constraint, INCLUSIVE); - if (schema.getExclusiveMinimum() == null && Boolean.FALSE.equals(inclusive)) { - schema.setExclusiveMinimum(Boolean.TRUE); + if (Boolean.FALSE.equals(inclusive)) { + schema.setExclusiveMinimum(decimal); + } else { + schema.setMinimum(decimal); } } catch (@SuppressWarnings("unused") NumberFormatException e) { DataObjectLogging.logger.invalidAnnotationFormat(decimalValue); @@ -362,29 +369,16 @@ void min(AnnotationTarget target, Schema schema) { void negative(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_NEGATIVE); - if (constraint != null && schema.getMaximum() == null) { - Boolean exclusive = schema.getExclusiveMaximum(); - - if (exclusive == null || exclusive) { - schema.setMaximum(BigDecimal.ZERO); - schema.setExclusiveMaximum(Boolean.TRUE); - } else { - schema.setMaximum(NEGATIVE_ONE); - } + if (constraint != null && schema.getMaximum() == null && schema.getExclusiveMaximum() == null) { + schema.setExclusiveMaximum(BigDecimal.ZERO); } } void negativeOrZero(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_NEGATIVE_OR_ZERO); - if (constraint != null && schema.getMaximum() == null) { - Boolean exclusive = schema.getExclusiveMaximum(); - - if (exclusive != null && exclusive) { - schema.setMaximum(BigDecimal.ONE); - } else { - schema.setMaximum(BigDecimal.ZERO); - } + if (constraint != null && schema.getMaximum() == null && schema.getExclusiveMaximum() == null) { + schema.setMaximum(BigDecimal.ZERO); } } @@ -455,8 +449,8 @@ void notNullKotlin(AnnotationTarget target, String propertyKey, RequirementHandl } void nullableKotlin(AnnotationTarget target, Schema schema) { - if (context.annotations().hasAnnotation(target, KOTLIN_NULLABLE) && schema.getNullable() == null) { - schema.setNullable(Boolean.TRUE); + if (context.annotations().hasAnnotation(target, KOTLIN_NULLABLE) && SchemaImpl.getNullable(schema) == null) { + SchemaImpl.setNullable(schema, Boolean.TRUE); } } @@ -471,29 +465,16 @@ void pattern(AnnotationTarget target, Schema schema) { void positive(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_POSITIVE); - if (constraint != null && schema.getMinimum() == null) { - Boolean exclusive = schema.getExclusiveMinimum(); - - if (exclusive == null || exclusive) { - schema.setMinimum(BigDecimal.ZERO); - schema.setExclusiveMinimum(Boolean.TRUE); - } else { - schema.setMinimum(BigDecimal.ONE); - } + if (constraint != null && schema.getMinimum() == null && schema.getExclusiveMinimum() == null) { + schema.setExclusiveMinimum(BigDecimal.ZERO); } } void positiveOrZero(AnnotationTarget target, Schema schema) { AnnotationInstance constraint = getConstraint(target, BV_POSITIVE_OR_ZERO); - if (constraint != null && schema.getMinimum() == null) { - Boolean exclusive = schema.getExclusiveMinimum(); - - if (exclusive != null && exclusive) { - schema.setMinimum(NEGATIVE_ONE); - } else { - schema.setMinimum(BigDecimal.ZERO); - } + if (constraint != null && schema.getMinimum() == null && schema.getExclusiveMinimum() == null) { + schema.setMinimum(BigDecimal.ZERO); } } @@ -561,12 +542,6 @@ void sizeString(AnnotationTarget target, Schema schema) { } boolean allowsAdditionalProperties(Schema schema) { - Boolean additionalProperties = schema.getAdditionalPropertiesBoolean(); - - if (additionalProperties != null) { - return additionalProperties; - } - return schema.getAdditionalPropertiesSchema() != null; } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java index eacf13706..8e2c6169c 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java @@ -8,11 +8,13 @@ import static io.smallrye.openapi.runtime.scanner.OpenApiDataObjectScanner.STREAM_TYPE; import static io.smallrye.openapi.runtime.scanner.OpenApiDataObjectScanner.STRING_TYPE; import static io.smallrye.openapi.runtime.util.TypeUtil.isTerminalType; +import static java.util.Collections.singletonList; import java.util.ArrayList; import java.util.List; import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.ArrayType; @@ -152,7 +154,7 @@ private Type readArrayType(ArrayType arrayType, Schema arraySchema) { // Array-type schema Schema itemSchema = new SchemaImpl(); - arraySchema.type(Schema.SchemaType.ARRAY); + arraySchema.addType(Schema.SchemaType.ARRAY); Type componentType = typeResolver.resolve(arrayType.component()); boolean isOptional = TypeUtil.isOptional(componentType); @@ -177,7 +179,7 @@ private Type readArrayType(ArrayType arrayType, Schema arraySchema) { while (arrayType.dimensions() > 1) { Schema parentArrSchema = new SchemaImpl(); - parentArrSchema.setType(Schema.SchemaType.ARRAY); + parentArrSchema.addType(Schema.SchemaType.ARRAY); parentArrSchema.setItems(itemSchema); itemSchema = parentArrSchema; @@ -201,7 +203,7 @@ private Type readParameterizedType(ParameterizedType pType, Schema schema) { // If it's a collection, iterable, or a stream, we should treat it as an array. if (seekType != null && seekType != MAP_TYPE) { DataObjectLogging.logger.processingTypeAs("Java Iterable or Stream", "Array"); - schema.type(Schema.SchemaType.ARRAY); + SchemaImpl.setType(schema, Schema.SchemaType.ARRAY); ParameterizedType ancestorType = TypeResolver.resolveParameterizedAncestor(context, pType, seekType) .orElse(pType); @@ -226,7 +228,7 @@ private Type readParameterizedType(ParameterizedType pType, Schema schema) { typeRead = ARRAY_TYPE_OBJECT; // Representing collection as JSON array } else if (seekType == MAP_TYPE) { DataObjectLogging.logger.processingTypeAs("Map", "object"); - schema.type(Schema.SchemaType.OBJECT); + SchemaImpl.setType(schema, Schema.SchemaType.OBJECT); ParameterizedType ancestorType = TypeResolver.resolveParameterizedAncestor(context, pType, seekType) .orElse(pType); @@ -265,8 +267,8 @@ private Type resolveSeekType(ParameterizedType pType) { private static Schema wrapOptionalItemSchema(Schema itemSchema) { return new SchemaImpl() - .nullable(Boolean.TRUE) - .addAllOf(itemSchema); + .addAnyOf(new SchemaImpl().type(singletonList(Schema.SchemaType.NULL))) + .addAnyOf(itemSchema); } private Schema readGenericValueType(Type valueType) { @@ -289,7 +291,7 @@ private Schema resolveParameterizedType(Type valueType, Schema propsSchema) { valueType.kind() == Type.Kind.WILDCARD_TYPE) { Type resolved = resolveTypeVariable(propsSchema, valueType, true); if (index.containsClass(resolved)) { - propsSchema.type(Schema.SchemaType.OBJECT); + SchemaImpl.setType(propsSchema, Schema.SchemaType.OBJECT); propsSchema = context.getSchemaRegistry().registerReference(valueType, context.getJsonViews(), typeResolver, propsSchema); } @@ -298,7 +300,7 @@ private Schema resolveParameterizedType(Type valueType, Schema propsSchema) { DataObjectLogging.logger.processingEnum(type); propsSchema = SchemaFactory.enumToSchema(context, valueType); } else { - propsSchema.type(Schema.SchemaType.OBJECT); + SchemaImpl.setType(propsSchema, Schema.SchemaType.OBJECT); } SchemaRegistry registry = context.getSchemaRegistry(); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AbstractParameterProcessor.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AbstractParameterProcessor.java index e3c8d58ee..61db6e955 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AbstractParameterProcessor.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AbstractParameterProcessor.java @@ -400,7 +400,8 @@ boolean templateParameterPatternEligible(Parameter param) { return Parameter.In.PATH.equals(param.getIn()) && !Style.MATRIX.equals(param.getStyle()) && param.getSchema() != null - && SchemaType.STRING.equals(param.getSchema().getType()) + && param.getSchema().getType() != null + && param.getSchema().getType().contains(SchemaType.STRING) && param.getSchema().getPattern() == null; } @@ -463,7 +464,7 @@ private void mapMatrixParameters() { if (schemas.isEmpty()) { // ParameterContext was generated above or no @Schema was provided on the @Parameter style=matrix Schema schema = new SchemaImpl(); - schema.setType(SchemaType.OBJECT); + schema.addType(SchemaType.OBJECT); ModelUtil.setParameterSchema(context.oaiParam, schema); schemas = Arrays.asList(schema); } @@ -578,7 +579,7 @@ void mapParameterSchema(Parameter param, ParameterContext context) { void mapParameterExtensions(Parameter param, ParameterContext context) { if (param.getExtensions() == null) { - param.setExtensions(scannerContext.io().extensions().readMap(context.target)); + param.setExtensions(scannerContext.io().extensionIO().readMap(context.target)); } } @@ -625,7 +626,7 @@ void augmentParamSchema(Parameter param, ParameterContext context) { if (refSchema != null) { localSchema = new SchemaImpl().type(refSchema.getType()); } else { - localSchema = new SchemaImpl().type(SchemaType + localSchema = new SchemaImpl().addType(SchemaType .valueOf(TypeUtil.getTypeAttributes(paramType).get(SchemaConstant.PROP_TYPE).toString().toUpperCase())); } } else { @@ -647,7 +648,7 @@ void augmentParamSchema(Parameter param, ParameterContext context) { if (localOnlySchemaModified(paramSchema, localSchema, modCount)) { // Add new `allOf` schema, erasing `type` derived above from the local schema - Schema allOf = new SchemaImpl().addAllOf(paramSchema).addAllOf(localSchema.type(null)); + Schema allOf = new SchemaImpl().addAllOf(paramSchema).addAllOf(localSchema.type((List) null)); param.setSchema(allOf); } } @@ -696,8 +697,8 @@ protected void setSchemaProperties(Schema schema, (target, name) -> setRequired(name, schema)); } - if (paramSchema.getNullable() == null && TypeUtil.isOptional(paramType)) { - paramSchema.setNullable(Boolean.TRUE); + if (SchemaImpl.getNullable(paramSchema) == null && TypeUtil.isOptional(paramType)) { + SchemaImpl.setNullable(paramSchema, Boolean.TRUE); } if (schema.getProperties() != null) { @@ -753,7 +754,7 @@ protected Content getFormBodyContent() { MediaType mediaType = new MediaTypeImpl(); Schema schema = new SchemaImpl(); Map encodings = new HashMap<>(); - schema.setType(SchemaType.OBJECT); + schema.addType(SchemaType.OBJECT); mediaType.setSchema(schema); if (APPLICATION_FORM_URLENCODED.equals(mediaTypeName)) { diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java index 019b9a3b2..497b8436b 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java @@ -1,5 +1,6 @@ package io.smallrye.openapi.runtime.scanner.spi; +import static java.util.Collections.singletonList; import static org.jboss.jandex.AnnotationTarget.Kind.METHOD_PARAMETER; import java.util.ArrayList; @@ -126,7 +127,7 @@ default Type unwrapType(Type type) { * @param targetClass the class that contain the server annotation */ default OpenAPI processDefinitionAnnotation(final AnnotationScannerContext context, final ClassInfo targetClass) { - return Optional.ofNullable(context.io().read(targetClass)) + return Optional.ofNullable(context.io().openApiDefinitionIO().read(targetClass)) .orElseGet(() -> new OpenAPIImpl().openapi(SmallRyeOASConfig.Defaults.VERSION)); } @@ -139,7 +140,7 @@ default OpenAPI processDefinitionAnnotation(final AnnotationScannerContext conte default void processSecuritySchemeAnnotation(final AnnotationScannerContext context, final ClassInfo targetClass, OpenAPI openApi) { - context.io().security().readSchemes(targetClass) + context.io().securityIO().readSchemes(targetClass) .forEach((name, scheme) -> ModelUtil.components(openApi).addSecurityScheme(name, scheme)); } @@ -150,7 +151,7 @@ default void processSecuritySchemeAnnotation(final AnnotationScannerContext cont * @param openApi the current OpenApi model being created */ default void processServerAnnotation(final AnnotationScannerContext context, final ClassInfo targetClass, OpenAPI openApi) { - context.io().servers().readList(targetClass).forEach(openApi::addServer); + context.io().serverIO().readList(targetClass).forEach(openApi::addServer); } /** @@ -207,13 +208,13 @@ default void processOperationTags(final AnnotationScannerContext context, final default Set processTags(final AnnotationScannerContext context, final AnnotationTarget target, OpenAPI openApi, final boolean nullWhenMissing) { - if (!context.io().tags().hasRepeatableAnnotation(target)) { + if (!context.io().tagIO().hasRepeatableAnnotation(target)) { return nullWhenMissing ? null : Collections.emptySet(); } Set tags = new LinkedHashSet<>(); - context.io().tags().readList(target) + context.io().tagIO().readList(target) .stream() .filter(tag -> Objects.nonNull(tag.getName())) .forEach(tag -> { @@ -221,7 +222,7 @@ default Set processTags(final AnnotationScannerContext context, final An ModelUtil.addTag(openApi, tag); }); - context.io().tags().readReferences(target).forEach(tags::add); + context.io().tagIO().readReferences(target).forEach(tags::add); return tags; } @@ -268,11 +269,11 @@ default List getResourceMethods(final AnnotationScannerContext conte default Optional processOperation(final AnnotationScannerContext context, final ClassInfo resourceClass, final MethodInfo method) { - if (context.io().operations().isHidden(method)) { + if (context.io().operationIO().isHidden(method)) { return Optional.empty(); } - OperationImpl operation = (OperationImpl) context.io().operations().read(method); + OperationImpl operation = (OperationImpl) context.io().operationIO().read(method); if (operation == null) { operation = new OperationImpl(); @@ -357,16 +358,16 @@ default void processResponse(final AnnotationScannerContext context, final Class setJsonViewContext(context, context.annotations().getAnnotationValue(method, JacksonConstants.JSON_VIEW)); - Optional classResponses = Optional.ofNullable(context.io().responses().read(resourceClass)); - Map classResponse = context.io().responses().readSingle(resourceClass); + Optional classResponses = Optional.ofNullable(context.io().apiResponsesIO().read(resourceClass)); + Map classResponse = context.io().apiResponsesIO().readSingle(resourceClass); addResponses(operation, classResponses, classResponse, false); // Method annotations override class annotations - Optional methodResponses = Optional.ofNullable(context.io().responses().read(method)); - Map methodResponse = context.io().responses().readSingle(method); + Optional methodResponses = Optional.ofNullable(context.io().apiResponsesIO().read(method)); + Map methodResponse = context.io().apiResponsesIO().readSingle(method); addResponses(operation, methodResponses, methodResponse, true); - context.io().responses().readResponseSchema(method) + context.io().apiResponsesIO().readResponseSchema(method) .ifPresent(responseSchema -> addApiReponseSchemaFromAnnotation(responseSchema, method, operation)); /* @@ -375,7 +376,7 @@ default void processResponse(final AnnotationScannerContext context, final Class * provides a way for the application to indicate that responses will be supplied some other * way (i.e. static file). */ - if (methodResponses.isPresent() || context.io().responses().getAnnotation(method) == null) { + if (methodResponses.isPresent() || context.io().apiResponsesIO().getAnnotation(method) == null) { createResponseFromRestMethod(context, method, operation); } @@ -456,7 +457,7 @@ default void createResponseFromRestMethod(final AnnotationScannerContext context Schema schema; if (isMultipartOutput(returnType)) { - schema = new SchemaImpl().type(Schema.SchemaType.OBJECT); + schema = new SchemaImpl().addType(Schema.SchemaType.OBJECT); } else if (hasKotlinContinuation(method)) { schema = kotlinContinuationToSchema(context, method); } else { @@ -470,8 +471,22 @@ default void createResponseFromRestMethod(final AnnotationScannerContext context produces = getDefaultProduces(context, method); } - if (schema != null && schema.getNullable() == null && TypeUtil.isOptional(returnType)) { - schema.setNullable(Boolean.TRUE); + if (schema != null && SchemaImpl.getNullable(schema) == null && TypeUtil.isOptional(returnType)) { + if (schema.getType() != null) { + schema.addType(Schema.SchemaType.NULL); + } + if (schema.getRef() != null) { + Schema nullSchema = new SchemaImpl().type(singletonList(Schema.SchemaType.NULL)); + // Move reference to type into its own subschema + Schema refSchema = new SchemaImpl().ref(schema.getRef()); + schema.setRef(null); + if (schema.getAnyOf() == null) { + schema.addAnyOf(refSchema).addAnyOf(nullSchema); + } else { + Schema anyOfSchema = new SchemaImpl().addAnyOf(refSchema).addAnyOf(nullSchema); + schema.addAllOf(anyOfSchema); + } + } } for (String producesType : produces) { @@ -645,11 +660,11 @@ default void processSecurityRequirementAnnotation(AnnotationScannerContext conte final MethodInfo method, Operation operation) { - List securityRequirements = context.io().security().readRequirements(method); + List securityRequirements = context.io().securityIO().readRequirements(method); boolean emptyContainerPresent = isEmptySecurityRequirements(context, method); if (securityRequirements.isEmpty() && !emptyContainerPresent) { - securityRequirements = context.io().security().readRequirements(resourceClass); + securityRequirements = context.io().securityIO().readRequirements(resourceClass); } if (securityRequirements.isEmpty() && emptyContainerPresent) { @@ -682,7 +697,7 @@ default boolean isEmptySecurityRequirements(AnnotationScannerContext context, An * @param operation the operation to add this to */ default void processCallback(final AnnotationScannerContext context, final MethodInfo method, Operation operation) { - Map callbacks = context.io().components().callbacks().readMap(method); + Map callbacks = context.io().componentsIO().callbacks().readMap(method); if (!callbacks.isEmpty()) { operation.setCallbacks(callbacks); @@ -696,10 +711,10 @@ default void processCallback(final AnnotationScannerContext context, final Metho * @param operation the current Operation model being created */ default void processServerAnnotation(final AnnotationScannerContext context, final MethodInfo method, Operation operation) { - List servers = context.io().servers().readList(method); + List servers = context.io().serverIO().readList(method); if (servers.isEmpty()) { - servers = context.io().servers().readList(method.declaringClass()); + servers = context.io().serverIO().readList(method.declaringClass()); } servers.forEach(operation::addServer); @@ -713,10 +728,10 @@ default void processServerAnnotation(final AnnotationScannerContext context, fin * @param operation the current operation */ default void processExtensions(final AnnotationScannerContext context, final MethodInfo method, Operation operation) { - Map methodExtensions = context.io().extensions().readMap(method); + Map methodExtensions = context.io().extensionIO().readMap(method); if (methodExtensions.isEmpty()) { - context.io().extensions().readMap(method.declaringClass()).forEach(operation::addExtension); + context.io().extensionIO().readMap(method.declaringClass()).forEach(operation::addExtension); } else { methodExtensions.forEach(operation::addExtension); } @@ -748,8 +763,8 @@ default RequestBody processRequestBody(final AnnotationScannerContext context, final ResourceParameters params) { RequestBody requestBody = null; - for (AnnotationInstance annotation : context.io().requestBodies().getRepeatableAnnotations(method)) { - requestBody = context.io().requestBodies().read(annotation); + for (AnnotationInstance annotation : context.io().requestBodyIO().getRepeatableAnnotations(method)) { + requestBody = context.io().requestBodyIO().read(annotation); Content formBodyContent = params.getFormBodyContent(); if (formBodyContent != null) { @@ -785,7 +800,7 @@ default RequestBody processRequestBody(final AnnotationScannerContext context, } } - if (requestBody.getRequired() == null && TypeUtil.isOptional(requestBodyType)) { + if (!RequestBodyImpl.isRequiredSet(requestBody) && TypeUtil.isOptional(requestBodyType)) { requestBody.setRequired(Boolean.FALSE); } @@ -794,7 +809,7 @@ default RequestBody processRequestBody(final AnnotationScannerContext context, } if (requestBody == null) { - requestBody = context.io().requestBodies().readRequestSchema(method); + requestBody = context.io().requestBodyIO().readRequestSchema(method); } // If the request body is null, figure it out from the parameters. Only if the @@ -803,7 +818,7 @@ default RequestBody processRequestBody(final AnnotationScannerContext context, && getConsumes(context) != null) { if (params.getFormBodyContent() != null) { if (requestBody == null) { - requestBody = new RequestBodyImpl(); + requestBody = new RequestBodyImpl().setRequiredDefault(Boolean.TRUE); } requestBody.setContent(params.getFormBodyContent()); } else { @@ -819,7 +834,7 @@ && getConsumes(context) != null) { if (isMultipartInput(requestBodyType)) { schema = new SchemaImpl(); - schema.setType(Schema.SchemaType.OBJECT); + schema.addType(Schema.SchemaType.OBJECT); } else { AnnotationInstance schemaAnnotation = context.annotations().getMethodParameterAnnotation(method, requestBodyType, @@ -829,14 +844,14 @@ && getConsumes(context) != null) { } if (requestBody == null) { - requestBody = new RequestBodyImpl(); + requestBody = new RequestBodyImpl().setRequiredDefault(Boolean.TRUE); } if (schema != null) { ModelUtil.setRequestBodySchema(requestBody, schema, getConsumesForRequestBody(context)); } - if (requestBody.getRequired() == null && TypeUtil.isOptional(requestBodyType)) { + if (!RequestBodyImpl.isRequiredSet(requestBody) && TypeUtil.isOptional(requestBodyType)) { requestBody.setRequired(Boolean.FALSE); } @@ -914,7 +929,7 @@ default void setRequestBodyConstraints(AnnotationScannerContext context, Request .filter(Objects::nonNull) .forEach(schema -> constraintScanner.get().applyConstraints(paramTarget, schema, null, (target, name) -> { - if (requestBody.getRequired() == null) { + if (!RequestBodyImpl.isRequiredSet(requestBody)) { requestBody.setRequired(Boolean.TRUE); } })); diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScannerContext.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScannerContext.java index 01a30f599..a486922ea 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScannerContext.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScannerContext.java @@ -218,12 +218,7 @@ public Annotations annotations() { } @SuppressWarnings("unchecked") - public IOContext getIoContext() { + public IOContext io() { // NOSONAR - ignore wildcards in return type return (IOContext) ioContext; } - - @SuppressWarnings("unchecked") - public OpenAPIDefinitionIO io() { // NOSONAR - ignore wildcards in return type - return (OpenAPIDefinitionIO) modelIO; - } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/util/TypeUtil.java b/core/src/main/java/io/smallrye/openapi/runtime/util/TypeUtil.java index 99407071f..e07b48377 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/util/TypeUtil.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/util/TypeUtil.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -37,6 +38,7 @@ import io.smallrye.openapi.api.constants.KotlinConstants; import io.smallrye.openapi.api.constants.MutinyConstants; import io.smallrye.openapi.api.models.ExternalDocumentationImpl; +import io.smallrye.openapi.api.models.media.SchemaImpl; import io.smallrye.openapi.runtime.io.schema.SchemaConstant; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; @@ -108,7 +110,7 @@ public class TypeUtil { public static final IndexView jdkIndex; private static final Set wrapperTypes = new HashSet<>(); - // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#dataTypeFormat + // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#dataTypeFormat static { TYPE_MAP.put(DOTNAME_OBJECT, ANY); @@ -414,13 +416,21 @@ public static boolean isTypeOverridden(AnnotationScannerContext context, Type cl public static void applyTypeAttributes(Type classType, Schema schema) { Map properties = getTypeAttributes(classType); - schema.setType((SchemaType) properties.get(SchemaConstant.PROP_TYPE)); + SchemaImpl.setType(schema, (SchemaType) properties.get(SchemaConstant.PROP_TYPE)); schema.setFormat((String) properties.get(SchemaConstant.PROP_FORMAT)); schema.setPattern((String) properties.get(SchemaConstant.PROP_PATTERN)); - schema.setExample(properties.get(SchemaConstant.PROP_EXAMPLE)); + schema.setExamples(wrapInList(properties.get(SchemaConstant.PROP_EXAMPLE))); schema.setExternalDocs((ExternalDocumentation) properties.get(SchemaConstant.PROP_EXTERNAL_DOCS)); } + private static List wrapInList(E item) { + if (item == null) { + return null; + } else { + return Collections.singletonList(item); + } + } + /** * Removes the known default schema attributes from the fieldSchema if they are also * present and have the same value in the typeSchema. This method reduces any duplicate @@ -432,6 +442,7 @@ public static void applyTypeAttributes(Type classType, Schema schema) { public static void clearMatchingDefaultAttributes(Schema fieldSchema, Schema typeSchema) { clearIfEqual(fieldSchema.getFormat(), typeSchema.getFormat(), fieldSchema::setFormat); clearIfEqual(fieldSchema.getPattern(), typeSchema.getPattern(), fieldSchema::setPattern); + clearIfEqual(fieldSchema.getExamples(), typeSchema.getExamples(), fieldSchema::setExamples); clearIfEqual(fieldSchema.getExample(), typeSchema.getExample(), fieldSchema::setExample); clearIfEqual(fieldSchema.getExternalDocs(), typeSchema.getExternalDocs(), fieldSchema::setExternalDocs); } diff --git a/core/src/test/java/io/smallrye/openapi/api/models/MapBasedModelmplTest.java b/core/src/test/java/io/smallrye/openapi/api/models/MapBasedModelmplTest.java new file mode 100644 index 000000000..c6dcc8d7c --- /dev/null +++ b/core/src/test/java/io/smallrye/openapi/api/models/MapBasedModelmplTest.java @@ -0,0 +1,64 @@ +package io.smallrye.openapi.api.models; + +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +public class MapBasedModelmplTest { + + public static class TestMapModel extends MapBasedModelImpl { + }; + + @Test + public void getWrongType() { + TestMapModel test = new TestMapModel(); + test.setProperty("test", "Hello"); + + assertEquals("Hello", test.getProperty("test", String.class)); + assertEquals("Hello", test.getProperty("test", Object.class)); + assertNull(test.getProperty("test", Integer.class)); + } + + @Test + public void addToNonList() { + TestMapModel test = new TestMapModel(); + test.setProperty("test", "Hello"); + test.addToListProperty("test", 4); + + assertEquals(asList(4), test.getProperty("test", Object.class)); + } + + @Test + public void removeFromNonList() { + TestMapModel test = new TestMapModel(); + test.setProperty("test", "Hello"); + test.removeFromListProperty("test", 4); + + assertEquals("Hello", test.getProperty("test", Object.class)); + } + + @Test + public void addToNonMap() { + TestMapModel test = new TestMapModel(); + test.setProperty("test", "Hello"); + test.addToMapProperty("test", "foo", 4); + + Map expected = new HashMap<>(); + expected.put("foo", 4); + assertEquals(expected, test.getProperty("test", Object.class)); + } + + @Test + public void removeFromNonMap() { + TestMapModel test = new TestMapModel(); + test.setProperty("test", "Hello"); + test.removeFromMapProperty("test", "foo"); + + assertEquals("Hello", test.getProperty("test", Object.class)); + } +} diff --git a/core/src/test/java/io/smallrye/openapi/api/util/UnusedSchemaFilterTest.java b/core/src/test/java/io/smallrye/openapi/api/util/UnusedSchemaFilterTest.java index 3d06dee9b..d12547ad4 100644 --- a/core/src/test/java/io/smallrye/openapi/api/util/UnusedSchemaFilterTest.java +++ b/core/src/test/java/io/smallrye/openapi/api/util/UnusedSchemaFilterTest.java @@ -40,7 +40,7 @@ void setUp() throws Exception { "http://example.com/schemas/Data?type=html"))))))))) .components(createComponents() .addSchema("Data", createSchema() - .type(SchemaType.STRING) + .addType(SchemaType.STRING) .description("The data returned by the API"))); } @@ -48,7 +48,7 @@ void setUp() throws Exception { void testUnusedSchemaPropertyRemoved() { openAPI.getComponents() .addSchema("RemovedSchema", createSchema() - .type(SchemaType.OBJECT) + .addType(SchemaType.OBJECT) .description("Schema to be removed, pass 1") .addProperty("prop1", createSchema() .ref("#/components/schemas/RemovedPropertySchema")) @@ -62,7 +62,7 @@ void testUnusedSchemaPropertyRemoved() { .addOneOf(createSchema() .ref("#/components/schemas/RemovedPropertySchema")))) .addSchema("RemovedPropertySchema", createSchema() - .type(SchemaType.STRING) + .addType(SchemaType.STRING) .description("Schema to be removed, pass 2")); assertEquals(3, openAPI.getComponents().getSchemas().size()); @@ -76,19 +76,19 @@ void testUnusedSchemaPropertyRemoved() { void testUnusedOneOfSchemasRemoved() { openAPI.getComponents() .addSchema("RemovedSchema", createSchema() - .type(SchemaType.OBJECT) + .addType(SchemaType.OBJECT) .description("Schema to be removed, pass 1") .addOneOf(createSchema() .ref("#/components/schemas/RemovedAllOfSchema1")) .addOneOf(createSchema() .ref("#/components/schemas/RemovedAllOfSchema2")) .addOneOf(createSchema() - .type(SchemaType.BOOLEAN))) + .addType(SchemaType.BOOLEAN))) .addSchema("RemovedAllOfSchema1", createSchema() - .type(SchemaType.INTEGER) + .addType(SchemaType.INTEGER) .description("Schema to be removed, pass 2")) .addSchema("RemovedAllOfSchema2", createSchema() - .type(SchemaType.STRING) + .addType(SchemaType.STRING) .description("Schema to be removed, pass 2")); assertEquals(4, openAPI.getComponents().getSchemas().size()); diff --git a/core/src/test/java/io/smallrye/openapi/runtime/io/ModelIOTest.java b/core/src/test/java/io/smallrye/openapi/runtime/io/ModelIOTest.java new file mode 100644 index 000000000..2c1986fce --- /dev/null +++ b/core/src/test/java/io/smallrye/openapi/runtime/io/ModelIOTest.java @@ -0,0 +1,37 @@ +package io.smallrye.openapi.runtime.io; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.AbstractMap.SimpleEntry; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collector; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +class ModelIOTest { + + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + void testToLinkedMapDuplicateKeyThrowsException() { + Stream> stream = Stream.of("k1", "k1").map(k -> new SimpleEntry(k, "")); + Collector, ?, Map> collector = ModelIO.toLinkedMap(); + assertThrows(IllegalStateException.class, () -> stream.collect(collector)); + } + + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + void testToLinkedMapParallelCombined() { + Stream> stream = IntStream + .range(0, 100).> mapToObj( + i -> new SimpleEntry(Integer.toString(i), i % 2 == 0 ? "" : null)); + Collector, ?, Map> collector = ModelIO.toLinkedMap(); + Map result = stream.parallel().collect(collector); + assertEquals(100, result.size()); + assertEquals(50, result.values().stream().filter(Objects::isNull).count()); + assertEquals(50, result.values().stream().filter(Objects::nonNull).count()); + } +} diff --git a/core/src/test/java/io/smallrye/openapi/runtime/io/OpenApiParserAndSerializerTest.java b/core/src/test/java/io/smallrye/openapi/runtime/io/OpenApiParserAndSerializerTest.java index 87ea30a13..31c499ab5 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/io/OpenApiParserAndSerializerTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/io/OpenApiParserAndSerializerTest.java @@ -45,6 +45,14 @@ private static void assertJsonEquals(String expected, String actual) throws JSON JSONAssert.assertEquals(expected, actual, true); } + private static void assertJsonEquals(String message, String expected, String actual) throws JSONException { + try { + JSONAssert.assertEquals(expected, actual, true); + } catch (AssertionError e) { + throw new AssertionError(message + "\n" + e.getMessage(), e); + } + } + /** * @param original * @param roundTrip @@ -77,21 +85,73 @@ private static String normalizeYaml(String yaml) { private static Path generateBigStaticFile() throws IOException { // let's build a big openapi file, start by its header - String bigFileContents = loadResource(OpenApiParserAndSerializerTest.class.getResource("openapi-fragment-header.yaml")); + String bigFileHeader = loadResource(OpenApiParserAndSerializerTest.class.getResource("openapi-fragment-header.yaml")); + StringBuilder bigFileContents = new StringBuilder(bigFileHeader); // body final String bodyChunk = loadResource(OpenApiParserAndSerializerTest.class.getResource("openapi-fragment-body.yaml")); for (int i = 0; i < REPEAT_BODY_CONTENTS_ITERATIONS; i++) { // n-chunk of body - bigFileContents += bodyChunk.replaceAll("@@ID@@", String.valueOf(i)); + bigFileContents.append(bodyChunk.replaceAll("@@ID@@", String.valueOf(i))); } // footer - bigFileContents += loadResource(OpenApiParserAndSerializerTest.class.getResource("openapi-fragment-footer.yaml")); + String bigFileFooter = loadResource(OpenApiParserAndSerializerTest.class.getResource("openapi-fragment-footer.yaml")); + bigFileContents.append(bigFileFooter); Path tempFile = Files.createTempFile("sroap-big-file-test-", "-generated.yaml"); - Files.write(tempFile, bigFileContents.getBytes(StandardCharsets.UTF_8)); + Files.write(tempFile, bigFileContents.toString().getBytes(StandardCharsets.UTF_8)); return tempFile; } + private static enum ConversionDirection { + TO_31_ONLY, + TO_30_ONLY, + BOTH_WAYS + } + + /** + * Tests parse+serialize+version conversion between two resources. + *

    + *

      + *
    • parse+serialize testResource31 and check the result matches the input + *
    • parse+serialize testResource30 and check the result matches the input + *
    • parse testResource31, set version to 3.0, serialize and check result matches testResource30 + *
    • parse testResource30, set version to 3.1, serialize and check result matches testResource31 + *
    + * + * @param resource31 resource in OpenAPI 3.1 format + * @param resource30 resource in OpenAPI 3.0 format + */ + @SuppressWarnings("deprecation") + private static void doMultiVersionTest(String resource31, String resource30, ConversionDirection direction) + throws IOException, JSONException { + URL testResource31 = OpenApiParserAndSerializerTest.class.getResource(resource31); + URL testResource30 = OpenApiParserAndSerializerTest.class.getResource(resource30); + + OpenAPI model31 = OpenApiParser.parse(testResource31); + OpenAPI model30 = OpenApiParser.parse(testResource30); + + String json31 = loadResource(testResource31); + String json30 = loadResource(testResource30); + + assertJsonEquals("Round-trip " + resource31, json31, OpenApiSerializer.serialize(model31, Format.JSON)); + + if (direction == ConversionDirection.BOTH_WAYS || direction == ConversionDirection.TO_30_ONLY) { + model31.setOpenapi("3.0.3"); + assertJsonEquals("Convert " + resource31 + " to " + resource30, json30, + OpenApiSerializer.serialize(model31, Format.JSON)); + + // Note, not testing round-trip of 3.0 model for TO_31_ONLY case + // when testing 3.0 -> 3.1 conversion, some data is lost on read, therefore the 3.0 model is not expected to round-trip + assertJsonEquals("Round-trip " + resource30, json30, OpenApiSerializer.serialize(model30, Format.JSON)); + } + + if (direction == ConversionDirection.BOTH_WAYS || direction == ConversionDirection.TO_31_ONLY) { + model30.setOpenapi("3.1.0"); + assertJsonEquals("Convert " + resource30 + " to " + resource31, json31, + OpenApiSerializer.serialize(model30, Format.JSON)); + } + } + /** * Performs a full round-trip parse+serialize test on a single resource. * @@ -454,7 +514,7 @@ void testPaths_Extensions() throws IOException, JSONException { */ @Test void testSchemas_Discriminator() throws IOException, JSONException { - doTest("schemas-discriminator.json", Format.JSON); + doMultiVersionTest("schemas-discriminator.json", "schemas-discriminator30.json", ConversionDirection.BOTH_WAYS); } /** @@ -462,7 +522,8 @@ void testSchemas_Discriminator() throws IOException, JSONException { */ @Test void testSchemas_AdditionalProperties() throws IOException, JSONException { - doTest("schemas-with-additionalProperties.json", Format.JSON); + doMultiVersionTest("schemas-with-additionalProperties.json", "schemas-with-additionalProperties30.json", + ConversionDirection.BOTH_WAYS); } /** @@ -470,7 +531,7 @@ void testSchemas_AdditionalProperties() throws IOException, JSONException { */ @Test void testSchemas_AllOf() throws IOException, JSONException { - doTest("schemas-with-allOf.json", Format.JSON); + doMultiVersionTest("schemas-with-allOf.json", "schemas-with-allOf30.json", ConversionDirection.BOTH_WAYS); } /** @@ -478,7 +539,7 @@ void testSchemas_AllOf() throws IOException, JSONException { */ @Test void testSchemas_Composition() throws IOException, JSONException { - doTest("schemas-with-composition.json", Format.JSON); + doMultiVersionTest("schemas-with-composition.json", "schemas-with-composition30.json", ConversionDirection.BOTH_WAYS); } /** @@ -486,7 +547,7 @@ void testSchemas_Composition() throws IOException, JSONException { */ @Test void testSchemas_Example() throws IOException, JSONException { - doTest("schemas-with-example.json", Format.JSON); + doMultiVersionTest("schemas-with-example.json", "schemas-with-example30.json", ConversionDirection.BOTH_WAYS); } /** @@ -494,7 +555,15 @@ void testSchemas_Example() throws IOException, JSONException { */ @Test void testSchemas_ExternalDocs() throws IOException, JSONException { - doTest("schemas-with-externalDocs.json", Format.JSON); + doMultiVersionTest("schemas-with-externalDocs.json", "schemas-with-externalDocs30.json", ConversionDirection.BOTH_WAYS); + } + + @Test + void testSchemas_MinMax() throws IOException, JSONException { + doMultiVersionTest("schemas-with-minmax.json", "schemas-with-minmax30.json", ConversionDirection.BOTH_WAYS); + + // One way test because it has both minimum and exclusiveMinimum set on the same schema, so data is lost when converting 3.1->3.0 + doMultiVersionTest("schemas-with-minmax-both.json", "schemas-with-minmax-both30.json", ConversionDirection.TO_30_ONLY); } /** @@ -502,7 +571,21 @@ void testSchemas_ExternalDocs() throws IOException, JSONException { */ @Test void testSchemas_MetaData() throws IOException, JSONException { - doTest("schemas-with-metaData.json", Format.JSON); + doMultiVersionTest("schemas-with-metaData.json", "schemas-with-metaData30.json", ConversionDirection.BOTH_WAYS); + } + + @Test + void testSchemas_NullableReference() throws IOException, JSONException { + doMultiVersionTest("schemas-with-nullable-reference.json", "schemas-with-nullable-reference30.json", + ConversionDirection.BOTH_WAYS); + } + + @Test + void testSchemas_NullableReferenceNonReversable() throws IOException, JSONException { + doMultiVersionTest("schemas-with-nullable-reference-non-reversable.json", + "schemas-with-nullable-reference-non-reversable30-1.json", ConversionDirection.TO_31_ONLY); + doMultiVersionTest("schemas-with-nullable-reference-non-reversable.json", + "schemas-with-nullable-reference-non-reversable30-2.json", ConversionDirection.BOTH_WAYS); } /** @@ -510,7 +593,7 @@ void testSchemas_MetaData() throws IOException, JSONException { */ @Test void testSchemas_XML() throws IOException, JSONException { - doTest("schemas-with-xml.json", Format.JSON); + doMultiVersionTest("schemas-with-xml.json", "schemas-with-xml30.json", ConversionDirection.BOTH_WAYS); } /** @@ -529,6 +612,19 @@ void testEverythingYaml() throws IOException, JSONException { doTest("_everything.yaml", Format.YAML); } + @Test + void testEverything30() throws IOException, JSONException { + // Tests non-30 fields in _everything are dropped + doMultiVersionTest("_everything.json", "_everything30.json", ConversionDirection.TO_30_ONLY); + // Tests conversion of features supported differently by 3.1 and 3.0 + doMultiVersionTest("_everything30_31.json", "_everything30.json", ConversionDirection.BOTH_WAYS); + } + + @Test + void testEverything30Yaml() throws IOException, JSONException { + doTest("_everything30.yaml", Format.YAML); + } + /** * Test method for {@link OpenApiParser#parse(java.net.URL)}. * diff --git a/core/src/test/java/io/smallrye/openapi/runtime/io/media/EncodingReaderTest.java b/core/src/test/java/io/smallrye/openapi/runtime/io/media/EncodingReaderTest.java index ab11cd370..64da869e1 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/io/media/EncodingReaderTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/io/media/EncodingReaderTest.java @@ -15,7 +15,6 @@ import io.smallrye.openapi.api.models.OpenAPIImpl; import io.smallrye.openapi.runtime.io.IOContext; -import io.smallrye.openapi.runtime.io.extensions.ExtensionIO; import io.smallrye.openapi.runtime.scanner.FilteredIndexView; import io.smallrye.openapi.runtime.scanner.IndexScannerTestBase; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; @@ -41,11 +40,7 @@ void testReadEncodingStyle(Class endpointClass, Encoding.Style expectedStyle) .asNestedArray()[0]; IOContext ioContext = IOContext.forScanning(context); - ExtensionIO extensionIO = new ExtensionIO<>(ioContext); - @SuppressWarnings({ "unchecked", "rawtypes" }) - ContentIO contentIO = new ContentIO(ioContext, extensionIO); - @SuppressWarnings({ "unchecked", "rawtypes" }) - EncodingIO encodingIO = new EncodingIO(ioContext, contentIO, extensionIO); + EncodingIO encodingIO = ioContext.encodingIO(); Encoding.Style style = encodingIO.readStyle(annotation); assertEquals(expectedStyle, style); } diff --git a/core/src/test/java/io/smallrye/openapi/runtime/io/schema/SchemaFactoryTest.java b/core/src/test/java/io/smallrye/openapi/runtime/io/schema/SchemaFactoryTest.java index 807863c44..bea554d6d 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/io/schema/SchemaFactoryTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/io/schema/SchemaFactoryTest.java @@ -69,7 +69,7 @@ void testEnumToSchemaTypeUsesValueWithAnnotation() { AnnotationScannerContext context = new AnnotationScannerContext(index, ClassLoaderUtil.getDefaultClassLoader(), emptyConfig()); Schema result = SchemaFactory.enumToSchema(context, Type.create(ExampleEnum1.class)); - assertEquals(Schema.SchemaType.INTEGER, result.getType()); + assertEquals(Arrays.asList(Schema.SchemaType.INTEGER), result.getType()); assertEquals("int32", result.getFormat()); assertEquals("An example enum with a value-driven schema type", result.getDescription()); } @@ -97,7 +97,7 @@ void testEnumToSchemaTypeUsesValueWithoutAnnotation() { AnnotationScannerContext context = new AnnotationScannerContext(index, ClassLoaderUtil.getDefaultClassLoader(), emptyConfig()); Schema result = SchemaFactory.enumToSchema(context, Type.create(ExampleEnum2.class)); - assertEquals(Schema.SchemaType.INTEGER, result.getType()); + assertEquals(Arrays.asList(Schema.SchemaType.INTEGER), result.getType()); assertEquals("int64", result.getFormat()); assertNull(result.getDescription()); } @@ -113,7 +113,7 @@ void testEnumToSchemaTypeWithEmptyEnum() { AnnotationScannerContext context = new AnnotationScannerContext(index, ClassLoaderUtil.getDefaultClassLoader(), emptyConfig()); Schema result = SchemaFactory.enumToSchema(context, Type.create(ExampleEnum3.class)); - assertEquals(Schema.SchemaType.STRING, result.getType()); + assertEquals(Arrays.asList(Schema.SchemaType.STRING), result.getType()); assertEquals(Arrays.asList("VAL1", "VAL2"), result.getEnumeration()); } diff --git a/core/src/test/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIOTest.java b/core/src/test/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIOTest.java new file mode 100644 index 000000000..3451dd3fc --- /dev/null +++ b/core/src/test/java/io/smallrye/openapi/runtime/io/security/SecuritySchemeIOTest.java @@ -0,0 +1,59 @@ +package io.smallrye.openapi.runtime.io.security; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType; +import org.eclipse.microprofile.openapi.annotations.security.OAuthFlow; +import org.eclipse.microprofile.openapi.annotations.security.OAuthFlows; +import org.eclipse.microprofile.openapi.annotations.security.OAuthScope; +import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassInfo; +import org.junit.jupiter.api.Test; + +import io.smallrye.openapi.api.models.OpenAPIImpl; +import io.smallrye.openapi.runtime.io.IOContext; +import io.smallrye.openapi.runtime.scanner.FilteredIndexView; +import io.smallrye.openapi.runtime.scanner.IndexScannerTestBase; +import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; + +class SecuritySchemeIOTest extends IndexScannerTestBase { + + @Test + void testReadFlow() { + FilteredIndexView index = new FilteredIndexView(IndexScannerTestBase.indexOf(Endpoint1.class), emptyConfig()); + + AnnotationScannerContext context = new AnnotationScannerContext(index, Thread.currentThread().getContextClassLoader(), + Collections.emptyList(), + emptyConfig(), new OpenAPIImpl()); + + ClassInfo clazz = index.getClassByName(Endpoint1.class); + AnnotationInstance annotation = clazz.annotation(SecurityScheme.class); + AnnotationInstance flowAnnotation = annotation + .value("flows").asNested() + .value("implicit").asNested(); + AnnotationInstance scopeAnnotation = flowAnnotation + .value("scopes").asNestedArray()[0]; + + IOContext ioContext = IOContext.forScanning(context); + + OAuthScopeIO scopeIO = ioContext.oauthScopeIO(); + String value = scopeIO.read(scopeAnnotation); + assertNull(value); + + OAuthFlowIO flowIO = ioContext.oauthFlowIO(); + org.eclipse.microprofile.openapi.models.security.OAuthFlow flow = flowIO.read(flowAnnotation); + Map expected = new HashMap<>(); + expected.put("foo", null); + assertEquals(expected, flow.getScopes()); + } + + @SecurityScheme(securitySchemeName = "OAuth2Authorization", type = SecuritySchemeType.OAUTH2, description = "authentication needed to delete a profile", flows = @OAuthFlows(implicit = @OAuthFlow(authorizationUrl = "https://example.com", scopes = @OAuthScope(name = "foo")))) + static class Endpoint1 { + } +} diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java index 54812bec6..5e7cc1f71 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java @@ -164,7 +164,8 @@ public static void verifyMethodAndParamRefsPresent(OpenAPI oai) { private static boolean isPathMatrixObject(Parameter parameter) { return parameter.getIn() == Parameter.In.PATH && parameter.getStyle() == Parameter.Style.MATRIX - && parameter.getSchema() != null && parameter.getSchema().getType() == Schema.SchemaType.OBJECT; + && parameter.getSchema() != null && parameter.getSchema().getType() != null + && parameter.getSchema().getType().equals(Collections.singletonList(Schema.SchemaType.OBJECT)); } public static String schemaToString(String entityName, Schema schema) { @@ -185,7 +186,13 @@ public static void assertJsonEquals(String expectedResource, OpenAPI actual) thr } public static void assertJsonEquals(URL expectedResourceUrl, OpenAPI actual) throws JSONException, IOException { - JSONAssert.assertEquals(loadResource(expectedResourceUrl), toJSON(actual), true); + String json = toJSON(actual); + try { + JSONAssert.assertEquals(loadResource(expectedResourceUrl), json, true); + } catch (AssertionError e) { + // If the JSON did not match, we want to add the serialized version to the end + throw new AssertionError(e.getMessage() + "\nFull result:\n" + json, e); + } } public static OpenAPI scan(Class... classes) { diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScannerTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScannerTest.java index 70d60c364..49df08f11 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScannerTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/OpenApiDataObjectScannerTest.java @@ -1,10 +1,12 @@ package io.smallrye.openapi.runtime.scanner; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import java.io.IOException; +import java.util.List; import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; import org.eclipse.microprofile.openapi.models.media.Schema; @@ -40,8 +42,9 @@ void testStreams(String type, Schema.SchemaType itemType, String itemFormat) thr AnnotationScannerContext context = new AnnotationScannerContext(index, Thread.currentThread().getContextClassLoader(), IndexScannerTestBase.emptyConfig()); Schema out = OpenApiDataObjectScanner.process(context, Type.create(DotName.createSimple(type), Kind.CLASS)); - assertEquals(Schema.SchemaType.ARRAY, out.getType()); - assertEquals(itemType, out.getItems().getType()); + assertEquals(singletonList(Schema.SchemaType.ARRAY), out.getType()); + List expectedTypes = itemType == null ? null : singletonList(itemType); + assertEquals(expectedTypes, out.getItems().getType()); assertEquals(itemFormat, out.getItems().getFormat()); } diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/SchemaPropertyNegativeTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/SchemaPropertyNegativeTest.java index 35f48d0bb..674f2c7dc 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/SchemaPropertyNegativeTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/SchemaPropertyNegativeTest.java @@ -129,7 +129,7 @@ void testClassSchemaPropertyRefWithOtherProps() throws Exception { assertJsonEquals("components.schemas.schemaproperty-refwithotherprops.json", RefWithOtherProps.class); } - // Name and ref used in document, other attributes ignored + // Ref is no longer treated as special, all properties are emitted @Schema(properties = @SchemaProperty(name = "test", type = SchemaType.STRING, ref = "foobar")) static class RefWithOtherProps { } diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java index f33dc6c08..cca4618e1 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java @@ -623,7 +623,7 @@ class Bean { }) OtherBean first; - @Schema(title = "Property with `allOf` referring to `OtherBean`") + @Schema(title = "Property with `type` and reference to `OtherBean`") OtherBean second; // Direct ref only diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/SubschemaApplicationTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/SubschemaApplicationTest.java new file mode 100644 index 000000000..74f82263a --- /dev/null +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/SubschemaApplicationTest.java @@ -0,0 +1,271 @@ +package io.smallrye.openapi.runtime.scanner; + +import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT; + +import java.util.List; +import java.util.Map; + +import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; +import org.eclipse.microprofile.openapi.annotations.media.DependentRequired; +import org.eclipse.microprofile.openapi.annotations.media.DependentSchema; +import org.eclipse.microprofile.openapi.annotations.media.PatternProperty; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.media.SchemaProperty; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.jboss.jandex.Index; +import org.junit.jupiter.api.Test; + +public class SubschemaApplicationTest extends IndexScannerTestBase { + + @Test + public void testSubschemaApplication() throws Exception { + Index index = indexOf(A.class, B.class, C.class, TestOneOf.class, TestAnyOf.class, TestAllOf.class, TestNot.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-application.json", result); + } + + @Test + public void testSubschemaApplicationProperty() throws Exception { + Index index = indexOf(A.class, B.class, C.class, TestOneOfProperty.class, TestAnyOfProperty.class, + TestAllOfProperty.class, TestNotProperty.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-application-property.json", result); + } + + @Test + public void testSubschemaIfThenElse() throws Exception { + Index index = indexOf(A.class, B.class, C.class, TestIfThenElse.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-ifthenelse.json", result); + } + + @Test + public void testSubschemaIfThenElseProperty() throws Exception { + Index index = indexOf(A.class, B.class, C.class, TestIfThenElseProperty.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-ifthenelse-property.json", result); + } + + @Test + public void testDependentSchemas() throws Exception { + Index index = indexOf(A.class, B.class, TestDepedentSchemas.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-dependent-schemas.json", result); + } + + @Test + public void testDependentSchemasProperty() throws Exception { + Index index = indexOf(A.class, B.class, TestDepedentSchemasProperty.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-dependent-schemas-property.json", result); + } + + @Test + public void testDependentRequired() throws Exception { + Index index = indexOf(TestDependentRequired.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-dependent-required.json", result); + } + + @Test + public void testDependentRequiredProperty() throws Exception { + Index index = indexOf(TestDependentRequiredProperty.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-dependent-required-property.json", result); + } + + @Test + public void testSubschemaCollections() throws Exception { + Index index = indexOf(A.class, JavaTypeString.class, TestCollections.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-collections.json", result); + } + + @Test + public void testSubschemaCollectionsProperty() throws Exception { + Index index = indexOf(A.class, JavaTypeString.class, TestCollectionsProperty.class); + OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); + + OpenAPI result = scanner.scan(); + + printToConsole(result); + assertJsonEquals("components.schemas.subschema-collections-property.json", result); + } + + @Schema(oneOf = { A.class, B.class, C.class }) + public static class TestOneOf { + } + + @Schema(anyOf = { A.class, B.class, C.class }) + public static class TestAnyOf { + } + + @Schema(allOf = { A.class, B.class, C.class }) + public static class TestAllOf { + } + + @Schema(not = A.class) + public static class TestNot { + } + + @Schema(properties = { + @SchemaProperty(name = "prop", oneOf = { A.class, B.class, C.class }) + }) + public static class TestOneOfProperty { + } + + @Schema(properties = { + @SchemaProperty(name = "prop", anyOf = { A.class, B.class, C.class }) + }) + public static class TestAnyOfProperty { + } + + @Schema(properties = { + @SchemaProperty(name = "prop", allOf = { A.class, B.class, C.class }) + }) + public static class TestAllOfProperty { + } + + @Schema(properties = @SchemaProperty(name = "prop", not = A.class)) + public static class TestNotProperty { + } + + @Schema(ifSchema = A.class, thenSchema = B.class, elseSchema = C.class) + public static class TestIfThenElse { + } + + @Schema(properties = @SchemaProperty(name = "prop", ifSchema = A.class, thenSchema = B.class, elseSchema = C.class)) + public static class TestIfThenElseProperty { + } + + @Schema(dependentSchemas = { + @DependentSchema(name = "field1", schema = A.class), + @DependentSchema(name = "field2", schema = B.class) + }) + public static class TestDepedentSchemas { + public String field1; + } + + @Schema(properties = @SchemaProperty(name = "prop", dependentSchemas = { + @DependentSchema(name = "field1", schema = A.class), + @DependentSchema(name = "field2", schema = B.class) + })) + public static class TestDepedentSchemasProperty { + } + + @Schema(dependentRequired = { + @DependentRequired(name = "field1", requires = { + "field2", + "field3" + }), + @DependentRequired(name = "field4", requires = "field5") + }) + public static class TestDependentRequired { + public String field1; + public String field2; + public String field3; + } + + @Schema(properties = @SchemaProperty(name = "prop", dependentRequired = { + @DependentRequired(name = "field1", requires = { + "field2", + "field3" + }), + @DependentRequired(name = "field4", requires = "field5") + })) + public static class TestDependentRequiredProperty { + } + + @Schema + public static class TestCollections { + @Schema(prefixItems = { JavaTypeString.class, JavaTypeString.class }) + public List mustStartWithTwoTypeNames; + + @Schema(contains = JavaTypeString.class) + public List mustContainATypeName; + + @Schema(contains = JavaTypeString.class, minContains = 3, maxContains = 5) + public List mustContain3To5TypeNames; + + @Schema(propertyNames = JavaTypeString.class) + public Map keysMustBeTypeNames; + + @Schema(patternProperties = { + @PatternProperty(regex = "^str", schema = String.class), + @PatternProperty(regex = "^int", schema = Integer.class) + }) + public Map keysNamedByType; + + @Schema(contentEncoding = "base64", contentMediaType = "application/json", contentSchema = A.class) + public String encodedJson; + } + + @Schema(properties = { + @SchemaProperty(name = "mustStartWithTwoTypeNames", type = SchemaType.ARRAY, implementation = String.class, prefixItems = { + JavaTypeString.class, + JavaTypeString.class + }), + @SchemaProperty(name = "mustContainATypeName", type = SchemaType.ARRAY, implementation = String.class, contains = JavaTypeString.class), + @SchemaProperty(name = "mustContain3To5TypeNames", type = SchemaType.ARRAY, implementation = String.class, contains = JavaTypeString.class, minContains = 3, maxContains = 5), + @SchemaProperty(name = "keysMustBeTypeNames", type = OBJECT, propertyNames = JavaTypeString.class, additionalProperties = String.class), + @SchemaProperty(name = "keysNamedByType", type = OBJECT, implementation = Object.class, patternProperties = { + @PatternProperty(regex = "^str", schema = String.class), + @PatternProperty(regex = "^int", schema = Integer.class) + }, additionalProperties = Object.class), + @SchemaProperty(name = "encodedJson", implementation = String.class, contentEncoding = "base64", contentMediaType = "application/json", contentSchema = A.class) + }) + public static class TestCollectionsProperty { + } + + @Schema(type = SchemaType.STRING, pattern = "^[A-Z][a-zA-Z0-9]*$") + public static class JavaTypeString { + } + + @Schema(type = OBJECT, description = "A") + public static class A { + } + + @Schema(description = "B") + public static class B { + } + + @Schema(description = "C") + public static class C { + } +} diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScannerTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScannerTest.java index 2776e70ee..aa8720b4a 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScannerTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/dataobject/BeanValidationScannerTest.java @@ -1,5 +1,6 @@ package io.smallrye.openapi.runtime.scanner.dataobject; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -117,7 +118,7 @@ void testJakartaNullSchemaIgnored() { @Test void testJavaxRefSchemaIgnored() { - schema.setType(SchemaType.OBJECT); + schema.setType(singletonList(SchemaType.OBJECT)); schema.setRef("#/components/schemas/Anything"); testTarget.applyConstraints(javaxTargetClass, proxySchema(schema, methodsInvoked), @@ -131,7 +132,7 @@ void testJavaxRefSchemaIgnored() { @Test void testJakartaRefSchemaIgnored() { - schema.setType(SchemaType.OBJECT); + schema.setType(singletonList(SchemaType.OBJECT)); schema.setRef("#/components/schemas/Anything"); testTarget.applyConstraints(jakartaTargetClass, proxySchema(schema, methodsInvoked), @@ -165,7 +166,7 @@ void testArrayListNotNullAndNotEmptyAndMaxItems(FieldInfo targetField) { testTarget.sizeArray(targetField, schema); testTarget.notEmptyArray(targetField, schema, propertyKey, requirementHandler(parentSchema)); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Integer.valueOf(1), schema.getMinItems()); assertEquals(Integer.valueOf(20), schema.getMaxItems()); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); @@ -191,7 +192,7 @@ void testArrayListNullableAndMinItemsAndMaxItems(FieldInfo targetField) { testTarget.sizeArray(targetField, schema); testTarget.notEmptyArray(targetField, schema, propertyKey, requirementHandler(parentSchema)); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Integer.valueOf(5), schema.getMinItems()); assertEquals(Integer.valueOf(20), schema.getMaxItems()); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); @@ -221,7 +222,7 @@ void testMapObjectNotNullAndNotEmptyAndMaxProperties(FieldInfo targetField) { testTarget.sizeObject(targetField, schema); testTarget.notEmptyObject(targetField, schema, propertyKey, requirementHandler(parentSchema)); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Integer.valueOf(1), schema.getMinProperties()); assertEquals(Integer.valueOf(20), schema.getMaxProperties()); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); @@ -249,7 +250,7 @@ void testMapObjectNullableAndMinPropertiesAndMaxProperties(FieldInfo targetField testTarget.sizeObject(targetField, schema); testTarget.notEmptyObject(targetField, schema, propertyKey, requirementHandler(parentSchema)); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Integer.valueOf(5), schema.getMinProperties()); assertEquals(Integer.valueOf(20), schema.getMaxProperties()); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); @@ -275,7 +276,7 @@ void testMapObjectNullableNoAdditionalProperties(FieldInfo targetField) { testTarget.sizeObject(targetField, schema); testTarget.notEmptyObject(targetField, schema, propertyKey, requirementHandlerFail()); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(null, schema.getMinProperties()); assertEquals(null, schema.getMaxProperties()); assertNull(parentSchema.getRequired()); @@ -347,8 +348,7 @@ void testJakartaDecimalMaxExclusiveDigits() { void testDecimalMaxExclusiveDigits(FieldInfo targetField) { testTarget.decimalMax(targetField, schema); testTarget.digits(targetField, schema); - assertEquals(new BigDecimal("201.0"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); + assertEquals(new BigDecimal("201.0"), schema.getExclusiveMaximum()); assertEquals("^\\d{1,3}([.]\\d)?$", schema.getPattern()); } @@ -426,8 +426,7 @@ void testDecimalMinExclusiveDigits(FieldInfo targetField) { testTarget.decimalMin(targetField, schema); testTarget.digits(targetField, schema); - assertEquals(new BigDecimal("9.00"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); + assertEquals(new BigDecimal("9.00"), schema.getExclusiveMinimum()); assertEquals("^\\d([.]\\d{1,2})?$", schema.getPattern()); } @@ -463,35 +462,8 @@ void testIntegerPositiveNotZeroMaxValue(FieldInfo targetField) { testTarget.max(targetField, schema); testTarget.positive(targetField, schema); - assertEquals(new BigDecimal("0"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); - assertEquals(new BigDecimal("1000"), schema.getMaximum()); - assertEquals(null, schema.getExclusiveMaximum()); - } - - @Test - void testJavaxIntegerPositiveNotZeroMaxValueExclusive() { - FieldInfo targetField = javaxTargetClass.field("integerPositiveNotZeroMaxValue"); - testIntegerPositiveNotZeroMaxValueExclusive(targetField); - } - - @Test - void testJakartaIntegerPositiveNotZeroMaxValueExclusive() { - FieldInfo targetField = jakartaTargetClass.field("integerPositiveNotZeroMaxValue"); - testIntegerPositiveNotZeroMaxValueExclusive(targetField); - } - - void testIntegerPositiveNotZeroMaxValueExclusive(FieldInfo targetField) { - schema.setExclusiveMaximum(Boolean.TRUE); - schema.setExclusiveMinimum(Boolean.TRUE); - - testTarget.max(targetField, schema); - testTarget.positive(targetField, schema); - - assertEquals(new BigDecimal("0"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); + assertEquals(new BigDecimal("0"), schema.getExclusiveMinimum()); assertEquals(new BigDecimal("1000"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); } @Test @@ -516,31 +488,6 @@ void testIntegerPositiveOrZeroMaxValue(FieldInfo targetField) { assertEquals(null, schema.getExclusiveMaximum()); } - @Test - void testJavaxIntegerPositiveOrZeroMaxValueExclusive() { - FieldInfo targetField = javaxTargetClass.field("integerPositiveOrZeroMaxValue"); - testIntegerPositiveOrZeroMaxValueExclusive(targetField); - } - - @Test - void testJakartaIntegerPositiveOrZeroMaxValueExclusive() { - FieldInfo targetField = jakartaTargetClass.field("integerPositiveOrZeroMaxValue"); - testIntegerPositiveOrZeroMaxValueExclusive(targetField); - } - - void testIntegerPositiveOrZeroMaxValueExclusive(FieldInfo targetField) { - schema.setExclusiveMaximum(Boolean.TRUE); - schema.setExclusiveMinimum(Boolean.TRUE); - - testTarget.max(targetField, schema); - testTarget.positiveOrZero(targetField, schema); - - assertEquals(new BigDecimal("-1"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); - assertEquals(new BigDecimal("999"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); - } - /**********************************************************************/ @Test @@ -559,35 +506,8 @@ void testIntegerNegativeNotZeroMinValue(FieldInfo targetField) { testTarget.min(targetField, schema); testTarget.negative(targetField, schema); - assertEquals(new BigDecimal("0"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); + assertEquals(new BigDecimal("0"), schema.getExclusiveMaximum()); assertEquals(new BigDecimal("-1000000"), schema.getMinimum()); - assertEquals(null, schema.getExclusiveMinimum()); - } - - @Test - void testJavaxIntegerNegativeNotZeroMinValueExclusive() { - FieldInfo targetField = javaxTargetClass.field("integerNegativeNotZeroMinValue"); - testIntegerNegativeNotZeroMinValueExclusive(targetField); - } - - @Test - void testJakartaIntegerNegativeNotZeroMinValueExclusive() { - FieldInfo targetField = jakartaTargetClass.field("integerNegativeNotZeroMinValue"); - testIntegerNegativeNotZeroMinValueExclusive(targetField); - } - - void testIntegerNegativeNotZeroMinValueExclusive(FieldInfo targetField) { - schema.setExclusiveMaximum(Boolean.TRUE); - schema.setExclusiveMinimum(Boolean.TRUE); - - testTarget.min(targetField, schema); - testTarget.negative(targetField, schema); - - assertEquals(new BigDecimal("0"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); - assertEquals(new BigDecimal("-1000000"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); } @Test @@ -612,31 +532,6 @@ void testIntegerNegativeOrZeroMinValue(FieldInfo targetField) { assertEquals(null, schema.getExclusiveMinimum()); } - @Test - void testJavaxIntegerNegativeOrZeroMinValueExclusive() { - FieldInfo targetField = javaxTargetClass.field("integerNegativeOrZeroMinValue"); - testIntegerNegativeOrZeroMinValueExclusive(targetField); - } - - @Test - void testJakartaIntegerNegativeOrZeroMinValueExclusive() { - FieldInfo targetField = jakartaTargetClass.field("integerNegativeOrZeroMinValue"); - testIntegerNegativeOrZeroMinValueExclusive(targetField); - } - - void testIntegerNegativeOrZeroMinValueExclusive(FieldInfo targetField) { - schema.setExclusiveMaximum(Boolean.TRUE); - schema.setExclusiveMinimum(Boolean.TRUE); - - testTarget.min(targetField, schema); - testTarget.negativeOrZero(targetField, schema); - - assertEquals(new BigDecimal("1"), schema.getMaximum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMaximum()); - assertEquals(new BigDecimal("-999"), schema.getMinimum()); - assertEquals(Boolean.TRUE, schema.getExclusiveMinimum()); - } - /**********************************************************************/ @Test @@ -659,7 +554,7 @@ void testStringNotBlankNotNull(FieldInfo targetField) { testTarget.notNull(targetField, propertyKey, requirementHandler(parentSchema)); assertEquals("\\S", schema.getPattern()); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); } @@ -683,7 +578,7 @@ void testStringNotBlankDigits(FieldInfo targetField) { testTarget.notBlank(targetField, schema, propertyKey, requirementHandler(parentSchema)); assertEquals("^\\d{1,8}([.]\\d{1,10})?$", schema.getPattern()); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); } @@ -708,7 +603,7 @@ void testStringNotEmptyMaxSize(FieldInfo targetField) { assertEquals(Integer.valueOf(1), schema.getMinLength()); assertEquals(Integer.valueOf(2000), schema.getMaxLength()); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); } @@ -733,7 +628,7 @@ void testStringNotEmptySizeRange(FieldInfo targetField) { assertEquals(Integer.valueOf(100), schema.getMinLength()); assertEquals(Integer.valueOf(2000), schema.getMaxLength()); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); } @@ -758,7 +653,7 @@ void testJacksonRequiredString(FieldInfo targetField, String propertyKey) { parentSchema.addRequired(name); }); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertEquals(Arrays.asList(propertyKey), parentSchema.getRequired()); } @@ -784,7 +679,7 @@ void testJacksonDefaultString(FieldInfo targetField) { parentSchema.addRequired(name); }); - assertNull(schema.getNullable()); + assertNull(SchemaImpl.getNullable(schema)); assertNull(parentSchema.getRequired()); } diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks1.json index ca45e8b75..95eeb431f 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks2.json index ca102132d..e6429fe8f 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/callbacks2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/merged.json index 3438198a7..0e36a2bf2 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_callbacks/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions1.json index ad21d58cf..9f3c6bb7c 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions1.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions2.json index c91cec3be..8f26538c0 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/extensions2.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "x-vendor-property-1": "FOO", "x-vendor-property-2": "bar", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/merged.json index 533c8370f..c6781f44d 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_extensions/merged.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_info/info1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_info/info1.json index 6b4e41640..d3ccee846 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_info/info1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_info/info1.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App", "termsOfService": "http://example.com/terms/", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_info/info2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_info/info2.json index a6b3f8eea..cfbedea63 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_info/info2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_info/info2.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App (Merged)", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_info/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_info/merged.json index 14d9f42e9..ca5406f9e 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_info/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_info/merged.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App (Merged)", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/merged.json index 8d2494d54..6e920fafc 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags1.json index e4ef246b0..caed3f82b 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags2.json index b72ff0483..1a6781535 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_opTags/opTags2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/merged.json index 4ced2d90d..ed76a4337 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault1.json index c1a40f2e0..a31c679e1 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault2.json index 6ebb37f61..96414d62e 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDefault/pathDefault2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/merged.json index 8360f0e81..868782f81 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path1.json index 953253e50..d513cff52 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path2.json index e4dbf14df..9399125b7 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathDocs/path2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/merged.json index cec43fc0a..4ff5bb844 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty1.json index 0a4ed9b46..14b4163b7 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty2.json index cec43fc0a..4ff5bb844 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_pathEmpty/pathEmpty2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_security/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_security/merged.json index ad6605418..b4c28fa2a 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_security/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_security/merged.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "security" : [ { "BASIC": [] diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_security/security1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_security/security1.json index 042d4c589..c573bfd06 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_security/security1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_security/security1.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "security" : [ { "BASIC": [] diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_security/security2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_security/security2.json index b53c0c73f..56819e132 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_security/security2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_security/security2.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "security" : [ { "JWT": [], diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/merged.json index 0fc5f2395..9a9a7f67c 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/merged.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "servers": [ { "url": "https://development.gigantic-server.com/v1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers1.json index d479db0b6..435fa5122 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers1.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "servers": [ { "url": "https://development.gigantic-server.com/v1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers2.json index 6f5e7413b..2bce11db6 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_servers/servers2.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "servers": [ { "url": "https://staging.gigantic-server.com/v1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/merged.json b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/merged.json index 92fb99f03..bdb548cef 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/merged.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/merged.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "tags" : [ { "name": "tag1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags1.json b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags1.json index 6266446a6..432194cda 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags1.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags1.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "tags" : [ { "name": "tag1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags2.json b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags2.json index b09428ac2..1649599ed 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags2.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/_tags/tags2.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "tags" : [ { "name": "tag1", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/filter-after.json b/core/src/test/resources/io/smallrye/openapi/api/util/filter-after.json index 9c4e8e110..35fd57715 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/filter-after.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/filter-after.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Updated API Title", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/api/util/filter-before.json b/core/src/test/resources/io/smallrye/openapi/api/util/filter-before.json index aca8cc49d..b6f7152ae 100644 --- a/core/src/test/resources/io/smallrye/openapi/api/util/filter-before.json +++ b/core/src/test/resources/io/smallrye/openapi/api/util/filter-before.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.json index d87f275d8..4b532c520 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", @@ -325,7 +325,39 @@ "components": { "schemas": { "Schema-1": {}, - "Schema-2": {} + "Schema-2": {}, + "mySchema": { + "type": ["object", "null"], + "description": "mySchema", + "properties": { + "number": { + "type": "integer", + "exclusiveMinimum": 0, + "exclusiveMaximum": 10 + }, + "string": { + "type": "string", + "maxLength": 5 + } + } + }, + "mySchema2": { + "description": "nullable reference", + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "type": "null" + } + ] + }, + "mySchema3": { + "const": 4 + }, + "mySchema4": { + "type": "null" + } }, "responses": { "Response-1": {}, diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.yaml index 04f9aa45b..0cc931d07 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.yaml +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything.yaml @@ -1,5 +1,5 @@ --- -openapi: 3.0.0 +openapi: 3.1.0 info: title: Sample Pet Store App description: This is a sample server for a pet store. @@ -233,6 +233,19 @@ paths: - 100 components: schemas: + mySchema: + type: + - object + - "null" + description: mySchema + properties: + number: + type: integer + exclusiveMinimum: 0 + exclusiveMaximum: 10 + string: + type: string + maxLength: 5 Schema-1: {} Schema-2: {} responses: diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.json new file mode 100644 index 000000000..2853f353b --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.json @@ -0,0 +1,425 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Sample Pet Store App", + "description": "This is a sample server for a pet store.", + "termsOfService": "http://example.com/terms/", + "contact": { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com", + "x-email": "x-email-value" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html", + "x-license": "x-license-value" + }, + "version": "1.0.1", + "x-version": "x-version-value" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://swagger.io", + "x-externalDocs": "x-externalDocs-value" + }, + "servers": [ + { + "url": "urn:server1", + "description": "Server 1 description.", + "variables": { + "Variable1": { + "enum": [ "one", "two", "three" ], + "default": "one", + "description": "Description of variable 1", + "x-description": "x-description-value" + }, + "Variable2": { + "enum": [ "dog", "cat", "pig" ], + "default": "dog", + "description": "Description of variable 2" + } + }, + "x-variables-int" : 100, + "x-variables-string": "string-value", + "x-variables-array": [ 1, 2, 3, 4, 5 ], + "x-variables-object": { + "prop1": "value1", + "prop2": "value2" + } + }, + { + "url": "urn:server2", + "description": "Server 2 description." + } + ], + "security": [ + { + "api_key": [] + }, + { + "basic_auth": [] + }, + { + "oauth2_auth": [ "write:foo", "read:foo" ] + } + ], + "tags": [ + { + "name": "tag-1", + "description": "Tag 1 description.", + "x-description": "x-description-value", + "x-description-2": "foo-bar" + }, + { + "name": "tag-2", + "description": "Tag 2 description.", + "externalDocs": { + "url": "https://example.com", + "description": "Find more info here" + } + } + ], + "paths": { + "/foo": { + "$ref": "#/paths/self", + "summary": "A summary", + "description": "Some description here.", + "get": { + "tags": [ "tag-1", "tag-2" ], + "summary": "Operation summary", + "description": "Operation description here.", + "externalDocs": { + "url": "https://example.com/#get", + "description": "Find more info on GET here" + }, + "operationId": "getAllFoos", + "parameters": [ + { + "name": "Param1", + "in": "query", + "description": "Param description here.", + "required": true, + "schema": { + "$ref": "#/components/schemas/MySchema" + }, + "allowEmptyValue": true, + "deprecated": false, + "style": "simple", + "explode": false, + "allowReserved": true, + "example": "yarr!", + "examples": { + "Example-1": { + "summary": "Summary of Example", + "description": "Description of example 1!", + "value": "foo", + "externalValue": "foo-bar" + }, + "Example-2" : { + "$ref": "#/components/examples/Example-2" + }, + "Example-3": { + "value": { + "name": "foo", + "id": 12 + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MySchema27" + }, + "example": { + "p1": "v1", + "p2": true, + "p3": 17, + "p4": [ "a", "b", "c" ] + }, + "encoding": { + "property1": { + "contentType": "application/xml", + "headers": { + "Header-1": { + "description": "Description of the header here.", + "required": true, + "deprecated": true, + "allowEmptyValue": true, + "style": "simple", + "explode": false, + "schema": { + "$ref": "#/components/schemas/SomeOtherSchema" + }, + "example": { + "foo": "baz" + }, + "examples": { + "Header-1-Example-1": {}, + "Header-1-Example-2": {} + }, + "content": {} + }, + "Header-2": { + "$ref": "#/components/headers/FooHeader" + } + }, + "style": "deepObject", + "explode": true, + "allowReserved": true, + "x-encoding-1": "1", + "x-encoding-2": 2 + }, + "property1": { + "contentType": "application/json", + "style": "pipeDelimited", + "explode": false, + "allowReserved": false + } + }, + "x-mediaType-1": "x-mediaType-1-value", + "x-mediaType-2": "x-mediaType-2-value" + } + } + }, + { + "$ref": "#/components/parameters/Param2" + } + ], + "requestBody": { + "description": "Description of the request body.", + "content": { + "application/json": {}, + "text/plain": {}, + "text/xml": {} + }, + "required": true, + "x-request-body-1": "value1", + "x-request-body-2": [ "foo", "bar", "baz" ] + }, + "responses": { + "default": { + "$ref": "#/components/responses/DefaultResponse" + }, + "200": { + "description": "Successful response.", + "headers": { + "Header-1": { + "description": "Description of the header here.", + "required": true, + "deprecated": true, + "allowEmptyValue": true, + "style": "simple", + "explode": false, + "schema": { + "$ref": "#/components/schemas/SomeOtherSchema" + }, + "example": { + "foo": "baz" + }, + "examples": { + "Header-1-Example-1": {}, + "Header-1-Example-2": {} + }, + "content": {}, + "x-header-1": "x-header-1-value", + "x-header-2": 179 + }, + "Header-2": { + "$ref": "#/components/headers/BarHeader" + } + }, + "content": { + "application/json": {}, + "text/plain": {} + }, + "links": { + "Link-1": { + "operationRef": "OPERATION-REF", + "operationId": "OP-ID", + "parameters": { + }, + "requestBody": { + "$ref": "#/components/requestBodies/FooRequestBody" + }, + "description": "Description of link 1.", + "server": { + "url": "urn:server-1" + }, + "x-link-1": "x-link-1-value", + "x-link-2": true + }, + "Link-2": { + "$ref": "#/components/links/LinkTwo" + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "callbacks": { + "Callback-1": { + "$ref": "#/components/callbacks/CallbackOne" + }, + "Callback-2": { + "PathItem-1": { + "$ref": "#/paths/fooItem" + }, + "x-callback-1": "x-callback-1-value", + "x-callback-2": 17.0 + } + }, + "deprecated": true, + "security": [ + { + "api_key": [] + }, + { + "basic_auth": [] + } + ], + "servers": [ + { + "url": "urn:server1" + }, + { + "url": "urn:server2" + } + ], + "x-operation-1": true, + "x-operation-2": { + "hello": "world", + "foo": 100, + "array": [ 1, 2, 3, 4, 5 ] + } + }, + "put": { + "operationId": "putAllFoos" + }, + "post": { + "operationId": "postAllFoos" + }, + "delete": { + "operationId": "deleteAllFoos" + }, + "options": { + "operationId": "optionsAllFoos" + }, + "head": { + "operationId": "headAllFoos" + }, + "patch": { + "operationId": "patchAllFoos" + }, + "trace": { + "operationId": "traceAllFoos" + } + }, + "/foo/{fooId}": { + "$ref": "#/paths/OtherPathItem" + }, + "x-paths-extension-1": "paths extension value", + "x-paths-extension-2": [ "array", "of", "values", true, 100 ] + }, + "components": { + "schemas": { + "Schema-1": {}, + "Schema-2": {}, + "mySchema": { + "type": "object", + "nullable": true, + "description": "mySchema", + "properties": { + "number": { + "type": "integer", + "minimum": 0, + "exclusiveMinimum": true, + "maximum": 10, + "exclusiveMaximum": true + }, + "string": { + "type": "string", + "maxLength": 5 + } + } + }, + "mySchema2": { + "description": "nullable reference", + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + } + ] + }, + "mySchema3": { + "enum": [4] + }, + "mySchema4": { + "enum": [null] + } + }, + "responses": { + "Response-1": {}, + "Response-2": {} + }, + "parameters": { + "Parameter-1": {}, + "Parameter-2": {} + }, + "examples": { + "Example-1": {}, + "Example-2": {} + }, + "requestBodies": { + "Request-Body-1": {}, + "Request-Body-2": {} + }, + "headers": { + "Header-1": {}, + "Header-2": {} + }, + "securitySchemes": { + "basic_auth": { + "type": "http", + "description": "Basic HTTP auth.", + "name": "Basic Auth", + "in": "header", + "scheme": "http", + "bearerFormat": "bearer-format-value", + "flows": { + "implicit": { + "authorizationUrl": "urn:auth-url", + "tokenUrl": "urn:token-url", + "refreshUrl": "urn:refresh-url", + "scopes": { + "read:foo": "read access to foos", + "write:foo": "write access to foos", + "admin:foo": "admin access" + }, + "x-implicit-ext-1": "some-value", + "x-implicit-ext-2": 190247109274091274019274120947 + }, + "password": {}, + "clientCredentials": {}, + "authorizationCode": {}, + "x-flows-ext-1": "flows-ext-value", + "x-flows-ext-2": false + }, + "openIdConnectUrl": "urn:open-id-connect/url", + "x-scheme-ext-1": "scheme-ext-value", + "x-scheme-ext-1": -1023873 + }, + "oauth": { + "type": "oauth2", + "in": "query", + "name": "OAuth Auth" + } + }, + "links": {}, + "callbacks": {} + }, + "x-root-extension-1": "hello world", + "x-root-extension-2": [ true, false ] +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.yaml new file mode 100644 index 000000000..5370c3afa --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30.yaml @@ -0,0 +1,302 @@ +--- +openapi: 3.0.3 +info: + title: Sample Pet Store App + description: This is a sample server for a pet store. + termsOfService: http://example.com/terms/ + contact: + name: API Support + url: http://www.example.com/support + email: support@example.com + x-email: x-email-value + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + x-license: x-license-value + version: 1.0.1 + x-version: x-version-value +externalDocs: + description: Find more info here + url: https://swagger.io + x-externalDocs: x-externalDocs-value +servers: +- url: urn:server1 + description: Server 1 description. + variables: + Variable1: + default: one + description: Description of variable 1 + enum: + - one + - two + - three + x-description: x-description-value + Variable2: + default: dog + description: Description of variable 2 + enum: + - dog + - cat + - pig + x-variables-int: 100 + x-variables-string: string-value + x-variables-array: + - 1 + - 2 + - 3 + - 4 + - 5 + x-variables-object: + prop1: value1 + prop2: value2 +- url: urn:server2 + description: Server 2 description. +security: +- api_key: [] +- basic_auth: [] +- oauth2_auth: + - write:foo + - read:foo +tags: +- name: tag-1 + description: Tag 1 description. + x-description: x-description-value + x-description-2: foo-bar +- name: tag-2 + description: Tag 2 description. + externalDocs: + description: Find more info here + url: https://example.com +paths: + /foo: + $ref: "#/paths/self" + summary: A summary + description: Some description here. + get: + tags: + - tag-1 + - tag-2 + summary: Operation summary + description: Operation description here. + externalDocs: + description: Find more info on GET here + url: https://example.com/#get + operationId: getAllFoos + parameters: + - name: Param1 + in: query + description: Param description here. + required: true + schema: + $ref: "#/components/schemas/MySchema" + allowEmptyValue: true + deprecated: false + style: simple + explode: false + allowReserved: true + example: yarr! + examples: + Example-1: + summary: Summary of Example + description: Description of example 1! + value: foo + externalValue: foo-bar + Example-2: + $ref: "#/components/examples/Example-2" + Example-3: + value: + name: foo + id: 12 + content: + application/json: + schema: + $ref: "#/components/schemas/MySchema27" + example: + p1: v1 + p2: true + p3: 17 + p4: + - a + - b + - c + encoding: + property1: + contentType: application/json + style: pipeDelimited + explode: false + allowReserved: false + x-mediaType-1: x-mediaType-1-value + x-mediaType-2: x-mediaType-2-value + - $ref: "#/components/parameters/Param2" + requestBody: + description: Description of the request body. + content: + application/json: {} + text/plain: {} + text/xml: {} + required: true + x-request-body-1: value1 + x-request-body-2: + - foo + - bar + - baz + responses: + default: + $ref: "#/components/responses/DefaultResponse" + "200": + description: Successful response. + headers: + Header-1: + description: Description of the header here. + required: true + deprecated: true + allowEmptyValue: true + style: simple + explode: false + schema: + $ref: "#/components/schemas/SomeOtherSchema" + example: + foo: baz + examples: + Header-1-Example-1: {} + Header-1-Example-2: {} + content: {} + x-header-1: x-header-1-value + x-header-2: 179 + Header-2: + $ref: "#/components/headers/BarHeader" + content: + application/json: {} + text/plain: {} + links: + Link-1: + operationRef: OPERATION-REF + operationId: OP-ID + parameters: {} + requestBody: {} + description: Description of link 1. + server: + url: urn:server-1 + x-link-1: x-link-1-value + x-link-2: true + Link-2: + $ref: "#/components/links/LinkTwo" + "404": + $ref: "#/components/responses/NotFound" + callbacks: + Callback-1: + $ref: "#/components/callbacks/CallbackOne" + Callback-2: + PathItem-1: + $ref: "#/paths/fooItem" + x-callback-1: x-callback-1-value + x-callback-2: 17 + deprecated: true + security: + - api_key: [] + - basic_auth: [] + servers: + - url: urn:server1 + - url: urn:server2 + x-operation-1: true + x-operation-2: + hello: world + foo: 100 + array: + - 1 + - 2 + - 3 + - 4 + - 5 + put: + operationId: putAllFoos + post: + operationId: postAllFoos + delete: + operationId: deleteAllFoos + options: + operationId: optionsAllFoos + head: + operationId: headAllFoos + patch: + operationId: patchAllFoos + trace: + operationId: traceAllFoos + /foo/{fooId}: + $ref: "#/paths/OtherPathItem" + x-paths-extension-1: paths extension value + x-paths-extension-2: + - array + - of + - values + - true + - 100 +components: + schemas: + mySchema: + description: mySchema + type: object + properties: + number: + maximum: 10 + exclusiveMaximum: true + minimum: 0 + exclusiveMinimum: true + type: integer + string: + maxLength: 5 + type: string + nullable: true + Schema-1: {} + Schema-2: {} + responses: + Response-1: {} + Response-2: {} + parameters: + Parameter-1: {} + Parameter-2: {} + examples: + Example-1: {} + Example-2: {} + requestBodies: + Request-Body-1: {} + Request-Body-2: {} + headers: + Header-1: {} + Header-2: {} + securitySchemes: + basic_auth: + type: http + description: Basic HTTP auth. + name: Basic Auth + in: header + scheme: http + bearerFormat: bearer-format-value + flows: + implicit: + authorizationUrl: urn:auth-url + tokenUrl: urn:token-url + refreshUrl: urn:refresh-url + scopes: + read:foo: read access to foos + write:foo: write access to foos + admin:foo: admin access + x-implicit-ext-1: some-value + x-implicit-ext-2: 1.902471092740913E29 + password: {} + clientCredentials: {} + authorizationCode: {} + x-flows-ext-1: flows-ext-value + x-flows-ext-2: false + openIdConnectUrl: urn:open-id-connect/url + x-scheme-ext-1: -1023873 + oauth: + type: oauth2 + name: OAuth Auth + in: query + links: {} + callbacks: {} +x-root-extension-1: hello world +x-root-extension-2: +- true +- false diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30_31.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30_31.json new file mode 100644 index 000000000..4b532c520 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/_everything30_31.json @@ -0,0 +1,424 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Sample Pet Store App", + "description": "This is a sample server for a pet store.", + "termsOfService": "http://example.com/terms/", + "contact": { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com", + "x-email": "x-email-value" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html", + "x-license": "x-license-value" + }, + "version": "1.0.1", + "x-version": "x-version-value" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://swagger.io", + "x-externalDocs": "x-externalDocs-value" + }, + "servers": [ + { + "url": "urn:server1", + "description": "Server 1 description.", + "variables": { + "Variable1": { + "enum": [ "one", "two", "three" ], + "default": "one", + "description": "Description of variable 1", + "x-description": "x-description-value" + }, + "Variable2": { + "enum": [ "dog", "cat", "pig" ], + "default": "dog", + "description": "Description of variable 2" + } + }, + "x-variables-int" : 100, + "x-variables-string": "string-value", + "x-variables-array": [ 1, 2, 3, 4, 5 ], + "x-variables-object": { + "prop1": "value1", + "prop2": "value2" + } + }, + { + "url": "urn:server2", + "description": "Server 2 description." + } + ], + "security": [ + { + "api_key": [] + }, + { + "basic_auth": [] + }, + { + "oauth2_auth": [ "write:foo", "read:foo" ] + } + ], + "tags": [ + { + "name": "tag-1", + "description": "Tag 1 description.", + "x-description": "x-description-value", + "x-description-2": "foo-bar" + }, + { + "name": "tag-2", + "description": "Tag 2 description.", + "externalDocs": { + "url": "https://example.com", + "description": "Find more info here" + } + } + ], + "paths": { + "/foo": { + "$ref": "#/paths/self", + "summary": "A summary", + "description": "Some description here.", + "get": { + "tags": [ "tag-1", "tag-2" ], + "summary": "Operation summary", + "description": "Operation description here.", + "externalDocs": { + "url": "https://example.com/#get", + "description": "Find more info on GET here" + }, + "operationId": "getAllFoos", + "parameters": [ + { + "name": "Param1", + "in": "query", + "description": "Param description here.", + "required": true, + "schema": { + "$ref": "#/components/schemas/MySchema" + }, + "allowEmptyValue": true, + "deprecated": false, + "style": "simple", + "explode": false, + "allowReserved": true, + "example": "yarr!", + "examples": { + "Example-1": { + "summary": "Summary of Example", + "description": "Description of example 1!", + "value": "foo", + "externalValue": "foo-bar" + }, + "Example-2" : { + "$ref": "#/components/examples/Example-2" + }, + "Example-3": { + "value": { + "name": "foo", + "id": 12 + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MySchema27" + }, + "example": { + "p1": "v1", + "p2": true, + "p3": 17, + "p4": [ "a", "b", "c" ] + }, + "encoding": { + "property1": { + "contentType": "application/xml", + "headers": { + "Header-1": { + "description": "Description of the header here.", + "required": true, + "deprecated": true, + "allowEmptyValue": true, + "style": "simple", + "explode": false, + "schema": { + "$ref": "#/components/schemas/SomeOtherSchema" + }, + "example": { + "foo": "baz" + }, + "examples": { + "Header-1-Example-1": {}, + "Header-1-Example-2": {} + }, + "content": {} + }, + "Header-2": { + "$ref": "#/components/headers/FooHeader" + } + }, + "style": "deepObject", + "explode": true, + "allowReserved": true, + "x-encoding-1": "1", + "x-encoding-2": 2 + }, + "property1": { + "contentType": "application/json", + "style": "pipeDelimited", + "explode": false, + "allowReserved": false + } + }, + "x-mediaType-1": "x-mediaType-1-value", + "x-mediaType-2": "x-mediaType-2-value" + } + } + }, + { + "$ref": "#/components/parameters/Param2" + } + ], + "requestBody": { + "description": "Description of the request body.", + "content": { + "application/json": {}, + "text/plain": {}, + "text/xml": {} + }, + "required": true, + "x-request-body-1": "value1", + "x-request-body-2": [ "foo", "bar", "baz" ] + }, + "responses": { + "default": { + "$ref": "#/components/responses/DefaultResponse" + }, + "200": { + "description": "Successful response.", + "headers": { + "Header-1": { + "description": "Description of the header here.", + "required": true, + "deprecated": true, + "allowEmptyValue": true, + "style": "simple", + "explode": false, + "schema": { + "$ref": "#/components/schemas/SomeOtherSchema" + }, + "example": { + "foo": "baz" + }, + "examples": { + "Header-1-Example-1": {}, + "Header-1-Example-2": {} + }, + "content": {}, + "x-header-1": "x-header-1-value", + "x-header-2": 179 + }, + "Header-2": { + "$ref": "#/components/headers/BarHeader" + } + }, + "content": { + "application/json": {}, + "text/plain": {} + }, + "links": { + "Link-1": { + "operationRef": "OPERATION-REF", + "operationId": "OP-ID", + "parameters": { + }, + "requestBody": { + "$ref": "#/components/requestBodies/FooRequestBody" + }, + "description": "Description of link 1.", + "server": { + "url": "urn:server-1" + }, + "x-link-1": "x-link-1-value", + "x-link-2": true + }, + "Link-2": { + "$ref": "#/components/links/LinkTwo" + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "callbacks": { + "Callback-1": { + "$ref": "#/components/callbacks/CallbackOne" + }, + "Callback-2": { + "PathItem-1": { + "$ref": "#/paths/fooItem" + }, + "x-callback-1": "x-callback-1-value", + "x-callback-2": 17.0 + } + }, + "deprecated": true, + "security": [ + { + "api_key": [] + }, + { + "basic_auth": [] + } + ], + "servers": [ + { + "url": "urn:server1" + }, + { + "url": "urn:server2" + } + ], + "x-operation-1": true, + "x-operation-2": { + "hello": "world", + "foo": 100, + "array": [ 1, 2, 3, 4, 5 ] + } + }, + "put": { + "operationId": "putAllFoos" + }, + "post": { + "operationId": "postAllFoos" + }, + "delete": { + "operationId": "deleteAllFoos" + }, + "options": { + "operationId": "optionsAllFoos" + }, + "head": { + "operationId": "headAllFoos" + }, + "patch": { + "operationId": "patchAllFoos" + }, + "trace": { + "operationId": "traceAllFoos" + } + }, + "/foo/{fooId}": { + "$ref": "#/paths/OtherPathItem" + }, + "x-paths-extension-1": "paths extension value", + "x-paths-extension-2": [ "array", "of", "values", true, 100 ] + }, + "components": { + "schemas": { + "Schema-1": {}, + "Schema-2": {}, + "mySchema": { + "type": ["object", "null"], + "description": "mySchema", + "properties": { + "number": { + "type": "integer", + "exclusiveMinimum": 0, + "exclusiveMaximum": 10 + }, + "string": { + "type": "string", + "maxLength": 5 + } + } + }, + "mySchema2": { + "description": "nullable reference", + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "type": "null" + } + ] + }, + "mySchema3": { + "const": 4 + }, + "mySchema4": { + "type": "null" + } + }, + "responses": { + "Response-1": {}, + "Response-2": {} + }, + "parameters": { + "Parameter-1": {}, + "Parameter-2": {} + }, + "examples": { + "Example-1": {}, + "Example-2": {} + }, + "requestBodies": { + "Request-Body-1": {}, + "Request-Body-2": {} + }, + "headers": { + "Header-1": {}, + "Header-2": {} + }, + "securitySchemes": { + "basic_auth": { + "type": "http", + "description": "Basic HTTP auth.", + "name": "Basic Auth", + "in": "header", + "scheme": "http", + "bearerFormat": "bearer-format-value", + "flows": { + "implicit": { + "authorizationUrl": "urn:auth-url", + "tokenUrl": "urn:token-url", + "refreshUrl": "urn:refresh-url", + "scopes": { + "read:foo": "read access to foos", + "write:foo": "write access to foos", + "admin:foo": "admin access" + }, + "x-implicit-ext-1": "some-value", + "x-implicit-ext-2": 190247109274091274019274120947 + }, + "password": {}, + "clientCredentials": {}, + "authorizationCode": {}, + "x-flows-ext-1": "flows-ext-value", + "x-flows-ext-2": false + }, + "openIdConnectUrl": "urn:open-id-connect/url", + "x-scheme-ext-1": "scheme-ext-value", + "x-scheme-ext-1": -1023873 + }, + "oauth": { + "type": "oauth2", + "in": "query", + "name": "OAuth Auth" + } + }, + "links": {}, + "callbacks": {} + }, + "x-root-extension-1": "hello world", + "x-root-extension-2": [ true, false ] +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-callbacks.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-callbacks.json index a84a7068b..e40813757 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-callbacks.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-callbacks.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "callbacks": { "Callback1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-empty.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-empty.json index 8644149c2..81f5f07fb 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-empty.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-empty.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { } } \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-examples.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-examples.json index 1dc1c11d8..8aac67b79 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-examples.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-examples.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "examples": { "Example1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-headers.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-headers.json index 660f96bb5..d10f8c333 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-headers.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-headers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "headers": { "Header1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-links.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-links.json index 751d0000e..2d4c051fa 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-links.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-links.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "links": { "Link1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-parameters.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-parameters.json index 677031ac5..d16f86f41 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-parameters.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-parameters.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "parameters": { "Param1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-requestBodies.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-requestBodies.json index 446ee4dc9..0351c4c8e 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-requestBodies.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-requestBodies.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "requestBodies": { "Body1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-responses.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-responses.json index 89a1e6549..976535208 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-responses.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-responses.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "responses": { "PetResponse": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-schemas.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-schemas.json index 4a46eaf58..71fe15e5d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-schemas.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-schemas.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "MySchema1" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-securitySchemes.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-securitySchemes.json index cc54b3d85..24b3a8dbf 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/components-securitySchemes.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/components-securitySchemes.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "securitySchemes": { "BASIC": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/extensions.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/extensions.json index 468f34ce9..419d5de9f 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/extensions.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/extensions.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/externalDocs.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/externalDocs.json index 1733a5355..5275a2e76 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/externalDocs.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/externalDocs.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "externalDocs" : { "description": "Find more info here", "url": "https://swagger.io" diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/info.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/info.json index 2fce0cdc6..9896df6c2 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/info.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/info.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "info" : { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/info.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/info.yaml index c3a9543c2..ee6d1888f 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/info.yaml +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/info.yaml @@ -1,5 +1,5 @@ --- -openapi: 3.0.0 +openapi: 3.1.0 info: title: Sample Pet Store App description: This is a sample server for a pet store. diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/openapi-fragment-header.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/openapi-fragment-header.yaml index a64d58d76..c7eae9ea6 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/openapi-fragment-header.yaml +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/openapi-fragment-header.yaml @@ -1,5 +1,5 @@ --- -openapi: 3.0.0 +openapi: 3.1.0 info: title: Proxy App version: "1.0" diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-all-operations.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-all-operations.json index b05a4e85d..32aaaf68d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-all-operations.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-all-operations.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-empty.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-empty.json index 613489b66..1a25b46d0 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-empty.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-empty.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths" : { } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-callbacks.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-callbacks.json index 63c5185dd..e76e9075d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-callbacks.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-callbacks.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-parameters.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-parameters.json index 477737d71..c18e0d39e 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-parameters.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-parameters.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-content.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-content.json index e2f4895d9..dbb26a66f 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-content.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-content.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-example.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-example.json index 5b4ad5229..de456dd75 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-example.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody-example.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody.json index 930f61a63..ab32782fa 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-requestBody.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-content.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-content.json index 28fc645d2..1acb4e1f8 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-content.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-content.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-headers.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-headers.json index fce77a1d1..bfcb7c14d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-headers.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-headers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-links.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-links.json index c3cd652e5..34cf900c7 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-links.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-response-links.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-responses.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-responses.json index 4ced2d90d..ed76a4337 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-responses.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-responses.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-security.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-security.json index d924b0849..77e8de33e 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-security.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-security.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-servers.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-servers.json index 931b65bbe..f308a4682 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-servers.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get-servers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get.json index e4ef246b0..caed3f82b 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-get.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-parameters.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-parameters.json index e01b5619c..e07a4bba9 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-parameters.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-parameters.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "parameters": [ diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-ref.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-ref.json index ad10453db..d2604e2c9 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-ref.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-ref.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/pets": { "$ref": "#/paths/foo" diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-servers.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-servers.json index 28c8d6129..a0631315d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-servers.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-servers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "servers": [ diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-with-extensions.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-with-extensions.json index 18e52aac1..06edbaed7 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-with-extensions.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/paths-with-extensions.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "paths": { "/foo": { "summary": "Foo Resource", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator.json index 13b034122..45ea89bf3 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "MyResponseType": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator30.json new file mode 100644 index 000000000..ebfb6aae1 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-discriminator30.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "MyResponseType": { + "oneOf": [ + { + "$ref": "#/components/schemas/Cat" + }, + { + "$ref": "#/components/schemas/Dog" + }, + { + "$ref": "#/components/schemas/Lizard" + }, + { + "$ref": "https://gigantic-server.com/schemas/Monster/schema.json" + } + ], + "discriminator": { + "propertyName": "pet_type", + "mapping": { + "dog": "#/components/schemas/Dog", + "monster": "https://gigantic-server.com/schemas/Monster/schema.json" + } + } + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties.json index 1e37de171..c45ff49c9 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Example": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties30.json new file mode 100644 index 000000000..ebe77d64d --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-additionalProperties30.json @@ -0,0 +1,38 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Example": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "additionalProperties" : { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "address": { + "$ref": "#/definitions/Address" + }, + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf.json index 93b8b23bd..7f9bbe3b1 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf.json @@ -1,13 +1,11 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Example": { + "$ref": "#/definitions/address", "type": "object", "allOf": [ - { - "$ref": "#/definitions/address" - }, { "properties": { "type": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf30.json new file mode 100644 index 000000000..3f6b46421 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-allOf30.json @@ -0,0 +1,26 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Example": { + "type": "object", + "allOf": [ + { + "properties": { + "type": { + "enum": [ + "residential", + "business" + ] + } + } + }, + { + "$ref": "#/definitions/address" + } + ], + "additionalProperties": false + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition.json index 1b502488f..26bfc50d5 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "ErrorModel": { @@ -20,10 +20,8 @@ } }, "ExtendedErrorModel": { + "$ref": "#/definitions/ErrorModel", "allOf": [ - { - "$ref": "#/definitions/ErrorModel" - }, { "type": "object", "required": [ diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition30.json new file mode 100644 index 000000000..e3941e3d5 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-composition30.json @@ -0,0 +1,42 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "ErrorModel": { + "type": "object", + "required": [ + "message", + "code" + ], + "properties": { + "message": { + "type": "string" + }, + "code": { + "type": "integer", + "minimum": 100, + "maximum": 600 + } + } + }, + "ExtendedErrorModel": { + "allOf": [ + { + "type": "object", + "required": [ + "rootCause" + ], + "properties": { + "rootCause": { + "type": "string" + } + } + }, + { + "$ref": "#/definitions/ErrorModel" + } + ] + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example.json index e5d36f7e4..97d66d4d1 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Person": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example30.json new file mode 100644 index 000000000..ff586a6af --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-example30.json @@ -0,0 +1,26 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Person": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "example": { + "name": "Puma", + "id": 1 + } + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs.json index 835de4484..276f28524 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Person": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs30.json new file mode 100644 index 000000000..b30e6527b --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-externalDocs30.json @@ -0,0 +1,23 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Person": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + }, + "externalDocs" : { + "description": "Find more info here", + "url": "https://swagger.io" + } + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData.json index 342830545..6a60b0044 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Example": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData30.json new file mode 100644 index 000000000..8bbc15585 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-metaData30.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Example": { + "title": "Example Type", + "description" : "Some markdown flavored description would go here!", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + } + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both.json new file mode 100644 index 000000000..a08a8e82c --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both.json @@ -0,0 +1,43 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "min": { + "type": "number", + "minimum": 5 + }, + "exMin": { + "type": "number", + "exclusiveMinimum": 5 + }, + "bothMin": { + "type": "number", + "minimum": 5, + "exclusiveMinimum": 3 + }, + "bothExMin": { + "type": "number", + "minimum": 3, + "exclusiveMinimum": 5 + }, + "max": { + "type": "number", + "maximum": 5 + }, + "exMax": { + "type": "number", + "exclusiveMaximum": 5 + }, + "bothMax": { + "type": "number", + "maximum": 3, + "exclusiveMaximum": 5 + }, + "bothExMax": { + "type": "number", + "maximum": 5, + "exclusiveMaximum": 3 + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both30.json new file mode 100644 index 000000000..18253f869 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax-both30.json @@ -0,0 +1,43 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "min": { + "type": "number", + "minimum": 5 + }, + "exMin": { + "type": "number", + "minimum": 5, + "exclusiveMinimum": true + }, + "bothMin": { + "type": "number", + "minimum": 5 + }, + "bothExMin": { + "type": "number", + "minimum": 5, + "exclusiveMinimum": true + }, + "max": { + "type": "number", + "maximum": 5 + }, + "exMax": { + "type": "number", + "maximum": 5, + "exclusiveMaximum": true + }, + "bothMax": { + "type": "number", + "maximum": 3 + }, + "bothExMax": { + "type": "number", + "maximum": 3, + "exclusiveMaximum": true + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax.json new file mode 100644 index 000000000..0d29f86ab --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax.json @@ -0,0 +1,23 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "min": { + "type": "number", + "minimum": 5 + }, + "exMin": { + "type": "number", + "exclusiveMinimum": 5 + }, + "max": { + "type": "number", + "maximum": 5 + }, + "exMax": { + "type": "number", + "exclusiveMaximum": 5 + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax30.json new file mode 100644 index 000000000..433d8f091 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-minmax30.json @@ -0,0 +1,25 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "min": { + "type": "number", + "minimum": 5 + }, + "exMin": { + "type": "number", + "minimum": 5, + "exclusiveMinimum": true + }, + "max": { + "type": "number", + "maximum": 5 + }, + "exMax": { + "type": "number", + "maximum": 5, + "exclusiveMaximum": true + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable.json new file mode 100644 index 000000000..f3fcdfc1c --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable.json @@ -0,0 +1,54 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "NullableAlone": { + "description": "nullable alone" + }, + "NullableWithAnyOf": { + "anyOf": [ + { + "multipleOf": 3 + }, + { + "multipleOf": 5 + } + ], + "allOf": [ + { + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "type": "null" + } + ] + } + ] + }, + "NullableWithMultiRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + }, + "NullableWithMultiAltRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-1.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-1.json new file mode 100644 index 000000000..7ce028ca4 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-1.json @@ -0,0 +1,51 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "NullableAlone": { + "description": "nullable alone", + "nullable": true + }, + "NullableWithAnyOf": { + "anyOf": [ + { + "multipleOf": 3 + }, + { + "multipleOf": 5 + } + ], + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + } + ] + }, + "NullableWithMultiRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + }, + "NullableWithMultiAltRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "nullable": true, + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-2.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-2.json new file mode 100644 index 000000000..a30fdd240 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference-non-reversable30-2.json @@ -0,0 +1,52 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "NullableAlone": { + "description": "nullable alone" + }, + "NullableWithAnyOf": { + "anyOf": [ + { + "multipleOf": 3 + }, + { + "multipleOf": 5 + } + ], + "allOf": [ + { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + } + ] + } + ] + }, + "NullableWithMultiRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + }, + "NullableWithMultiAltRef": { + "description": "nullable should really be kept here, but currently it gets dropped", + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference.json new file mode 100644 index 000000000..beaa95af9 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference.json @@ -0,0 +1,72 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "NullRef": { + "description": "nullable reference", + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "type": "null" + } + ] + }, + "NullRefWithAnyOf": { + "allOf": [ + { + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "type": "null" + } + ] + }, + { + "anyOf": [ + { + "multipleOf": 3 + }, + { + "multipleOf": 5 + } + ] + } + ] + }, + "MultiAnyNullRef": { + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + }, + { + "type": "null" + } + ] + }, + "MultiAllNullRef": { + "anyOf": [ + { + "allOf" : [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + }, + { + "type": "null" + } + ] + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference30.json new file mode 100644 index 000000000..d5de5f61d --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-nullable-reference30.json @@ -0,0 +1,68 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "NullRef": { + "description": "nullable reference", + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + } + ] + }, + "NullRefWithAnyOf": { + "allOf": [ + { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/mySchema" + } + ] + }, + { + "anyOf": [ + { + "multipleOf": 3 + }, + { + "multipleOf": 5 + } + ] + } + ] + }, + "MultiAnyNullRef": { + "anyOf": [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + }, + { + "enum": [null] + } + ] + }, + "MultiAllNullRef": { + "anyOf": [ + { + "allOf" : [ + { + "$ref": "#/components/schemas/mySchema" + }, + { + "$ref": "#/components/schemas/mySchema2" + } + ] + }, + { + "enum": [null] + } + ] + } + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml.json index 649215c86..b30e5daea 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "components": { "schemas": { "Person": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml30.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml30.json new file mode 100644 index 000000000..77d874503 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/schemas-with-xml30.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.0.3", + "components": { + "schemas": { + "Person": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32", + "xml": { + "attribute": true + } + }, + "name": { + "type": "string", + "xml": { + "name": "xname", + "namespace": "http://swagger.io/schema/sample", + "prefix": "sample", + "wrapped": false + } + } + } + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/security.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/security.json index 5a3d026b4..825396e4a 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/security.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/security.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "security" : [ { "api_key": [] diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.json index 0c5c1067a..6969e9ec9 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "servers": [ { "url": "https://development.gigantic-server.com/v1", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.yaml index 6ec847029..c1dff32b0 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.yaml +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/servers.yaml @@ -1,5 +1,5 @@ --- -openapi: 3.0.0 +openapi: 3.1.0 servers: - url: https://development.gigantic-server.com/v1 description: Development server diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.json index 7ce81cfcc..c4cc075ba 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.json @@ -1,3 +1,3 @@ { - "openapi" : "3.0.0" + "openapi" : "3.1.0" } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.yaml b/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.yaml index 7f2e28857..37162cc13 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.yaml +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/simplest.yaml @@ -1 +1 @@ -openapi: 3.0.0 \ No newline at end of file +openapi: 3.1.0 \ No newline at end of file diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/io/tags.json b/core/src/test/resources/io/smallrye/openapi/runtime/io/tags.json index 5fb0c97bd..7fdc08581 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/io/tags.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/io/tags.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.0", "tags" : [ { "name": "tag1", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas-jackson-jsonunwrapped.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas-jackson-jsonunwrapped.json index 07cdc5055..37c0bc95e 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas-jackson-jsonunwrapped.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas-jackson-jsonunwrapped.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "JacksonJsonPerson": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.annotated-constructor-arg-ignored.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.annotated-constructor-arg-ignored.json index ca165319c..8a9a8f6ac 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.annotated-constructor-arg-ignored.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.annotated-constructor-arg-ignored.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "SingleAnnotatedConstructorArgument": { @@ -9,7 +9,7 @@ "property1": { "description": "The single property", "type": "string", - "example": "some value" + "examples": ["some value"] } } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.array-type-override.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.array-type-override.json index e7d3be67a..0d0469191 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.array-type-override.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.array-type-override.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "Sample": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.enum-naming.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.enum-naming.json index c1da0a0f7..522ac8304 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.enum-naming.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.enum-naming.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Bean" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json index 29892de7f..3fa047073 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json @@ -1,33 +1,33 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Bean" : { "type" : "object", "properties" : { "property1" : { - "example" : "{ Looks like object, but invalid }" + "examples" : [ "{ Looks like object, but invalid }" ] }, "property2" : { - "example" : "{ \"key\": \"object end missing\"" + "examples" : [ "{ \"key\": \"object end missing\"" ] }, "property3" : { - "example" : "[ Looks like array, but invalid ]" + "examples" : [ "[ Looks like array, but invalid ]" ] }, "property4" : { - "example" : "[ \"array end missing\"" + "examples" : [ "[ \"array end missing\"" ] }, "property5" : { - "example" : "trick" + "examples" : [ "trick" ] }, "property6" : { - "example" : "fake" + "examples" : [ "fake" ] }, "property7" : { - "example" : "1046\n1049\n1051" + "examples" : [ "1046\n1049\n1051" ] }, "property8" : { - "example" : "" + "examples" : [ "" ] } } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.field-overrides-type.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.field-overrides-type.json index 22177fe12..37df7cc6d 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.field-overrides-type.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.field-overrides-type.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "Bean": { @@ -20,13 +20,9 @@ } }, "second": { - "title": "Property with `allOf` referring to `OtherBean`", + "title": "Property with `type` and reference to `OtherBean`", "type": "object", - "allOf": [ - { - "$ref": "#/components/schemas/OtherBean" - } - ] + "$ref": "#/components/schemas/OtherBean" }, "third": { "$ref": "#/components/schemas/OtherBean" diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance-parent-only.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance-parent-only.json index 8c7fed01c..f7bb7e748 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance-parent-only.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance-parent-only.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Alligator" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance.json index 3a5ad4f43..3bb65669e 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.inheritance.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Alligator" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.iterator-stream-map-types.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.iterator-stream-map-types.json index 08dbab9d6..39e85e338 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.iterator-stream-map-types.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.iterator-stream-map-types.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "StringArray": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jackson-property-access.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jackson-property-access.json index ef489ce68..631ada14f 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jackson-property-access.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jackson-property-access.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Bean" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.javabean-property-prefix.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.javabean-property-prefix.json index 58c822b7e..42c399666 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.javabean-property-prefix.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.javabean-property-prefix.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Bean" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jaxbelement-generic-type-unwrapped.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jaxbelement-generic-type-unwrapped.json index a5073a789..0e1ced25a 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jaxbelement-generic-type-unwrapped.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.jaxbelement-generic-type-unwrapped.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "JAXBElementDto": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-ignored.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-ignored.json index 7f6e2ea20..bbff760d0 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-ignored.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-ignored.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "NameStrategyBean2": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-kebab.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-kebab.json index 026de8b28..d50571bb0 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-kebab.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-kebab.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "NameStrategyKebab": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-snake.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-snake.json index 8e539a888..c30aca969 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-snake.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.name-strategy-snake.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "NameStrategyBean1": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json index 97a2d60af..f4a8c85e9 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "Foo": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-parameterized-collection-types.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-parameterized-collection-types.json index 1a8833a57..84522f776 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-parameterized-collection-types.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-parameterized-collection-types.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "CollectionBean" : { @@ -18,9 +18,7 @@ "b_multivaluedEntryMap" : { "type": "object", "description" : "Reference to `MultivaluedMapStringEntryBean", - "allOf" : [ { - "$ref" : "#/components/schemas/MultivaluedMapStringEntryBean" - } ] + "$ref" : "#/components/schemas/MultivaluedMapStringEntryBean" }, "c_mapStringListEntryBean" : { "description" : "In-line schema, `additionalProperties` array `items` reference `EntryBean`", @@ -64,9 +62,7 @@ "f_listOfStringLists" : { "type": "array", "description" : "Reference to `MultivaluedCollectionString`", - "allOf" : [ { - "$ref" : "#/components/schemas/MultivaluedCollectionString" - } ] + "$ref" : "#/components/schemas/MultivaluedCollectionString" } } }, diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.no-self-ref-for-property-schema.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.no-self-ref-for-property-schema.json index 4ac077522..b9a7a5475 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.no-self-ref-for-property-schema.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.no-self-ref-for-property-schema.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MyClass" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nonparameterized-ancestry-chain-link.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nonparameterized-ancestry-chain-link.json index a3b8b02c3..1e9aa8f25 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nonparameterized-ancestry-chain-link.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nonparameterized-ancestry-chain-link.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "1PairStringString": { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.optional-arraytype.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.optional-arraytype.json index 9e90a7270..76ef01682 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.optional-arraytype.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.optional-arraytype.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "A": { @@ -8,8 +8,10 @@ "arrayOfOptionalB": { "type": "array", "items": { - "nullable": true, - "allOf": [ + "anyOf": [ + { + "type": "null" + }, { "$ref": "#/components/schemas/B" } @@ -28,8 +30,10 @@ "listOfOptionalB": { "type": "array", "items": { - "nullable": true, - "allOf": [ + "anyOf": [ + { + "type": "null" + }, { "$ref": "#/components/schemas/B" } @@ -37,25 +41,24 @@ } }, "optionalArrayOfB": { - "type": "array", + "type": ["array", "null"], "items": { "$ref": "#/components/schemas/B" - }, - "nullable": true + } }, "optionalListOfB": { - "type": "array", + "type": ["array","null"], "items": { "$ref": "#/components/schemas/B" - }, - "nullable": true + } }, "optionalOfB": { - "type": "object", - "nullable": true, - "allOf": [ + "anyOf": [ { "$ref": "#/components/schemas/B" + }, + { + "type": "null" } ] } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.parameterized-type-schema-config.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.parameterized-type-schema-config.json index 472f9e518..eb4ca8c26 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.parameterized-type-schema-config.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.parameterized-type-schema-config.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "Bean" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.registered-schema-type-preserved.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.registered-schema-type-preserved.json index 360e1036d..c8016799a 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.registered-schema-type-preserved.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.registered-schema-type-preserved.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "AnimalListEnvelope": { @@ -8,7 +8,7 @@ "apiVersion": { "description": "The API version", "type": "string", - "example": "v3" + "examples": ["v3"] }, "context": { "description": "Optional context-value for request/response correlation", @@ -17,16 +17,12 @@ "requestId": { "description": "Unique request-id (used for logging)", "type": "string", - "example": "F176f717c7a71" + "examples": ["F176f717c7a71"] }, "data": { "type": "object", "description": "The business data object", - "allOf": [ - { - "$ref": "#/components/schemas/MessageDataItemsAnimal" - } - ] + "$ref": "#/components/schemas/MessageDataItemsAnimal" }, "kind": { "description": "The class-name of the business data object", @@ -46,7 +42,7 @@ "currentItemCount": { "format": "int32", "type": "integer", - "example": 1 + "examples": [1] } } }, @@ -62,7 +58,7 @@ "currentItemCount": { "format": "int32", "type": "integer", - "example": 1 + "examples": [1] } } }, @@ -84,7 +80,7 @@ "apiVersion": { "description": "The API version", "type": "string", - "example": "v3" + "examples": ["v3"] }, "context": { "description": "Optional context-value for request/response correlation", @@ -93,7 +89,7 @@ "requestId": { "description": "Unique request-id (used for logging)", "type": "string", - "example": "F176f717c7a71" + "examples": ["F176f717c7a71"] } } }, @@ -103,7 +99,7 @@ "apiVersion": { "description": "The API version", "type": "string", - "example": "v3" + "examples": ["v3"] }, "context": { "description": "Optional context-value for request/response correlation", @@ -112,7 +108,7 @@ "requestId": { "description": "Unique request-id (used for logging)", "type": "string", - "example": "F176f717c7a71" + "examples": ["F176f717c7a71"] }, "data": { "description": "The business data object" diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-allofmissing.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-allofmissing.json index 5622a78c8..6b93aabe1 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-allofmissing.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-allofmissing.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "AllOfMissing" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-anyofmissing.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-anyofmissing.json index 789152ca6..e1ae149ce 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-anyofmissing.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-anyofmissing.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "AnyOfMissing" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-blankname.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-blankname.json index 42aa24241..d8b0ee433 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-blankname.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-blankname.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "BlankNameTest" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-defaultvaluewrongtype.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-defaultvaluewrongtype.json index fea5df844..35df1f278 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-defaultvaluewrongtype.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-defaultvaluewrongtype.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "DefaultValueWrongType" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-duplicatename.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-duplicatename.json index 87d838194..a13256d98 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-duplicatename.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-duplicatename.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "DuplicateNameTest" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-implementationmissing.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-implementationmissing.json index 1a2812a27..441d3e097 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-implementationmissing.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-implementationmissing.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "ImplementationMissing" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maximumnotnumber.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maximumnotnumber.json index 87ab12fa6..42c96e62c 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maximumnotnumber.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maximumnotnumber.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MaximumNotNumber" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxitemsnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxitemsnegative.json index b46662e20..7c69a32ac 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxitemsnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxitemsnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MaxItemsNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxlengthnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxlengthnegative.json index defc7276e..5a933d4e1 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxlengthnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxlengthnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MaxLengthNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxpropertiesnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxpropertiesnegative.json index 9f3e40a98..84d2265af 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxpropertiesnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-maxpropertiesnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MaxPropertiesNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-merge.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-merge.json index 19c675bb6..e3cba19e1 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-merge.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-merge.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "Lizard": { @@ -32,11 +32,7 @@ "type": "string", "description": "The units of measure for length", "default": "CM", - "allOf": [ - { - "$ref": "#/components/schemas/LengthUnitsEnum" - } - ] + "$ref": "#/components/schemas/LengthUnitsEnum" }, "length": { "format": "double", diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minimumnotnumber.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minimumnotnumber.json index 4e9c79b01..9a0ee6acb 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minimumnotnumber.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minimumnotnumber.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MinimumNotNumber" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minitemsnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minitemsnegative.json index 83ab700b2..0dddf06b8 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minitemsnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minitemsnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MinItemsNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minlengthnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minlengthnegative.json index ed62e1da3..ddeffca47 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minlengthnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minlengthnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MinLengthNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minpropertiesnegative.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minpropertiesnegative.json index bed167102..5c731efae 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minpropertiesnegative.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-minpropertiesnegative.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "MinPropertiesNegative" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-negativemultipleof.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-negativemultipleof.json index 8d4fbca71..37f457f02 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-negativemultipleof.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-negativemultipleof.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "NegativeMultipleOf" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-notmissing.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-notmissing.json index 5f277f18c..a77541fd6 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-notmissing.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-notmissing.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "NotMissing" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-oneofmissing.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-oneofmissing.json index 8bab1be7d..e144e24fd 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-oneofmissing.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-oneofmissing.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "OneOfMissing" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-patterninvalid.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-patterninvalid.json index 9792e6ad0..e9fef0492 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-patterninvalid.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-patterninvalid.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "PatternInvalid" : { diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-refwithotherprops.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-refwithotherprops.json index b868a3eea..0f02df075 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-refwithotherprops.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.schemaproperty-refwithotherprops.json @@ -1,11 +1,12 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "RefWithOtherProps" : { "type" : "object", "properties" : { "test" : { + "type" : "string", "$ref" : "#/components/schemas/foobar" } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application-property.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application-property.json new file mode 100644 index 000000000..48cf06f81 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application-property.json @@ -0,0 +1,83 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "A": { + "description": "A", + "type": "object" + }, + "B": { + "description": "B", + "type": "object" + }, + "C": { + "description": "C", + "type": "object" + }, + "TestAnyOfProperty": { + "properties": { + "prop": { + "anyOf": [ + { + "$ref": "#/components/schemas/A" + }, + { + "$ref": "#/components/schemas/B" + }, + { + "$ref": "#/components/schemas/C" + } + ] + } + }, + "type": "object" + }, + "TestAllOfProperty": { + "properties": { + "prop": { + "allOf": [ + { + "$ref": "#/components/schemas/A" + }, + { + "$ref": "#/components/schemas/B" + }, + { + "$ref": "#/components/schemas/C" + } + ] + } + }, + "type": "object" + }, + "TestNotProperty": { + "properties": { + "prop": { + "not": { + "$ref": "#/components/schemas/A" + } + } + }, + "type": "object" + }, + "TestOneOfProperty": { + "properties": { + "prop": { + "oneOf": [ + { + "$ref": "#/components/schemas/A" + }, + { + "$ref": "#/components/schemas/B" + }, + { + "$ref": "#/components/schemas/C" + } + ] + } + }, + "type": "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application.json new file mode 100644 index 000000000..f57260e27 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-application.json @@ -0,0 +1,55 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "A" : { + "description" : "A", + "type" : "object" + }, + "B" : { + "description" : "B", + "type" : "object" + }, + "C" : { + "description" : "C", + "type" : "object" + }, + "TestAnyOf" : { + "anyOf" : [ { + "$ref" : "#/components/schemas/A" + }, { + "$ref" : "#/components/schemas/B" + }, { + "$ref" : "#/components/schemas/C" + } ], + "type" : "object" + }, + "TestAllOf" : { + "allOf" : [ { + "$ref" : "#/components/schemas/A" + }, { + "$ref" : "#/components/schemas/B" + }, { + "$ref" : "#/components/schemas/C" + } ], + "type" : "object" + }, + "TestNot" : { + "not" : { + "$ref" : "#/components/schemas/A" + }, + "type" : "object" + }, + "TestOneOf" : { + "oneOf" : [ { + "$ref" : "#/components/schemas/A" + }, { + "$ref" : "#/components/schemas/B" + }, { + "$ref" : "#/components/schemas/C" + } ], + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections-property.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections-property.json new file mode 100644 index 000000000..ed26dfd19 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections-property.json @@ -0,0 +1,83 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "JavaTypeString" : { + "type" : "string", + "pattern" : "^[A-Z][a-zA-Z0-9]*$" + }, + "A" : { + "description" : "A", + "type" : "object" + }, + "TestCollectionsProperty" : { + "properties" : { + "mustStartWithTwoTypeNames" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "prefixItems" : [ + { + "$ref" : "#/components/schemas/JavaTypeString" + }, { + "$ref" : "#/components/schemas/JavaTypeString" + } + ] + }, + "mustContainATypeName" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "contains" : { + "$ref" : "#/components/schemas/JavaTypeString" + } + }, + "mustContain3To5TypeNames" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "contains" : { + "$ref" : "#/components/schemas/JavaTypeString" + }, + "minContains" : 3, + "maxContains" : 5 + }, + "keysMustBeTypeNames" : { + "type" : "object", + "propertyNames" : { + "$ref" : "#/components/schemas/JavaTypeString" + }, + "additionalProperties" : { + "type" : "string" + } + }, + "keysNamedByType" : { + "type" : "object", + "patternProperties" : { + "^str" : { + "type" : "string" + }, + "^int" : { + "type" : "integer", + "format" : "int32" + } + }, + "additionalProperties" : {} + }, + "encodedJson" : { + "type" : "string", + "contentEncoding" : "base64", + "contentMediaType" : "application/json", + "contentSchema" : { + "$ref" : "#/components/schemas/A" + } + } + }, + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections.json new file mode 100644 index 000000000..2e051d435 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-collections.json @@ -0,0 +1,83 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "JavaTypeString" : { + "type" : "string", + "pattern" : "^[A-Z][a-zA-Z0-9]*$" + }, + "A" : { + "description" : "A", + "type" : "object" + }, + "TestCollections" : { + "properties" : { + "mustStartWithTwoTypeNames" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "prefixItems" : [ + { + "$ref" : "#/components/schemas/JavaTypeString" + }, { + "$ref" : "#/components/schemas/JavaTypeString" + } + ] + }, + "mustContainATypeName" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "contains" : { + "$ref" : "#/components/schemas/JavaTypeString" + } + }, + "mustContain3To5TypeNames" : { + "type" : "array", + "items" : { + "type" : "string" + }, + "contains" : { + "$ref" : "#/components/schemas/JavaTypeString" + }, + "minContains" : 3, + "maxContains" : 5 + }, + "keysMustBeTypeNames" : { + "type" : "object", + "propertyNames" : { + "$ref" : "#/components/schemas/JavaTypeString" + }, + "additionalProperties" : { + "type" : "string" + } + }, + "keysNamedByType" : { + "type" : "object", + "patternProperties" : { + "^str" : { + "type" : "string" + }, + "^int" : { + "type" : "integer", + "format" : "int32" + } + }, + "additionalProperties" : {} + }, + "encodedJson" : { + "type" : "string", + "contentEncoding" : "base64", + "contentMediaType" : "application/json", + "contentSchema" : { + "$ref" : "#/components/schemas/A" + } + } + }, + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required-property.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required-property.json new file mode 100644 index 000000000..3a1b7f4ac --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required-property.json @@ -0,0 +1,23 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "TestDependentRequiredProperty": { + "properties": { + "prop": { + "dependentRequired": { + "field1": [ + "field2", + "field3" + ], + "field4": [ + "field5" + ] + } + } + }, + "type": "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required.json new file mode 100644 index 000000000..de2c7eb5c --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-required.json @@ -0,0 +1,30 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "TestDependentRequired" : { + "properties" : { + "field1" : { + "type" : "string" + }, + "field2" : { + "type" : "string" + }, + "field3" : { + "type" : "string" + } + }, + "dependentRequired": { + "field1" : [ + "field2", + "field3" + ], + "field4" : [ + "field5" + ] + }, + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas-property.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas-property.json new file mode 100644 index 000000000..90e1c932e --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas-property.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "A": { + "description": "A", + "type": "object" + }, + "B": { + "description": "B", + "type": "object" + }, + "TestDepedentSchemasProperty": { + "properties": { + "prop": { + "dependentSchemas": { + "field1": { + "$ref": "#/components/schemas/A" + }, + "field2": { + "$ref": "#/components/schemas/B" + } + } + } + }, + "type": "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas.json new file mode 100644 index 000000000..47d9f05ae --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-dependent-schemas.json @@ -0,0 +1,31 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "A" : { + "description" : "A", + "type" : "object" + }, + "B" : { + "description" : "B", + "type" : "object" + }, + "TestDepedentSchemas" : { + "properties" : { + "field1" : { + "type" : "string" + } + }, + "dependentSchemas": { + "field1" : { + "$ref" : "#/components/schemas/A" + }, + "field2" : { + "$ref" : "#/components/schemas/B" + } + }, + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse-property.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse-property.json new file mode 100644 index 000000000..6e0ff9881 --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse-property.json @@ -0,0 +1,35 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "A": { + "description": "A", + "type": "object" + }, + "B": { + "description": "B", + "type": "object" + }, + "C": { + "description": "C", + "type": "object" + }, + "TestIfThenElseProperty": { + "properties": { + "prop": { + "if": { + "$ref": "#/components/schemas/A" + }, + "then": { + "$ref": "#/components/schemas/B" + }, + "else": { + "$ref": "#/components/schemas/C" + } + } + }, + "type": "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse.json new file mode 100644 index 000000000..7b7e2453e --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.subschema-ifthenelse.json @@ -0,0 +1,31 @@ +{ + "openapi" : "3.1.0", + "components" : { + "schemas" : { + "A" : { + "description" : "A", + "type" : "object" + }, + "B" : { + "description" : "B", + "type" : "object" + }, + "C" : { + "description" : "C", + "type" : "object" + }, + "TestIfThenElse" : { + "if" : { + "$ref" : "#/components/schemas/A" + }, + "then" : { + "$ref" : "#/components/schemas/B" + }, + "else" :{ + "$ref" : "#/components/schemas/C" + }, + "type" : "object" + } + } + } +} diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.terminal-array-item-registration.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.terminal-array-item-registration.json index edb9c420d..a20287bc2 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.terminal-array-item-registration.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.terminal-array-item-registration.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "ZonedDateTimeArrayWrapper": { @@ -16,7 +16,7 @@ "ZonedDateTime": { "format": "date-time", "type": "string", - "example": "2022-03-10T12:15:50-04:00" + "examples": [ "2022-03-10T12:15:50-04:00" ] } } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.unreferenced.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.unreferenced.json index 1e4263e94..336c2d4eb 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.unreferenced.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.unreferenced.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Test", "version": "1.0" @@ -16,8 +16,7 @@ "maximum": 20 }, "color": { - "type": "string", - "nullable": true + "type": ["string", "null"] }, "name": { "type": "string" diff --git a/extension-jaxrs/pom.xml b/extension-jaxrs/pom.xml index 880896ec9..6fb6b15ac 100644 --- a/extension-jaxrs/pom.xml +++ b/extension-jaxrs/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-jaxrs diff --git a/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java b/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java index f8ea21e6b..0ba7144ca 100644 --- a/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java +++ b/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java @@ -345,13 +345,13 @@ private Stream>> exceptionResponseAnnota .of(classInfo.method(JaxRsConstants.TO_RESPONSE_METHOD_NAME, exceptionType)) .filter(Objects::nonNull) .flatMap(m -> context.io() - .responses() + .apiResponsesIO() .readAll(m) .entrySet() .stream()); Stream> classAnnotations = context.io() - .responses() + .apiResponsesIO() .readAll(classInfo) .entrySet() .stream(); @@ -404,7 +404,7 @@ private void processSubResource(final ClassInfo resourceClass, // Do not allow the same resource locator method to be used twice (sign of infinite recursion) if (subResourceClass != null && !this.subResourceStack.contains(locator)) { - Function reader = t -> context.io().parameters().read(t); + Function reader = t -> context.io().parameterIO().read(t); ResourceParameters params = JaxRsParameterProcessor.process(context, currentAppPath, resourceClass, method, reader, context.getExtensions()); @@ -549,7 +549,7 @@ private void processResourceMethod(final ClassInfo resourceClass, } private ResourceParameters getResourceParameters(final ClassInfo resourceClass, final MethodInfo method) { - Function reader = t -> context.io().parameters().read(t); + Function reader = t -> context.io().parameterIO().read(t); return JaxRsParameterProcessor.process(context, currentAppPath, resourceClass, method, reader, context.getExtensions()); } diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigExtensionsTest.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigExtensionsTest.java index 1d6a89670..dd9a7e4cb 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigExtensionsTest.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigExtensionsTest.java @@ -25,11 +25,13 @@ class ConfigExtensionsTest extends JaxRsDataObjectScannerTestBase { private static final String TITLE = "mp.openapi.extensions.smallrye.info.title"; private static final String VERSION = "mp.openapi.extensions.smallrye.info.version"; private static final String DESCRIPTION = "mp.openapi.extensions.smallrye.info.description"; + private static final String SUMMARY = "mp.openapi.extensions.smallrye.info.summary"; private static final String TERMS = "mp.openapi.extensions.smallrye.info.termsOfService"; private static final String CONTACT_EMAIL = "mp.openapi.extensions.smallrye.info.contact.email"; private static final String CONTACT_NAME = "mp.openapi.extensions.smallrye.info.contact.name"; private static final String CONTACT_URL = "mp.openapi.extensions.smallrye.info.contact.url"; private static final String LICENSE_NAME = "mp.openapi.extensions.smallrye.info.license.name"; + private static final String LICENSE_IDENTIFIER = "mp.openapi.extensions.smallrye.info.license.identifier"; private static final String LICENSE_URL = "mp.openapi.extensions.smallrye.info.license.url"; @Test @@ -67,8 +69,9 @@ void testSettingJustContactEmail() throws IOException, JSONException { } @Test - void testSettingJustLicenseName() throws IOException, JSONException { + void testSettingJustLicenseNameAndIdentifier() throws IOException, JSONException { System.setProperty(LICENSE_NAME, "Apache License 2.0"); + System.setProperty(LICENSE_IDENTIFIER, "Apache-2.0"); Config config = ConfigProvider.getConfig(); OpenApiConfig openApiConfig = OpenApiConfig.fromConfig(config); try { @@ -80,21 +83,23 @@ void testSettingJustLicenseName() throws IOException, JSONException { } finally { System.clearProperty(LICENSE_NAME); + System.clearProperty(LICENSE_IDENTIFIER); } } @Test void testSettingAllInfo() throws IOException, JSONException { - System.setProperty(TITLE, "My own awesome REST service"); System.setProperty(VERSION, "1.2.3"); System.setProperty(DESCRIPTION, "This service is awesome"); + System.setProperty(SUMMARY, "This summary is rather boring"); System.setProperty(TERMS, "The terms is also awesome"); System.setProperty(CONTACT_EMAIL, "phillip.kruger@redhat.com"); System.setProperty(CONTACT_NAME, "Phillip Kruger"); System.setProperty(CONTACT_URL, "https://www.phillip-kruger.com"); System.setProperty(LICENSE_NAME, "Apache License 2.0"); System.setProperty(LICENSE_URL, "https://choosealicense.com/licenses/apache-2.0/"); + //Licence Identifier excluded for being exclusive with URL Config config = ConfigProvider.getConfig(); OpenApiConfig openApiConfig = OpenApiConfig.fromConfig(config); @@ -109,6 +114,7 @@ void testSettingAllInfo() throws IOException, JSONException { System.clearProperty(TITLE); System.clearProperty(VERSION); System.clearProperty(DESCRIPTION); + System.clearProperty(SUMMARY); System.clearProperty(TERMS); System.clearProperty(CONTACT_EMAIL); System.clearProperty(CONTACT_NAME); diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigSchemaTest.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigSchemaTest.java index cac24aa52..b881703fb 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigSchemaTest.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ConfigSchemaTest.java @@ -36,7 +36,7 @@ class ConfigSchemaTest extends JaxRsDataObjectScannerTestBase { private static final String INVALID_PROPERTY_VALUE_SCHEMA = Json.createObjectBuilder() .add("name", "message") .add("type", "string") - .add("malformed-property", "This should not appear in output document") + .add("unknown-property", "This should appear in output document") .build() .toString(); @@ -79,9 +79,9 @@ void testInvalidSchemaKeyDefinitionViaConfig() throws IOException, JSONException } } - // Technically correct behaviour as malformed-property is not rendered in schema, but no feedback + // Unknown properties should be passed through untouched @Test - void testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig() throws IOException, JSONException { + void testValidSchemaKeyWithUnknownSchemaPropertyValueViaConfig() throws IOException, JSONException { System.setProperty(VALID_SCHEMA_PROPERTY_KEY, INVALID_PROPERTY_VALUE_SCHEMA); Config config = ConfigProvider.getConfig(); OpenApiConfig openApiConfig = OpenApiConfig.fromConfig(config); @@ -90,7 +90,7 @@ void testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig() throws IOExcept OpenAPI result = OpenApiProcessor.bootstrap(openApiConfig, i); printToConsole(result); - assertJsonEquals("resource.testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig.json", result); + assertJsonEquals("resource.testValidSchemaKeyWithUnknownSchemaPropertyValueViaConfig.json", result); } finally { System.clearProperty(VALID_SCHEMA_PROPERTY_KEY); diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JaxRsAnnotationScannerTest.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JaxRsAnnotationScannerTest.java index 8c4f66db9..4f9283c87 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JaxRsAnnotationScannerTest.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JaxRsAnnotationScannerTest.java @@ -412,7 +412,7 @@ static class MyCustomSchemaRegistry implements CustomSchemaRegistry { public void registerCustomSchemas(SchemaRegistry schemaRegistry) { Type uuidType = Type.create(componentize(UUID.class.getName()), Kind.CLASS); Schema schema = new SchemaImpl(); - schema.setType(Schema.SchemaType.STRING); + schema.addType(Schema.SchemaType.STRING); schema.setFormat("uuid"); schema.setPattern("^[a-f0-9]{8}-?[a-f0-9]{4}-?[1-5][a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"); schema.setTitle("UUID"); diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/VersionTest.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/VersionTest.java index 54906cd1e..6f792d9f7 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/VersionTest.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/VersionTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import test.io.smallrye.openapi.runtime.scanner.entities.Greeting; +import test.io.smallrye.openapi.runtime.scanner.entities.Schema31Changes; /** * Basic tests to check the version configuration @@ -38,7 +39,7 @@ void testJakartaSettingViaProvidedSchema() throws IOException, JSONException { } void testSettingViaProvidedSchema(Class... classes) throws IOException, JSONException { - OpenAPI result = scan(config(Collections.emptyMap()), true, loadStaticFile(), classes); + OpenAPI result = scan(config(Collections.emptyMap()), true, loadStaticFile("version-valid.json"), classes); assertJsonEquals("resource.testVersionViaSchema.json", result); } @@ -55,7 +56,7 @@ void testJakartaSettingViaConfig() throws IOException, JSONException { } void testSettingViaConfig(Class... classes) throws IOException, JSONException { - System.setProperty(VERSION_PROPERTY, "3.0.0"); + System.setProperty(VERSION_PROPERTY, "3.1.2"); try { OpenAPI result = scan(config(Collections.emptyMap()), true, null, classes); @@ -78,19 +79,47 @@ void testJakartaSettingViaConfigWhenStaticPresent() throws IOException, JSONExce } void testSettingViaConfigWhenStaticPresent(Class... classes) throws IOException, JSONException { - System.setProperty(VERSION_PROPERTY, "3.0.0"); + //The test will pass if this version matches the one in the file of expected JSON (resource.testVersionViaConfig.json) and the file read by loadStaticFile() (version.json) is overriden. + System.setProperty(VERSION_PROPERTY, "3.1.2"); try { - OpenAPI result = scan(config(Collections.emptyMap()), true, loadStaticFile(), classes); + OpenAPI result = scan(config(Collections.emptyMap()), true, loadStaticFile("version-broken.json"), classes); assertJsonEquals("resource.testVersionViaConfig.json", result); } finally { System.clearProperty(VERSION_PROPERTY); } } - private InputStream loadStaticFile() { + @Test + void testJavaxSetting30ViaConfig() throws IOException, JSONException { + testSetting30ViaConfig( + test.io.smallrye.openapi.runtime.scanner.resources.javax.GreetingGetResource.class, Greeting.class, + Schema31Changes.class); + } + + @Test + void testJakartaSetting30ViaConfig() throws IOException, JSONException { + testSetting30ViaConfig( + test.io.smallrye.openapi.runtime.scanner.resources.jakarta.GreetingGetResource.class, Greeting.class, + Schema31Changes.class); + } + + void testSetting30ViaConfig(Class... classes) throws JSONException, IOException { + //The test will pass if this version matches the one in the file of expected JSON (resource.testVersionViaConfig.json) and the file read by loadStaticFile() (version.json) is overriden. + System.setProperty(VERSION_PROPERTY, "3.0.3"); + + try { + OpenAPI result = scan(config(Collections.emptyMap()), true, null, classes); + assertJsonEquals("resource.testVersion30ViaConfig.json", result); + } finally { + System.clearProperty(VERSION_PROPERTY); + } + + } + + private InputStream loadStaticFile(String fileName) { ClassLoader classLoader = this.getClass().getClassLoader(); - InputStream versionJson = classLoader.getResourceAsStream("io/smallrye/openapi/runtime/scanner/static/version.json"); + InputStream versionJson = classLoader.getResourceAsStream("io/smallrye/openapi/runtime/scanner/static/" + fileName); return versionJson; } diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/entities/Schema31Changes.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/entities/Schema31Changes.java new file mode 100644 index 000000000..feed7d7fc --- /dev/null +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/entities/Schema31Changes.java @@ -0,0 +1,26 @@ +package test.io.smallrye.openapi.runtime.scanner.entities; + +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +@Schema(name = "Schema31Changes") +public class Schema31Changes { + + @Schema(nullable = true) + private String nullableString; + + @Schema(minimum = "4", maximum = "10", exclusiveMinimum = true, exclusiveMaximum = true) + private int rangedInt; + + public Schema31Changes(String nullableString, int rangedInt) { + this.nullableString = nullableString; + this.rangedInt = rangedInt; + } + + public String getNullableString() { + return nullableString; + } + + public int getRangedInt() { + return rangedInt; + } +} diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/jakarta/RequestBodyTestApplication.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/jakarta/RequestBodyTestApplication.java index c87f0ded2..ddedc498f 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/jakarta/RequestBodyTestApplication.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/jakarta/RequestBodyTestApplication.java @@ -23,7 +23,10 @@ * * @author Michael Edgar {@literal } */ -@OpenAPIDefinition(info = @Info(title = "Test Request Body", version = "1.0"), components = @Components(requestBodies = @RequestBody(name = "test", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = true))) +@OpenAPIDefinition(info = @Info(title = "Test Request Body", version = "1.0"), components = @Components(requestBodies = { + @RequestBody(name = "test", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = true), + @RequestBody(name = "testRequiredDefault", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class))), + @RequestBody(name = "testNotRequired", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = false) })) public class RequestBodyTestApplication extends Application { public static class SomeObject { @@ -56,7 +59,7 @@ public void testRef(@RequestBody(ref = "test") SomeObject body) { @POST @Consumes(MediaType.APPLICATION_JSON) @Path("defaults") - public void testDefaults(@RequestBody(required = true) SomeObject body) { + public void testDefaults(@RequestBody SomeObject body) { return; } @@ -66,5 +69,12 @@ public void testDefaults(@RequestBody(required = true) SomeObject body) { public void testAny(SomeObject body) { return; } + + @POST + @Path("notRequired") + @Consumes(MediaType.APPLICATION_JSON) + public void testNotRequired(@RequestBody(required = false) SomeObject body) { + return; + } } } diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/javax/RequestBodyTestApplication.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/javax/RequestBodyTestApplication.java index 1ab665166..c807c5181 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/javax/RequestBodyTestApplication.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/javax/RequestBodyTestApplication.java @@ -23,7 +23,10 @@ * * @author Michael Edgar {@literal } */ -@OpenAPIDefinition(info = @Info(title = "Test Request Body", version = "1.0"), components = @Components(requestBodies = @RequestBody(name = "test", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = true))) +@OpenAPIDefinition(info = @Info(title = "Test Request Body", version = "1.0"), components = @Components(requestBodies = { + @RequestBody(name = "test", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = true), + @RequestBody(name = "testRequiredDefault", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class))), + @RequestBody(name = "testNotRequired", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = DifferentObject.class)), required = false) })) public class RequestBodyTestApplication extends Application { public static class SomeObject { @@ -56,7 +59,7 @@ public void testRef(@RequestBody(ref = "test") SomeObject body) { @POST @Consumes(MediaType.APPLICATION_JSON) @Path("defaults") - public void testDefaults(@RequestBody(required = true) SomeObject body) { + public void testDefaults(@RequestBody SomeObject body) { return; } @@ -66,5 +69,12 @@ public void testDefaults(@RequestBody(required = true) SomeObject body) { public void testAny(SomeObject body) { return; } + + @POST + @Path("notRequired") + @Consumes(MediaType.APPLICATION_JSON) + public void testNotRequired(@RequestBody(required = false) SomeObject body) { + return; + } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/_expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/_expected.json index 47829d47d..90ee213f6 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/_expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/_expected.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Updated API Title", "description": "This is a sample server for a pet store.", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/static.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/static.json index dc99314ab..d4db8f466 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/static.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_filtered/static.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_modelReader/_expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_modelReader/_expected.json deleted file mode 100644 index 9a6f2b3a1..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_modelReader/_expected.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "openapi": "3.0.1", - "info": { - "title": "Model Reader API", - "description": "This is an API created by the Model Reader.", - "contact": { - "name": "API Support", - "url": "http://www.example.com/support", - "email": "support@example.com" - }, - "version": "1.17" - }, - "paths": {} -} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/_expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/_expected.json index dc99314ab..d4db8f466 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/_expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/_expected.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/static.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/static.json index dc99314ab..d4db8f466 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/static.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/_static/static.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Sample Pet Store App", "description": "This is a sample server for a pet store.", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/callback.reference-component-callback.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/callback.reference-component-callback.json index e77a9e6b2..0440d912a 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/callback.reference-component-callback.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/callback.reference-component-callback.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Greetings", "version" : "0.0.1" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/resource.testBeanValidationDocument.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/resource.testBeanValidationDocument.json index 4e5e769e0..0748bed27 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/resource.testBeanValidationDocument.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/resource.testBeanValidationDocument.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "tags": [ { "name": "Test", @@ -13,6 +13,7 @@ "Test" ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -52,32 +53,28 @@ ], "properties": { "string_no_bean_constraints": { - "type": "string", + "type": ["string", "null"], "minLength": 10, - "maxLength": 101, - "nullable": true + "maxLength": 101 }, "big_int_no_bean_constraints": { - "type": "integer", + "type": ["integer", "null"], "minimum": 101, "maximum": 101.999, - "nullable": true, "pattern": "^\\d{1,3}([.]\\d{1,3})?$" }, "list_no_bean_constraints": { - "type": "array", + "type": ["array", "null"], "minItems": 0, "maxItems": 100, - "nullable": true, "items": { "type": "string" } }, "map_no_bean_constraints": { - "type": "object", + "type": ["object", "null"], "minProperties": 0, "maxProperties": 100, - "nullable": true, "additionalProperties": { "type": "string" } @@ -123,8 +120,7 @@ }, "decimalMaxBigDecimalExclusiveDigits": { "type": "number", - "maximum": 201.0, - "exclusiveMaximum": true, + "exclusiveMaximum": 201.0, "pattern": "^\\d{1,3}([.]\\d)?$" }, "decimalMaxBigDecimalInclusive": { @@ -144,8 +140,7 @@ }, "decimalMinBigDecimalExclusiveDigits": { "type": "number", - "minimum": 9, - "exclusiveMinimum": true, + "exclusiveMinimum": 9, "pattern": "^\\d([.]\\d{1,2})?$" }, "decimalMinBigDecimalInclusive": { @@ -165,8 +160,7 @@ "integerNegativeNotZeroMinValue": { "type": "integer", "format": "int64", - "maximum": 0, - "exclusiveMaximum": true, + "exclusiveMaximum": 0, "minimum": -1000000 }, "integerNegativeOrZeroMinValue": { @@ -179,8 +173,7 @@ "type": "integer", "format": "int64", "maximum": 1000, - "minimum": 0, - "exclusiveMinimum": true + "exclusiveMinimum": 0 }, "integerPositiveOrZeroMaxValue": { "type": "integer", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/schema.inherited-bv-constraints.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/schema.inherited-bv-constraints.json index 126bc7ac7..ea28a3792 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/schema.inherited-bv-constraints.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/dataobject/schema.inherited-bv-constraints.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "UserImpl": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/default.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/default.json index 64da88cda..c4cc075ba 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/default.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/default.json @@ -1,3 +1,3 @@ { - "openapi" : "3.0.3" + "openapi" : "3.1.0" } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.parsing.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.parsing.expected.json index 29efcd4d6..e64921780 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.parsing.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.parsing.expected.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/ext": { "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.scan-siblings.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.scan-siblings.expected.json index 00422820f..980f00c20 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.scan-siblings.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/extensions.scan-siblings.expected.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/ext/segment1": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.complexNesting.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.complexNesting.expected.json index 001579b9a..fbf7e222a 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.complexNesting.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.complexNesting.expected.json @@ -30,18 +30,18 @@ "qAgain" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qAgain3" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qValue" : { "format" : "date", "description" : "Ah, Q, my favourite variable!", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "tAgain2" : { "type" : "string" @@ -69,18 +69,18 @@ "qAgain" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qAgain3" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qValue" : { "format" : "date", "description" : "Ah, Q, my favourite variable!", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "tAgain2" : { "type" : "string" @@ -108,18 +108,18 @@ "qAgain" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qAgain3" : { "format" : "date", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qValue" : { "format" : "date", "description" : "Ah, Q, my favourite variable!", "type" : "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "tAgain2" : { "type" : "string" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.fields.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.fields.expected.json index 58409f424..e9445b2c4 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.fields.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/generic.fields.expected.json @@ -9,13 +9,13 @@ "items" : { "format" : "date-time", "type" : "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] } }, "genericFieldK" : { "format" : "date-time", "type" : "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] }, "mapOfKToFoo" : { "type" : "object", @@ -48,7 +48,7 @@ "additionalProperties" : { "format" : "date-time", "type" : "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/hidden.components.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/hidden.components.json index 2bdd57bc0..f89514ec2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/hidden.components.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/hidden.components.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/fruits" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.all-the-params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.all-the-params.json index 5947671f3..78129abca 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.all-the-params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.all-the-params.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/all/the/params/{id1}/{id2}{id2Matrix}": { "parameters": [ @@ -101,6 +101,7 @@ } ], "requestBody": { + "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.annotation-preferred-order.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.annotation-preferred-order.json index 2f666257b..ccb229c0e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.annotation-preferred-order.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.annotation-preferred-order.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Parameter Order", "version": "1.0.0" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.beanparam-multipartform-inherited.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.beanparam-multipartform-inherited.json index 4246cce0e..a1fb6b67a 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.beanparam-multipartform-inherited.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.beanparam-multipartform-inherited.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/beanparambase": { "get": { @@ -61,6 +61,7 @@ "/uploadIcon": { "post": { "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { @@ -91,6 +92,7 @@ "/uploadIcon/reactive": { "post": { "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.char-sequence-arrays.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.char-sequence-arrays.json index 2a757406c..6df8c8d6b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.char-sequence-arrays.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.char-sequence-arrays.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/char/sequence": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.common-annotation-target-method.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.common-annotation-target-method.json index f0d2c8389..ef7e60779 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.common-annotation-target-method.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.common-annotation-target-method.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/common-target-method": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.enum-form-param.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.enum-form-param.json index db6e47b45..5cfd032d7 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.enum-form-param.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.enum-form-param.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/enum/formparam": { "post": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.generic-type-variables.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.generic-type-variables.json index 10f7907aa..0c8983915 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.generic-type-variables.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.generic-type-variables.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/integer-string/map": { "get": { @@ -34,6 +34,7 @@ } ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.ignored-mp-openapi-headers.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.ignored-mp-openapi-headers.json index 8c2df0442..915a1ac6d 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.ignored-mp-openapi-headers.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.ignored-mp-openapi-headers.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/ignored-headers": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.local-schema-attributes.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.local-schema-attributes.json index 3d2e895d7..198fca0ff 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.local-schema-attributes.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.local-schema-attributes.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/enum-default-param": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-method-and-field-args.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-method-and-field-args.json index c5b4b0169..08edbffb1 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-method-and-field-args.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-method-and-field-args.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/matrix-params-on-method-and-field-args/{id}{idMatrix}/seg1/seg2/resourceA{resourceA}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-args.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-args.json index 377262ee9..abaa0a106 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-args.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-args.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/matrix-params-on-resource-method-args/{id}/anotherpathsegment/reloaded{reloaded}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-custom-name.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-custom-name.json index 051141220..a6f06ef0d 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-custom-name.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.matrix-params-on-resource-method-custom-name.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/matrix-params-on-resource-method-custom-name/{id}{idMatrix}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json index 4ead02b34..7ca517677 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/policies": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multipart-form.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multipart-form.json index 933181d7e..df5cea207 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multipart-form.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multipart-form.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart/{id1}/{id2}": { "parameters": [ @@ -23,6 +23,7 @@ ], "post": { "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multiple-content-types-with-form-params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multiple-content-types-with-form-params.json index cdbd1dfe2..1c5acb0a2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multiple-content-types-with-form-params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.multiple-content-types-with-form-params.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multiple-content-types-with-form-params/widgets/create": { "post": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.optional-types.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.optional-types.json index 8c834fe48..0a94e0571 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.optional-types.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.optional-types.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/optional/n1": { "get": { @@ -71,8 +71,7 @@ "content": { "text/plain": { "schema": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } @@ -83,14 +82,14 @@ "/optional/n4": { "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { "type": "object", "properties": { "name4": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } @@ -140,8 +139,7 @@ "content": { "text/plain": { "schema": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } @@ -176,8 +174,7 @@ "content": { "text/plain": { "schema": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } @@ -229,8 +226,7 @@ "content": { "text/plain": { "schema": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } @@ -272,8 +268,7 @@ "required": [ "title" ], "properties": { "title": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } }, @@ -282,19 +277,18 @@ "properties": { "age": { "format": "double", - "type": "number", - "nullable": true + "type": ["number", "null"] }, "name": { - "type": "string", - "nullable": true + "type": ["string", "null"] }, "nested": { - "type": "object", - "nullable": true, - "allOf": [ + "anyOf": [ { "$ref": "#/components/schemas/NestedBean" + }, + { + "type": "null" } ] } @@ -304,8 +298,7 @@ "type": "object", "properties": { "value": { - "type": "string", - "nullable": true + "type": ["string", "null"] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.param-name-override.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.param-name-override.json index 4155a9305..c1a8bfcd3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.param-name-override.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.param-name-override.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/override/{p1}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-field.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-field.json index 7555101dc..0fdacbec0 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-field.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-field.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/parameter-in-bean-from-field/{id}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-setter.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-setter.json index 5ce98f24e..611d267b4 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-setter.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-in-bean-from-setter.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/parameter-in-bean-from-setter/{id}/{id2}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-field.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-field.json index 37227ad29..0c06c65d0 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-field.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-field.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/parameter-on-field/{id}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-method.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-method.json index 1ca86d4d7..4c1ec93b3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-method.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-on-method.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/parameter-on-method/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-ref-property.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-ref-property.json index 5142fc0c2..63f6a6d06 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-ref-property.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameter-ref-property.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "title", "version": "1" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameters-in-constructor.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameters-in-constructor.json index bcebba21a..cb58ce2eb 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameters-in-constructor.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.parameters-in-constructor.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/parameters-in-constructor/{id}/{p1}": { "parameters": [ diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-templates.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-templates.json index 024902eed..b71e2b47e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-templates.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-templates.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/template/{id}/{name}/{nickname}/{age}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-with-form-params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-with-form-params.json index 812035f4a..a307afa67 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-with-form-params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-param-with-form-params.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/path-param-with-form-params/{id}": { "parameters": [ @@ -17,6 +17,7 @@ ], "post": { "requestBody": { + "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-segment-param.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-segment-param.json index 8c2f06103..2a4f152c2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-segment-param.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.path-segment-param.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/segments{segments}/seg1": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.request-body-constraints.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.request-body-constraints.json index 51a96183f..7a3594004 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.request-body-constraints.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.request-body-constraints.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/bars": { "post": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-fields-and-setters.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-fields-and-setters.json index 27d13e361..4c0523d19 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-fields-and-setters.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-fields-and-setters.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/test{test}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-input.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-input.json index 5911f0c00..038749605 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-input.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-input.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart-form-data-input/post": { "post": { "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-map.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-map.json index 977057f82..7b6a7b8f9 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-map.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-form-data-map.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart-form-data-map/post": { "post": { "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed-array.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed-array.json index 20c538b06..3cd3d1061 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed-array.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed-array.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart-mixed-array/post": { "post": { "requestBody": { + "required": true, "content": { "multipart/mixed": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed.json index d0cd49ba6..2a294bd20 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-mixed.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart-mixed/post": { "post": { "requestBody": { + "required": true, "content": { "multipart/mixed": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-related-input.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-related-input.json index 6ceca00cb..7cdbbe229 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-related-input.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-multipart-related-input.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multipart-related-input/post/{id}": { "post": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-reactive-missing-restpath.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-reactive-missing-restpath.json index f91e3574b..54fab5061 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-reactive-missing-restpath.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.resteasy-reactive-missing-restpath.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/movies/{id2}" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.serialized-annotation-index.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.serialized-annotation-index.json index 4f0d8d96e..23a585d71 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.serialized-annotation-index.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.serialized-annotation-index.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/greet/{name}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.synthetic-methods-not-included.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.synthetic-methods-not-included.json index 346cd2af9..edc349bdb 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.synthetic-methods-not-included.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.synthetic-methods-not-included.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "tags": [ { "name": "reproducers", @@ -44,6 +44,7 @@ ], "summary": "create", "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.uuid-params-responses.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.uuid-params-responses.json index 50749da34..2e284bc41 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.uuid-params-responses.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.uuid-params-responses.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/uuid": { "get": { @@ -30,6 +30,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { @@ -61,11 +62,7 @@ "theUUID": { "type": "string", "description": "test", - "allOf": [ - { - "$ref": "#/components/schemas/UUID" - } - ] + "$ref": "#/components/schemas/UUID" } } }, diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.value-class-pathparam.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.value-class-pathparam.json index ffcd85859..05106614d 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.value-class-pathparam.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.value-class-pathparam.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/fruits/{fruitId}" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-empty-mapping.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-empty-mapping.json index 2018bc01c..efdb74200 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-empty-mapping.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-empty-mapping.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-key.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-key.json index 6a9a7e5a5..f55f097dc 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-key.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-key.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-schema.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-schema.json index d4046dabb..591dab4cc 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-schema.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping-schema.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping.json index c44ed6a9b..5bfc49f65 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-mapping.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-property-name.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-property-name.json index 43a84e12f..e8920905e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-property-name.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator-no-property-name.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator.json index 84b18e5ef..39757b2bd 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/polymorphism.declared-discriminator.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.duration.fields.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.duration.fields.expected.json index 44a68ad31..ad5eae2b2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.duration.fields.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.duration.fields.expected.json @@ -35,13 +35,13 @@ "items": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] } }, "genericFieldK": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] }, "mapOfKToFoo": { "type": "object", @@ -54,7 +54,7 @@ "additionalProperties": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.complexNesting.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.complexNesting.expected.json index 464717dfd..a283ee5c5 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.complexNesting.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.complexNesting.expected.json @@ -13,11 +13,7 @@ "foo": { "type": "object", "maxLength": 123456, - "allOf": [ - { - "$ref": "#/components/schemas/FuzzStringDate" - } - ] + "$ref": "#/components/schemas/FuzzStringDate" } } }, @@ -27,18 +23,18 @@ "qAgain": { "format": "date", "type": "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qAgain3": { "format": "date", "type": "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "qValue": { "format": "date", "description": "Ah, Q, my favourite variable!", "type": "string", - "example": "2022-03-10" + "examples" : [ "2022-03-10" ] }, "tAgain2": { "type": "string" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.fields.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.fields.expected.json index 96e91aee4..0dcd53f44 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.fields.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.fields.expected.json @@ -35,13 +35,13 @@ "items": { "format": "date-time", "type": "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] } }, "genericFieldK": { "format": "date-time", "type": "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] }, "mapOfKToFoo": { "type": "object", @@ -54,7 +54,7 @@ "additionalProperties": { "format": "date-time", "type": "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.nested.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.nested.expected.json index cb9bdf73d..dee61cf4b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.nested.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.generic.nested.expected.json @@ -31,11 +31,7 @@ "foo": { "type": "object", "maxLength": 123456, - "allOf": [ - { - "$ref": "#/components/schemas/KustomPairStringString" - } - ] + "$ref": "#/components/schemas/KustomPairStringString" } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.kitchenSink.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.kitchenSink.expected.json index f2b3df8c2..d5f55cd1a 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.kitchenSink.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.kitchenSink.expected.json @@ -40,11 +40,11 @@ "properties": { "contactPhone": { "type": "string", - "example": "1-888-1234-567" + "examples" : [ "1-888-1234-567" ] }, "name": { "type": "string", - "example": "Acme Air" + "examples" : [ "Acme Air" ] } }, "additionalProperties": true @@ -66,28 +66,28 @@ }, "airportFrom": { "type": "string", - "example": "YYZ" + "examples" : [ "YYZ" ] }, "airportTo": { "type": "string", - "example": "LAX" + "examples" : [ "LAX" ] }, "dateTime": { "pattern": "dateTime", "type": "string", - "example": "2016-03-05 18:00" + "examples" : [ "2016-03-05 18:00" ] }, "number": { "type": "string", - "example": "AC190" + "examples" : [ "AC190" ] }, "price": { "type": "string", - "example": "US$350" + "examples" : [ "US$350" ] }, "status": { "type": "string", - "example": "On Schedule" + "examples" : [ "On Schedule" ] } }, "additionalProperties": { @@ -106,23 +106,23 @@ "properties": { "cardNumber": { "type": "string", - "example": "**********1234" + "examples" : [ "**********1234" ] }, "cardholderName": { "type": "string", - "example": "Joe Smith" + "examples" : [ "Joe Smith" ] }, "cvv": { "type": "string", - "example": "0322" + "examples" : [ "0322" ] }, "expiryDate": { "type": "string", - "example": "04/19" + "examples" : [ "04/19" ] }, "issuer": { "type": "string", - "example": "VISA" + "examples" : [ "VISA" ] } }, "additionalProperties": false @@ -139,7 +139,7 @@ "properties": { "airMiles": { "type": "string", - "example": "32126319" + "examples" : [ "32126319" ] }, "creditCard": { "$ref": "#/components/schemas/CreditCard" @@ -152,7 +152,7 @@ }, "seatPreference": { "type": "string", - "example": "window" + "examples" : [ "window" ] } } }, @@ -219,11 +219,7 @@ "foo": { "type": "object", "maxLength": 123456, - "allOf": [ - { - "$ref": "#/components/schemas/FuzzStringObject" - } - ] + "$ref": "#/components/schemas/FuzzStringObject" } } }, @@ -280,11 +276,7 @@ "qValue": { "type": "object", "description": "Ah, Q, my favourite variable!", - "allOf": [ - { - "$ref": "#/components/schemas/FooExtendsFoo" - } - ] + "$ref": "#/components/schemas/FooExtendsFoo" }, "tAgain2": { "type": "string" @@ -327,11 +319,7 @@ "foo": { "type": "object", "maxLength": 123456, - "allOf": [ - { - "$ref": "#/components/schemas/KustomPairStringString" - } - ] + "$ref": "#/components/schemas/KustomPairStringString" } } }, @@ -502,7 +490,7 @@ "seatPreference": { "maxLength": 999, "type": "string", - "example": "window" + "examples" : [ "window" ] }, "simpleParameterizedType": { "$ref": "#/components/schemas/KustomPairStringInteger" @@ -532,7 +520,7 @@ } } }, - "example": "This is the KitchenSink example field in Schema", + "examples" : [ "This is the KitchenSink example field in Schema" ], "deprecated": true } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.period.fields.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.period.fields.expected.json index 4c40e1931..053f122f3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.period.fields.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.period.fields.expected.json @@ -35,13 +35,13 @@ "items": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] } }, "genericFieldK": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] }, "mapOfKToFoo": { "type": "object", @@ -54,7 +54,7 @@ "additionalProperties": { "format": "duration", "type": "string", - "example" : "P1D" + "examples" : [ "P1D" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.simple.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.simple.expected.json index 0f10488f7..a324de028 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.simple.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.simple.expected.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/foo": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.testNestedSchemaOnParameter.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.testNestedSchemaOnParameter.json index eb0f9e2c5..053a59d01 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.testNestedSchemaOnParameter.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/refsEnabled.resource.testNestedSchemaOnParameter.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/nested": { "post": { @@ -49,11 +49,7 @@ "another_child": { "type": "object", "description": "This schema will be unioned to $ref to 'another_nested', name will be used for the property, and this description will be present on this property", - "allOf": [ - { - "$ref": "#/components/schemas/another_nested" - } - ] + "$ref": "#/components/schemas/another_nested" }, "childList": { "type": "array", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.array-item-ref.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.array-item-ref.json index 6caf84eb4..9a5012455 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.array-item-ref.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.array-item-ref.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/v1/generics": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.overwritten.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.overwritten.json index 4016242e8..c27e1d9ff 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.overwritten.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.overwritten.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/overwritten-resource-path" : { "get" : { @@ -22,6 +22,7 @@ }, "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -49,6 +50,7 @@ }, "delete" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.unannotated.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.unannotated.json index 70dadb769..7d28bb275 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.unannotated.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.class.path.unannotated.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/overwritten-resource-path" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.concrete-implementation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.concrete-implementation.json index 12d0c1193..aa45570f2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.concrete-implementation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.concrete-implementation.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/concrete": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types-wo-array-refs.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types-wo-array-refs.json index 872b026bb..9b1247e5f 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types-wo-array-refs.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types-wo-array-refs.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "API - Service", "version" : "V1" @@ -59,6 +59,7 @@ }, "put" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -82,6 +83,7 @@ }, "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -105,6 +107,7 @@ }, "delete" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -183,6 +186,7 @@ }, "put" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -206,6 +210,7 @@ }, "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -229,6 +234,7 @@ }, "delete" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -291,6 +297,7 @@ }, "put" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -314,6 +321,7 @@ }, "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -337,6 +345,7 @@ }, "delete" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types.json index 7933fc9b8..34678ba01 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.generic-model-types.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "API - Service", "version": "V1" @@ -68,6 +68,7 @@ }, "put": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -91,6 +92,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -114,6 +116,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -197,6 +200,7 @@ }, "put": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -220,6 +224,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -243,6 +248,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -310,6 +316,7 @@ }, "put": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -333,6 +340,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -356,6 +364,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.param-default-values.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.param-default-values.json index 4565d69bd..fbe7faa96 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.param-default-values.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.param-default-values.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/1/alpha": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.params.json index 166836a23..4e9201af4 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.inheritance.params.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/hello/speak": { "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { @@ -29,6 +30,7 @@ "/hi/speak": { "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { @@ -61,7 +63,7 @@ "$ref" : "#/components/schemas/LocalDate" }, "allowEmptyValue": false, - "example": "2019-12-31" + "example" : "2019-12-31" } ], "get": { @@ -115,11 +117,12 @@ "$ref" : "#/components/schemas/LocalDate" }, "allowEmptyValue": false, - "example": "2019-12-31" + "example" : "2019-12-31" } ], "post": { "requestBody": { + "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { @@ -186,6 +189,7 @@ ], "post": { "requestBody": { + "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { @@ -219,7 +223,7 @@ "LocalDate" : { "format" : "date", "type" : "string", - "example" : "2022-03-10" + "examples" : [ "2022-03-10" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-inheritance.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-inheritance.json index 5842a3a69..7438d7f0b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-inheritance.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-inheritance.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/fruits": { "get": { @@ -72,7 +72,7 @@ "format": "date-time", "description": "When the entity was modified as a Unix timestamp.", "type": "string", - "example": "0" + "examples" : [ "0" ] }, "modifier": { "format": "uuid", @@ -86,7 +86,7 @@ "format": "date-time", "description": "When the entity was created as a Unix timestamp. For create operations, this will not need to be defined.", "type": "string", - "example": "0" + "examples" : [ "0" ] }, "creator": { "format": "uuid", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-only.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-only.json index 5ab69b103..b01c43e46 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-only.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.interface-only.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/noimpl": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-param.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-param.json index 965f0baa0..48f1d964b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-param.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-param.json @@ -1,10 +1,11 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/v1": { "post": { "summary": "Convert an array of doubles to an array of floats", "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-polymorphism.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-polymorphism.json index cd8763bfe..16ad22990 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-polymorphism.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-polymorphism.json @@ -1,10 +1,11 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/v1": { "post": { "summary": "Convert an array of integer types to an array of floating point types", "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-schema.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-schema.json index 0d7bfcb75..478c1bf27 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-schema.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.primitive-array-schema.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/v1": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.simpleSchema.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.simpleSchema.json index 985a38bde..a664347e7 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.simpleSchema.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.simpleSchema.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/params/{taskId}/unnamed": { "delete": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.string-implementation-wrapped.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.string-implementation-wrapped.json index f46f3477e..1c42ca0e8 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.string-implementation-wrapped.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.string-implementation-wrapped.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/hello": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -28,11 +29,7 @@ "message": { "type": "string", "description": "Used to send a message", - "allOf": [ - { - "$ref": "#/components/schemas/SimpleString" - } - ] + "$ref": "#/components/schemas/SimpleString" }, "optionalMessage": { "type": "string", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.time.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.time.json index 681ee8935..16196e83f 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.time.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.time.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/times/local": { "get": { @@ -98,7 +98,7 @@ "description": "As defined by 'partial-time' in RFC3339", "url": "https://www.rfc-editor.org/rfc/rfc3339.html#section-5.6" }, - "example": "13:45:30.123456789" + "examples" : [ "13:45:30.123456789" ] }, "OffsetTime": { "type": "string", @@ -107,7 +107,7 @@ "description": "As defined by 'full-time' in RFC3339", "url": "https://www.rfc-editor.org/rfc/rfc3339.html#section-5.6" }, - "example": "13:45:30.123456789+02:00" + "examples" : [ "13:45:30.123456789+02:00" ] }, "UTC": { "type": "object", @@ -115,11 +115,7 @@ "utc": { "type": "string", "description": "Current time at offset '00:00'", - "allOf": [ - { - "$ref": "#/components/schemas/OffsetTime" - } - ] + "$ref": "#/components/schemas/OffsetTime" } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.type-variable.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.type-variable.json index 70b2f7870..92d020812 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.type-variable.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.parameters.type-variable.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/variable-types": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresource-tag-placement-priority.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresource-tag-placement-priority.json index 0cacb5c91..4f47f36d5 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresource-tag-placement-priority.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresource-tag-placement-priority.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "tags" : [ { "name" : "root-a2-tag" }, { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json index 144acf298..440598f28 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/recursion/alternate1/alternate2/fetch": { "get": { @@ -107,6 +107,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -126,6 +127,7 @@ }, "patch": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { @@ -351,7 +353,7 @@ "LocalDateTime": { "format": "date-time", "type": "string", - "example": "2022-03-10T12:15:50" + "examples" : [ "2022-03-10T12:15:50" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.inherited.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.inherited.json index a0eda6f26..e4010239d 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.inherited.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.inherited.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "tags" : [ { "name" : "foobar", "description" : "baz" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.multilocation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.multilocation.json index ffbb2de48..03595a263 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.multilocation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.multilocation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "tags" : [ { "name" : "tag1", "description" : "TAG1 from TagTestResource2" @@ -30,6 +30,7 @@ "post" : { "tags" : [ "tag1" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -46,6 +47,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -80,6 +82,7 @@ "post" : { "tags" : [ "tag1", "http://example/com/tag2" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -96,6 +99,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.annotation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.annotation.json index e6d305d0b..c6a605631 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.annotation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.annotation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info": { "title" : "Testing user-specified tag order", "version" : "1.0.0" @@ -34,6 +34,7 @@ "post" : { "tags" : [ "tag1" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -50,6 +51,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -84,6 +86,7 @@ "post" : { "tags" : [ "tag1", "http://example/com/tag2" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -100,6 +103,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.staticfile.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.staticfile.json index 1ae7d500c..478789ed3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.staticfile.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.tags.ordergiven.staticfile.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info": { "title" : "Tag order in static file", "version" : "1.0.0-static" @@ -34,6 +34,7 @@ "post" : { "tags" : [ "tag1" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -50,6 +51,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -84,6 +86,7 @@ "post" : { "tags" : [ "tag1", "http://example/com/tag2" ], "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { @@ -100,6 +103,7 @@ }, "patch" : { "requestBody" : { + "required": true, "content" : { "text/plain" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testAllInfoViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testAllInfoViaConfig.json index de1e7b2c2..32aea4672 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testAllInfoViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testAllInfoViaConfig.json @@ -1,9 +1,10 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "My own awesome REST service", "description" : "This service is awesome", "termsOfService" : "The terms is also awesome", + "summary" : "This summary is rather boring", "contact" : { "name" : "Phillip Kruger", "url" : "https://www.phillip-kruger.com", @@ -32,7 +33,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } @@ -175,4 +183,4 @@ } } } -} \ No newline at end of file +} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsDeleteDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsDeleteDefinitionScanning.json index fd74ede86..9ddddd79b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsDeleteDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsDeleteDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "delete" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsGetDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsGetDefinitionScanning.json index 193427421..11bef419e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsGetDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsGetDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/helloOptional/{name}" : { "get" : { @@ -17,7 +17,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPostDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPostDefinitionScanning.json index 86fdcd0c6..a3e51eae1 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPostDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPostDefinitionScanning.json @@ -1,9 +1,10 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -29,6 +30,7 @@ "/greeting/greetWithResponse" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -54,6 +56,7 @@ "/greeting/greetWithResponseTyped" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPutDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPutDefinitionScanning.json index b9f2feb69..aee6558c8 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPutDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxRsPutDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "put" : { @@ -12,6 +12,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -45,6 +46,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -78,6 +80,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxbJaxRsGetDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxbJaxRsGetDefinitionScanning.json index fc0320fa7..c14273a0c 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxbJaxRsGetDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicJaxbJaxRsGetDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/helloPathVariable1/{name}" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testContactEmailViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testContactEmailViaConfig.json index f60f172fb..921b12ed3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testContactEmailViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testContactEmailViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0", @@ -24,7 +24,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testCsvConsumesProduces.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testCsvConsumesProduces.json index 71e43988e..235958777 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testCsvConsumesProduces.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testCsvConsumesProduces.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/multi-produce-consume": { "get": { @@ -17,6 +17,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "text/plain": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeConfigured.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeConfigured.json index 42f30812e..87a29db55 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeConfigured.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeConfigured.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -38,6 +38,7 @@ }, "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -103,8 +104,7 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string", - "nullable" : true + "type" : ["string", "null" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeVanilla.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeVanilla.json index fd6947b20..6d5367157 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeVanilla.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testDefaultContentTypeVanilla.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -94,8 +94,7 @@ "content" : { "*/*" : { "schema" : { - "type" : "string", - "nullable" : true + "type" : [ "string", "null" ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testEmptySecurityRequirements.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testEmptySecurityRequirements.json index 5f414ff03..b8e12eb57 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testEmptySecurityRequirements.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testEmptySecurityRequirements.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/public": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationNotPresent.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationNotPresent.json index 9ea8bcd02..fe3cc252b 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationNotPresent.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationNotPresent.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/public": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationPathNotPresent.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationPathNotPresent.json index 2536ec6f2..492ff4541 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationPathNotPresent.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testHiddenOperationPathNotPresent.json @@ -1 +1 @@ -{ "openapi": "3.0.3" } +{ "openapi": "3.1.0" } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testInvalidSchemaKeyDefinitionViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testInvalidSchemaKeyDefinitionViaConfig.json index 470561597..d7f4a3186 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testInvalidSchemaKeyDefinitionViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testInvalidSchemaKeyDefinitionViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testLicenseNameViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testLicenseNameViaConfig.json index a527a237c..060eeccee 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testLicenseNameViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testLicenseNameViaConfig.json @@ -1,10 +1,11 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0", "license" : { - "name" : "Apache License 2.0" + "name" : "Apache License 2.0", + "identifier" : "Apache-2.0" } }, "paths" : { @@ -24,7 +25,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdClassMethod.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdClassMethod.json index 63e3bc3be..62fd76dd2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdClassMethod.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdClassMethod.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -22,7 +22,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf" : [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethod.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethod.json index 413c2d4b5..02dd986b3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethod.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethod.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -22,7 +22,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf" : [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethodWithOperation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethodWithOperation.json index aa3808768..233db6b13 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethodWithOperation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdMethodWithOperation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdPackageClassMethod.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdPackageClassMethod.json index 2bdcd168c..e016efff1 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdPackageClassMethod.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdPackageClassMethod.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -22,7 +22,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf" : [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdWithInheritance.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdWithInheritance.json index 94968630e..78064ea9f 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdWithInheritance.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testOperationIdWithInheritance.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Generated API", "version": "1.0" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testPackageInfoDefinitionScanning.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testPackageInfoDefinitionScanning.json index 8f5f8e073..42a471be3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testPackageInfoDefinitionScanning.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testPackageInfoDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Title from the application", "description": "Description from the package", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testRequestBodyComponentGeneration.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testRequestBodyComponentGeneration.json index 95f07705b..57599d2a5 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testRequestBodyComponentGeneration.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testRequestBodyComponentGeneration.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Test Request Body", "version": "1.0" @@ -39,6 +39,7 @@ "/requestbodies/any": { "post": { "requestBody": { + "required": true, "content": { "*/*": { "schema": { @@ -72,7 +73,27 @@ } } } + }, + "/requestbodies/notRequired": { + "post": { + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SomeObject" + } + } + } + }, + "responses": { + "201": { + "description": "Created" + } + } + } } + }, "components": { "schemas": { @@ -114,6 +135,26 @@ } }, "required": true + }, + "testRequiredDefault": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DifferentObject" + } + } + }, + "required": true + }, + "testNotRequired": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DifferentObject" + } + } + }, + "required": false } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testTitleViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testTitleViaConfig.json index 5959a250a..dd2e48482 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testTitleViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testTitleViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "My Awesome Service", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaDefinitionViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaDefinitionViaConfig.json index 00872d92f..03258011e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaDefinitionViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaDefinitionViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaJSONValueViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaJSONValueViaConfig.json index 3b4bad48f..b707634ba 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaJSONValueViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaJSONValueViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithUnknownSchemaPropertyValueViaConfig.json similarity index 91% rename from extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig.json rename to extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithUnknownSchemaPropertyValueViaConfig.json index 9794e2fc7..dd4fe49b3 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithInvalidSchemaPropertyValueViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testValidSchemaKeyWithUnknownSchemaPropertyValueViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } @@ -155,7 +162,8 @@ "components" : { "schemas" : { "message" : { - "type" : "string" + "type" : "string", + "unknown-property" : "This should appear in output document" }, "Greeting" : { "type" : "object", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersion30ViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersion30ViaConfig.json new file mode 100644 index 000000000..b7ba2256e --- /dev/null +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersion30ViaConfig.json @@ -0,0 +1,189 @@ +{ + "openapi" : "3.0.3", + "info" : { + "title" : "Generated API", + "version" : "1.0" + }, + "paths" : { + "/greeting/helloOptional/{name}" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "nullable": true, + "allOf": [ + { + "$ref" : "#/components/schemas/Greeting" + } + ] + } + } + } + } + } + } + }, + "/greeting/helloPathVariable/{name}" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + } + } + } + }, + "/greeting/helloPathVariableWithResponse/{name}" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + } + } + } + }, + "/greeting/helloPathVariableWithResponseTyped/{name}" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + } + } + } + }, + "/greeting/helloRequestParam" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + } + } + } + }, + "/greeting/hellosPathVariable/{name}" : { + "get" : { + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Greeting" : { + "type" : "object", + "properties" : { + "message" : { + "type" : "string" + } + } + }, + "Schema31Changes": { + "type" : "object", + "properties" : { + "nullableString" : { + "type" : "string", + "nullable" : true + }, + "rangedInt" : { + "type" : "integer", + "format" : "int32", + "minimum" : 4, + "exclusiveMinimum" : true, + "maximum" : 10, + "exclusiveMaximum" : true + } + } + } + } + } +} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaConfig.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaConfig.json index ba55506b4..645d3a359 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaConfig.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaConfig.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.0", + "openapi" : "3.1.2", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaSchema.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaSchema.json index bbe5474dd..702e20226 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaSchema.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testVersionViaSchema.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.2", + "openapi" : "3.1.1", "info" : { "title" : "Generated API", "version" : "1.0" @@ -21,7 +21,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } @@ -164,4 +171,4 @@ } } } -} \ No newline at end of file +} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-delete.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-delete.json deleted file mode 100644 index f98d3043c..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-delete.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "delete": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-get.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-get.json deleted file mode 100644 index fd776ae0d..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-get.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "get": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-delete.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-delete.json deleted file mode 100644 index 5dd5e3553..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-delete.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "delete": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "204": { - "description": "No Content", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-get.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-get.json deleted file mode 100644 index b7a0fae44..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-get.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "get": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "204": { - "description": "No Content", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-patch.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-patch.json deleted file mode 100644 index b8ad8f576..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-patch.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "patch": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "204": { - "description": "No Content", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-put.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-put.json deleted file mode 100644 index ac8b7af32..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-not-async-void-put.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "put": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "204": { - "description": "No Content", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-patch.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-patch.json deleted file mode 100644 index 4e04ccaa8..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-patch.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "patch": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-post.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-post.json deleted file mode 100644 index 135763d55..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-post.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "post": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-put.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-put.json deleted file mode 100644 index b14ab190b..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-put.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "put": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-void-post.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-void-post.json deleted file mode 100644 index 05394c4e9..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-invalid-response-code-void-post.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "post": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-no-description.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-no-description.json deleted file mode 100644 index 135763d55..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-no-description.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "openapi": "3.0.3", - "paths": { - "/pets": { - "post": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-variations.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-variations.json index 7d0b16266..c0ae16f5a 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-variations.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.api-response-schema-variations.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/item/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.component-status-reuse.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.component-status-reuse.json index 7fb1aa6e4..5bdf751ca 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.component-status-reuse.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.component-status-reuse.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Test title", "version": "0.1" diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-generation.json index b7d407830..7a722ac77 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-generation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/resources" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-multiple-response-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-multiple-response-generation.json index f4c9780c3..8f06f2175 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-multiple-response-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-multiple-response-generation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/resources" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-overridden-by-method-annotation-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-overridden-by-method-annotation-generation.json index bc8c328b8..1f0394067 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-overridden-by-method-annotation-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.exception-mapper-overridden-by-method-annotation-generation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/resource2s" : { "get" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-enabled-by-incomplete-api-response.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-enabled-by-incomplete-api-response.json index 336e4c149..f148fb2df 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-enabled-by-incomplete-api-response.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-enabled-by-incomplete-api-response.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-json-example-api-response.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-json-example-api-response.json index 7c5c2ee52..5f5f95950 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-json-example-api-response.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-json-example-api-response.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/pets/{id}" : { "get" : { @@ -12,6 +12,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-api-responses-annotation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-api-responses-annotation.json index 7d7315634..630907cc2 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-api-responses-annotation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-api-responses-annotation.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-status-omission.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-status-omission.json index af36733a9..ebd32978d 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-status-omission.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-status-omission.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-supplied-default-api-response.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-supplied-default-api-response.json index a8a1f5847..723062177 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-supplied-default-api-response.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generation-suppressed-by-supplied-default-api-response.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed-wo-array-refs.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed-wo-array-refs.json index b6cdd8125..e08a39180 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed-wo-array-refs.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed-wo-array-refs.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/fruits": { "get": { @@ -22,6 +22,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -49,6 +50,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed.json index b6cdd8125..e08a39180 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-indexed.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/fruits": { "get": { @@ -22,6 +22,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -49,6 +50,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-unindexed.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-unindexed.json index 5c290ec6d..401571007 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-unindexed.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-collection.set-unindexed.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/fruits": { "get": { @@ -22,6 +22,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -49,6 +50,7 @@ }, "delete": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-type-variables.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-type-variables.json index c8f9fbc37..5643e84cf 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-type-variables.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.generic-type-variables.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/generic/map": { "get": { @@ -55,6 +55,7 @@ "/generic/save": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.hidden-setter-readonly-props.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.hidden-setter-readonly-props.json index d1ac96aa8..9a2aa0327 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.hidden-setter-readonly-props.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.hidden-setter-readonly-props.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/beanparamimpl": { "get": { @@ -35,7 +35,7 @@ "description": "Condition string.", "minLength": 1, "type": "string", - "example": "arch = \"x86_64\"" + "examples" : [ "arch = \"x86_64\"" ] }, "ctime": { "format": "yyyy-MM-dd hh:mm:ss.ddd", diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation-opaque.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation-opaque.json index 5ae973a25..a0d5ebd97 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation-opaque.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation-opaque.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/1": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -22,6 +23,7 @@ "/2": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation.json index ef1283b6b..47f98e9e8 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.kotlin-continuation.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/hello/async": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.multipart-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.multipart-generation.json index adb4a8271..5ca23be9c 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.multipart-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.multipart-generation.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.mutiny-uni.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.mutiny-uni.json index 46087feeb..505178f01 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.mutiny-uni.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.mutiny-uni.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/item": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nested-parameterized-collection-types.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nested-parameterized-collection-types.json index ae95b8bb6..7f6766100 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nested-parameterized-collection-types.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nested-parameterized-collection-types.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/map": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nonjaxrs-methods-skipped.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nonjaxrs-methods-skipped.json index 3848e176c..0f0729db6 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nonjaxrs-methods-skipped.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.nonjaxrs-methods-skipped.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/trees": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.standin-generic-type-resolved.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.standin-generic-type-resolved.json index 6c2f9709b..3c5e84e0e 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.standin-generic-type-resolved.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.standin-generic-type-resolved.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/either": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.unknown-type.empty-schema.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.unknown-type.empty-schema.json index 6c9a76ba5..a1d62c3ce 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.unknown-type.empty-schema.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.unknown-type.empty-schema.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/unindexed": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-async-response-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-async-response-generation.json index 4a58feaa4..4e338a041 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-async-response-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-async-response-generation.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "get": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-nonpost-response-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-nonpost-response-generation.json index 005330a3a..631e669d7 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-nonpost-response-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-nonpost-response-generation.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets/{id}": { "delete": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-post-response-generation.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-post-response-generation.json index 72ea025a3..daad885c5 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-post-response-generation.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/responses.void-post-response-generation.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/pets": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.dataObjectList.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.dataObjectList.expected.json index 8af253b7a..ee5c5fada 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.dataObjectList.expected.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.dataObjectList.expected.json @@ -9,23 +9,23 @@ "properties" : { "cardNumber" : { "type" : "string", - "example" : "**********1234" + "examples" : [ "**********1234" ] }, "cardholderName" : { "type" : "string", - "example" : "Joe Smith" + "examples" : [ "Joe Smith" ] }, "cvv" : { "type" : "string", - "example" : "0322" + "examples" : [ "0322" ] }, "expiryDate" : { "type" : "string", - "example" : "04/19" + "examples" : [ "04/19" ] }, "issuer" : { "type" : "string", - "example" : "VISA" + "examples" : [ "VISA" ] } }, "additionalProperties": false diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.jsonview-schemas-basic.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.jsonview-schemas-basic.json index 4571d1c54..bce3f1a63 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.jsonview-schemas-basic.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/special.jsonview-schemas-basic.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "info": { "title": "Generated API", "version": "1.0" @@ -38,6 +38,7 @@ }, "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-broken.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-broken.json new file mode 100644 index 000000000..49a031af0 --- /dev/null +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-broken.json @@ -0,0 +1,3 @@ +{ + "openapi" : "9999999.999999.99999" +} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-valid.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-valid.json new file mode 100644 index 000000000..1d4c0349b --- /dev/null +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version-valid.json @@ -0,0 +1,3 @@ +{ + "openapi" : "3.1.1" +} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version.json deleted file mode 100644 index fd01e637b..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/static/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "openapi" : "3.0.2" -} \ No newline at end of file diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanGatewayWAR.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanGatewayWAR.expected.json deleted file mode 100644 index 8925ab733..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanGatewayWAR.expected.json +++ /dev/null @@ -1,283 +0,0 @@ -{ - "openapi" : "3.0.1", - "info" : { - "title" : "Generated API", - "version" : "1.0" - }, - "paths" : { - "/apis" : { - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Api" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/apis/{organizationId}/{apiId}/{version}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/apis/{organizationId}/{apiId}/{version}/endpoint" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiEndpoint" - } - } - } - } - } - } - }, - "/clients" : { - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Client" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/clients/{organizationId}/{clientId}/{version}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/system/status" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SystemStatus" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ApiEndpoint" : { - "properties" : { - "endpoint" : { - "type" : "string" - } - } - }, - "Api" : { - "properties" : { - "apiId" : { - "type" : "string" - }, - "apiPolicies" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "policyImpl" : { - "type" : "string" - }, - "policyJsonConfig" : { - "type" : "string" - } - } - } - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "type" : "string" - }, - "maxPayloadBufferSize" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "publicAPI" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "Client" : { - "properties" : { - "apiKey" : { - "type" : "string" - }, - "clientId" : { - "type" : "string" - }, - "contracts" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiId" : { - "type" : "string" - }, - "apiOrgId" : { - "type" : "string" - }, - "apiVersion" : { - "type" : "string" - }, - "plan" : { - "type" : "string" - }, - "policies" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "policyImpl" : { - "type" : "string" - }, - "policyJsonConfig" : { - "type" : "string" - } - } - } - } - } - } - }, - "organizationId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "SystemStatus" : { - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "up" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - } - } - } -} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanManagerWAR.expected.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanManagerWAR.expected.json deleted file mode 100644 index 15cedf2dc..000000000 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/testApimanManagerWAR.expected.json +++ /dev/null @@ -1,10001 +0,0 @@ -{ - "openapi" : "3.0.1", - "info" : { - "title" : "Generated API", - "version" : "1.0" - }, - "paths" : { - "/actions" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ActionBean" - } - } - } - }, - "responses" : { - "201" : { } - } - } - }, - "/apis" : { - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Api" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/apis/{organizationId}/{apiId}/{version}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/apis/{organizationId}/{apiId}/{version}/endpoint" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiEndpoint" - } - } - } - } - } - } - }, - "/clients" : { - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Client" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/clients/{organizationId}/{clientId}/{version}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/currentuser/apiorgs" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numApis" : { - "format" : "int32", - "type" : "integer" - }, - "numClients" : { - "format" : "int32", - "type" : "integer" - }, - "numMembers" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - } - }, - "/currentuser/apis" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/currentuser/clientorgs" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numApis" : { - "format" : "int32", - "type" : "integer" - }, - "numClients" : { - "format" : "int32", - "type" : "integer" - }, - "numMembers" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - } - }, - "/currentuser/clients" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numContracts" : { - "format" : "int32", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/currentuser/info" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/CurrentUserBean" - } - } - } - } - } - }, - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateUserBean" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/currentuser/planorgs" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numApis" : { - "format" : "int32", - "type" : "integer" - }, - "numClients" : { - "format" : "int32", - "type" : "integer" - }, - "numMembers" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - } - }, - "/downloads/{downloadId}" : { - "get" : { - "parameters" : [ { - "name" : "downloadId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { }, - "text/xml" : { } - } - } - } - } - }, - "/gateways" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "type" : { - "enum" : [ "REST" ], - "type" : "string" - } - } - } - } - } - } - } - } - }, - "put" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewGatewayBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/GatewayTestResultBean" - } - } - } - } - } - }, - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewGatewayBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/GatewayBean" - } - } - } - } - } - } - }, - "/gateways/{gatewayId}" : { - "get" : { - "parameters" : [ { - "name" : "gatewayId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/GatewayBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "gatewayId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateGatewayBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "gatewayId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewOrganizationBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/OrganizationBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/OrganizationBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateOrganizationBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewApiBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateApiBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - }, - "publicAPI" : { - "type" : "boolean" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewApiVersionBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiVersionBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateApiVersionBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/contracts" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiDescription" : { - "type" : "string" - }, - "apiId" : { - "type" : "string" - }, - "apiName" : { - "type" : "string" - }, - "apiOrganizationId" : { - "type" : "string" - }, - "apiOrganizationName" : { - "type" : "string" - }, - "apiVersion" : { - "type" : "string" - }, - "clientId" : { - "type" : "string" - }, - "clientName" : { - "type" : "string" - }, - "clientOrganizationId" : { - "type" : "string" - }, - "clientOrganizationName" : { - "type" : "string" - }, - "clientVersion" : { - "type" : "string" - }, - "contractId" : { - "format" : "int64", - "type" : "integer" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "planId" : { - "type" : "string" - }, - "planName" : { - "type" : "string" - }, - "planVersion" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/definition" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { }, - "application/wsdl+xml" : { }, - "application/x-yaml" : { } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewApiDefinitionBean" - } - } - } - }, - "responses" : { - "201" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/endpoint" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiVersionEndpointSummaryBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/clientResponseStats" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ResponseStatsPerClientBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/clientUsage" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UsagePerClientBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/planResponseStats" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ResponseStatsPerPlanBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/planUsage" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UsagePerPlanBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/responseStats" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "interval", - "in" : "query", - "required" : true, - "schema" : { - "$ref" : "#/components/schemas/HistogramIntervalType" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ResponseStatsHistogramBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/summaryResponseStats" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ResponseStatsSummaryBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/metrics/usage" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "interval", - "in" : "query", - "required" : true, - "schema" : { - "$ref" : "#/components/schemas/HistogramIntervalType" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UsageHistogramBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/plans" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planDescription" : { - "type" : "string" - }, - "planId" : { - "type" : "string" - }, - "planName" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/plans/{planId}/policyChain" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyChainBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/policies" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "policyDefinitionId" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPolicyBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/policies/{policyId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdatePolicyBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/reorderPolicies" : { - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyChainBean" - } - } - } - }, - "responses" : { - "201" : { } - } - } - }, - "/organizations/{organizationId}/apis/{apiId}/versions/{version}/status" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "apiId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiVersionStatusBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numContracts" : { - "format" : "int32", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewClientBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ClientBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ClientBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateClientBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiKey" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewClientVersionBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ClientVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ClientVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/apikey" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiKeyBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiKeyBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ApiKeyBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/apiregistry/json" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "download", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/apiregistry/xml" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "download", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/xml" : { }, - "application/json" : { } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/contracts" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiDescription" : { - "type" : "string" - }, - "apiId" : { - "type" : "string" - }, - "apiName" : { - "type" : "string" - }, - "apiOrganizationId" : { - "type" : "string" - }, - "apiOrganizationName" : { - "type" : "string" - }, - "apiVersion" : { - "type" : "string" - }, - "clientId" : { - "type" : "string" - }, - "clientName" : { - "type" : "string" - }, - "clientOrganizationId" : { - "type" : "string" - }, - "clientOrganizationName" : { - "type" : "string" - }, - "clientVersion" : { - "type" : "string" - }, - "contractId" : { - "format" : "int64", - "type" : "integer" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "planId" : { - "type" : "string" - }, - "planName" : { - "type" : "string" - }, - "planVersion" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewContractBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ContractBean" - } - } - } - } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/contracts/{contractId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "contractId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ContractBean" - } - } - } - } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "contractId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/metrics/apiUsage" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "from", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "to", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ClientUsagePerApiBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/policies" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "policyDefinitionId" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPolicyBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/policies/{policyId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdatePolicyBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/clients/{clientId}/versions/{version}/reorderPolicies" : { - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "clientId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyChainBean" - } - } - } - }, - "responses" : { - "201" : { } - } - } - }, - "/organizations/{organizationId}/members" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "email" : { - "type" : "string" - }, - "joinedOn" : { - "format" : "date", - "type" : "string" - }, - "roles" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "roleId" : { - "type" : "string" - }, - "roleName" : { - "type" : "string" - } - } - } - }, - "userId" : { - "type" : "string" - }, - "userName" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/members/{userId}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/plans" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPlanBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PlanBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PlanBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdatePlanBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPlanVersionBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PlanVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions/{version}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PlanVersionBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions/{version}/activity" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions/{version}/policies" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "policyDefinitionId" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPolicyBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions/{version}/policies/{policyId}" : { - "get" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdatePolicyBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "policyId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/organizations/{organizationId}/plans/{planId}/versions/{version}/reorderPolicies" : { - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "planId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "version", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyChainBean" - } - } - } - }, - "responses" : { - "201" : { } - } - } - }, - "/organizations/{organizationId}/roles" : { - "post" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/GrantRolesBean" - } - } - } - }, - "responses" : { - "201" : { } - } - } - }, - "/organizations/{organizationId}/roles/{roleId}/{userId}" : { - "delete" : { - "parameters" : [ { - "name" : "organizationId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "roleId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/permissions" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserPermissionsBean" - } - } - } - } - } - } - }, - "/permissions/{userId}" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserPermissionsBean" - } - } - } - } - } - } - }, - "/plugins" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "artifactId" : { - "type" : "string" - }, - "classifier" : { - "type" : "string" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "groupId" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "type" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewPluginBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PluginBean" - } - } - } - } - } - } - }, - "/plugins/availablePlugins" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "artifactId" : { - "type" : "string" - }, - "classifier" : { - "type" : "string" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "groupId" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "type" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/plugins/{pluginId}" : { - "get" : { - "parameters" : [ { - "name" : "pluginId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PluginBean" - } - } - } - } - } - }, - "delete" : { - "parameters" : [ { - "name" : "pluginId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/plugins/{pluginId}/policyDefs" : { - "get" : { - "parameters" : [ { - "name" : "pluginId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "formType" : { - "enum" : [ "Default", "JsonSchema" ], - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "pluginId" : { - "format" : "int64", - "type" : "integer" - }, - "policyImpl" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/plugins/{pluginId}/policyDefs/{policyDefId}/form" : { - "get" : { - "parameters" : [ { - "name" : "pluginId", - "in" : "path", - "required" : true, - "schema" : { - "format" : "int64", - "type" : "integer" - } - }, { - "name" : "policyDefId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/policyDefs" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "formType" : { - "enum" : [ "Default", "JsonSchema" ], - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "pluginId" : { - "format" : "int64", - "type" : "integer" - }, - "policyImpl" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyDefinitionBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyDefinitionBean" - } - } - } - } - } - } - }, - "/policyDefs/{policyDefinitionId}" : { - "get" : { - "parameters" : [ { - "name" : "policyDefinitionId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PolicyDefinitionBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "policyDefinitionId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "policyDefinitionId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/roles" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "autoGrant" : { - "type" : "boolean" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "permissions" : { - "type" : "array", - "items" : { - "type" : "object" - } - } - } - } - } - } - } - } - } - }, - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/NewRoleBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/RoleBean" - } - } - } - } - } - } - }, - "/roles/search" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "autoGrant" : { - "type" : "boolean" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "permissions" : { - "type" : "array", - "items" : { - "type" : "object" - } - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/roles/{roleId}" : { - "get" : { - "parameters" : [ { - "name" : "roleId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/RoleBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "roleId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateRoleBean" - } - } - } - }, - "responses" : { - "204" : { } - } - }, - "delete" : { - "parameters" : [ { - "name" : "roleId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { } - } - } - }, - "/search/apiCatalog/entries" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "definitionUrl" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "internal" : { - "type" : "boolean" - }, - "name" : { - "type" : "string" - }, - "namespace" : { - "type" : "string" - }, - "routeDefinitionUrl" : { - "type" : "string" - }, - "routeEndpoint" : { - "type" : "string" - }, - "tags" : { - "type" : "array", - "items" : { - "type" : "string" - } - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/search/apiCatalog/namespaces" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "current" : { - "type" : "boolean" - }, - "name" : { - "type" : "string" - }, - "ownedByUser" : { - "type" : "boolean" - } - } - } - } - } - } - } - } - } - }, - "/search/apis" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/search/clients" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numContracts" : { - "format" : "int32", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/search/organizations" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numApis" : { - "format" : "int32", - "type" : "integer" - }, - "numClients" : { - "format" : "int32", - "type" : "integer" - }, - "numMembers" : { - "format" : "int32", - "type" : "integer" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/system/export" : { - "get" : { - "parameters" : [ { - "name" : "download", - "in" : "query", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { } - } - } - } - } - }, - "/system/import" : { - "post" : { - "responses" : { - "200" : { - "content" : { - "text/plain" : { } - } - } - } - } - }, - "/system/status" : { - "get" : { - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SystemStatusBean" - } - } - } - } - } - } - }, - "/users/search" : { - "post" : { - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/SearchCriteriaBean" - } - } - } - }, - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "admin" : { - "type" : "boolean" - }, - "email" : { - "type" : "string" - }, - "fullName" : { - "type" : "string" - }, - "joinedOn" : { - "format" : "date", - "type" : "string" - }, - "username" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/users/{userId}" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserBean" - } - } - } - } - } - }, - "put" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateUserBean" - } - } - } - }, - "responses" : { - "204" : { } - } - } - }, - "/users/{userId}/activity" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - }, { - "name" : "count", - "in" : "query", - "required" : true, - "schema" : { - "format" : "int32", - "type" : "integer" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "properties" : { - "beans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "data" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityType" : { - "enum" : [ "Api", "Client", "Organization", "Plan" ], - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "what" : { - "enum" : [ "AddPolicy", "BreakContract", "Clone", "Create", "CreateContract", "Delete", "DeleteDefinition", "Grant", "Lock", "Publish", "Register", "RemovePolicy", "ReorderPolicies", "Retire", "Revoke", "Unregister", "Update", "UpdateDefinition", "UpdatePolicy" ], - "type" : "string" - }, - "who" : { - "type" : "string" - } - } - } - }, - "totalSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - }, - "/users/{userId}/apis" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/users/{userId}/clients" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numContracts" : { - "format" : "int32", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "organizationName" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - }, - "/users/{userId}/organizations" : { - "get" : { - "parameters" : [ { - "name" : "userId", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numApis" : { - "format" : "int32", - "type" : "integer" - }, - "numClients" : { - "format" : "int32", - "type" : "integer" - }, - "numMembers" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ApiEndpoint" : { - "properties" : { - "endpoint" : { - "type" : "string" - } - } - }, - "Api" : { - "properties" : { - "apiId" : { - "type" : "string" - }, - "apiPolicies" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "policyImpl" : { - "type" : "string" - }, - "policyJsonConfig" : { - "type" : "string" - } - } - } - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "type" : "string" - }, - "maxPayloadBufferSize" : { - "format" : "int64", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "publicAPI" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "Client" : { - "properties" : { - "apiKey" : { - "type" : "string" - }, - "clientId" : { - "type" : "string" - }, - "contracts" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiId" : { - "type" : "string" - }, - "apiOrgId" : { - "type" : "string" - }, - "apiVersion" : { - "type" : "string" - }, - "plan" : { - "type" : "string" - }, - "policies" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "policyImpl" : { - "type" : "string" - }, - "policyJsonConfig" : { - "type" : "string" - } - } - } - } - } - } - }, - "organizationId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "SystemStatus" : { - "properties" : { - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "up" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "ActionBean" : { - "properties" : { - "entityId" : { - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "organizationId" : { - "type" : "string" - }, - "type" : { - "enum" : [ "lockPlan", "publishAPI", "registerClient", "retireAPI", "unregisterClient" ], - "type" : "string" - } - } - }, - "CurrentUserBean" : { - "properties" : { - "permissions" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "name" : { - "enum" : [ "apiAdmin", "apiEdit", "apiView", "clientAdmin", "clientEdit", "clientView", "orgAdmin", "orgEdit", "orgView", "planAdmin", "planEdit", "planView" ], - "type" : "string" - }, - "organizationId" : { - "type" : "string" - } - } - } - }, - "admin" : { - "type" : "boolean" - }, - "email" : { - "type" : "string" - }, - "fullName" : { - "type" : "string" - }, - "joinedOn" : { - "format" : "date", - "type" : "string" - }, - "username" : { - "type" : "string" - } - } - }, - "UpdateUserBean" : { - "properties" : { - "email" : { - "type" : "string" - }, - "fullName" : { - "type" : "string" - } - } - }, - "NewGatewayBean" : { - "properties" : { - "configuration" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "type" : { - "enum" : [ "REST" ], - "type" : "string" - } - } - }, - "GatewayBean" : { - "properties" : { - "configuration" : { - "type" : "string" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "type" : { - "enum" : [ "REST" ], - "type" : "string" - } - } - }, - "GatewayTestResultBean" : { - "properties" : { - "detail" : { - "type" : "string" - }, - "success" : { - "type" : "boolean" - } - } - }, - "UpdateGatewayBean" : { - "properties" : { - "configuration" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "type" : { - "enum" : [ "REST" ], - "type" : "string" - } - } - }, - "NewOrganizationBean" : { - "properties" : { - "description" : { - "type" : "string" - }, - "name" : { - "type" : "string" - } - } - }, - "OrganizationBean" : { - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - }, - "NewApiBean" : { - "properties" : { - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "definitionUrl" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "initialVersion" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - } - } - }, - "ApiBean" : { - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "NewPolicyBean" : { - "properties" : { - "configuration" : { - "type" : "string" - }, - "definitionId" : { - "type" : "string" - } - } - }, - "PolicyBean" : { - "properties" : { - "configuration" : { - "type" : "string" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definition" : { - "type" : "object", - "properties" : { - "deleted" : { - "type" : "boolean" - }, - "description" : { - "type" : "string" - }, - "form" : { - "type" : "string" - }, - "formType" : { - "enum" : [ "Default", "JsonSchema" ], - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "pluginId" : { - "format" : "int64", - "type" : "integer" - }, - "policyImpl" : { - "type" : "string" - }, - "templates" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "language" : { - "type" : "string" - }, - "template" : { - "type" : "string" - } - } - } - } - } - }, - "description" : { - "type" : "string" - }, - "entityId" : { - "type" : "string" - }, - "entityVersion" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "orderIndex" : { - "format" : "int32", - "type" : "integer" - }, - "organizationId" : { - "type" : "string" - }, - "type" : { - "enum" : [ "Api", "Client", "Plan" ], - "type" : "string" - } - } - }, - "NewApiVersionBean" : { - "properties" : { - "clone" : { - "type" : "boolean" - }, - "cloneVersion" : { - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "definitionUrl" : { - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "ApiVersionBean" : { - "properties" : { - "api" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "NewClientBean" : { - "properties" : { - "description" : { - "type" : "string" - }, - "initialVersion" : { - "type" : "string" - }, - "name" : { - "type" : "string" - } - } - }, - "ClientBean" : { - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "NewClientVersionBean" : { - "properties" : { - "apiKey" : { - "type" : "string" - }, - "clone" : { - "type" : "boolean" - }, - "cloneVersion" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "ClientVersionBean" : { - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientVersionBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "NewContractBean" : { - "properties" : { - "apiId" : { - "type" : "string" - }, - "apiOrgId" : { - "type" : "string" - }, - "apiVersion" : { - "type" : "string" - }, - "planId" : { - "type" : "string" - } - } - }, - "ContractBean" : { - "properties" : { - "api" : { - "type" : "object", - "properties" : { - "api" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "client" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientVersionBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - } - } - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "plan" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - } - } - } - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanVersionBean", - "type" : "object" - } - } - } - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - }, - "NewPlanBean" : { - "properties" : { - "description" : { - "type" : "string" - }, - "initialVersion" : { - "type" : "string" - }, - "name" : { - "type" : "string" - } - } - }, - "PlanBean" : { - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - } - } - } - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - } - } - }, - "NewPlanVersionBean" : { - "properties" : { - "clone" : { - "type" : "boolean" - }, - "cloneVersion" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "PlanVersionBean" : { - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "lockedOn" : { - "format" : "date", - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "plan" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "type" : "object", - "properties" : { - "apiSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apiVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "api" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiBean", - "type" : "object" - }, - "apiDefinition" : { - "type" : "object", - "properties" : { - "apiVersion" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.apis.ApiVersionBean", - "type" : "object" - }, - "data" : { - "type" : "array", - "items" : { - "format" : "byte", - "type" : "string" - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "numPublished" : { - "format" : "int32", - "type" : "integer" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "clientSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "clientVersionSet" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "apikey" : { - "type" : "string" - }, - "client" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.clients.ClientBean", - "type" : "object" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "publishedOn" : { - "format" : "date", - "type" : "string" - }, - "retiredOn" : { - "format" : "date", - "type" : "string" - }, - "status" : { - "enum" : [ "Created", "Ready", "Registered", "Retired" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "organization" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.orgs.OrganizationBean", - "type" : "object" - } - } - } - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "modifiedBy" : { - "type" : "string" - }, - "modifiedOn" : { - "format" : "date", - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "planSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanBean", - "type" : "object" - } - } - } - }, - "planVersionSet" : { - "type" : "array", - "items" : { - "description" : "Cyclic reference to io.apiman.manager.api.beans.plans.PlanVersionBean", - "type" : "object" - } - } - } - }, - "status" : { - "enum" : [ "Created", "Locked", "Ready" ], - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "PolicyChainBean" : { - "properties" : { - "policies" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "policyDefinitionId" : { - "type" : "string" - } - } - } - } - } - }, - "ApiVersionEndpointSummaryBean" : { - "properties" : { - "managedEndpoint" : { - "type" : "string" - } - } - }, - "ApiVersionStatusBean" : { - "properties" : { - "items" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "done" : { - "type" : "boolean" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "optional" : { - "type" : "boolean" - }, - "remediation" : { - "type" : "string" - } - } - } - }, - "status" : { - "enum" : [ "Created", "Published", "Ready", "Retired" ], - "type" : "string" - } - } - }, - "ApiKeyBean" : { - "properties" : { - "apiKey" : { - "type" : "string" - } - } - }, - "ClientUsagePerApiBean" : { - "properties" : { - "data" : { - "type" : "object", - "additionalProperties" : { - "format" : "int64", - "type" : "integer" - } - } - } - }, - "HistogramIntervalType" : { }, - "ResponseStatsHistogramBean" : { - "properties" : { - "data" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "errors" : { - "format" : "int64", - "type" : "integer" - }, - "failures" : { - "format" : "int64", - "type" : "integer" - }, - "total" : { - "format" : "int64", - "type" : "integer" - }, - "label" : { - "type" : "string" - } - } - } - } - } - }, - "ResponseStatsPerClientBean" : { - "properties" : { - "data" : { - "type" : "object", - "additionalProperties" : { - "type" : "object", - "properties" : { - "errors" : { - "format" : "int64", - "type" : "integer" - }, - "failures" : { - "format" : "int64", - "type" : "integer" - }, - "total" : { - "format" : "int64", - "type" : "integer" - }, - "label" : { - "type" : "string" - } - } - } - } - } - }, - "ResponseStatsPerPlanBean" : { - "properties" : { - "data" : { - "type" : "object", - "additionalProperties" : { - "type" : "object", - "properties" : { - "errors" : { - "format" : "int64", - "type" : "integer" - }, - "failures" : { - "format" : "int64", - "type" : "integer" - }, - "total" : { - "format" : "int64", - "type" : "integer" - }, - "label" : { - "type" : "string" - } - } - } - } - } - }, - "ResponseStatsSummaryBean" : { - "properties" : { - "errors" : { - "format" : "int64", - "type" : "integer" - }, - "failures" : { - "format" : "int64", - "type" : "integer" - }, - "total" : { - "format" : "int64", - "type" : "integer" - } - } - }, - "UsageHistogramBean" : { - "properties" : { - "data" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "count" : { - "format" : "int64", - "type" : "integer" - }, - "label" : { - "type" : "string" - } - } - } - } - } - }, - "UsagePerClientBean" : { - "properties" : { - "data" : { - "type" : "object", - "additionalProperties" : { - "format" : "int64", - "type" : "integer" - } - } - } - }, - "UsagePerPlanBean" : { - "properties" : { - "data" : { - "type" : "object", - "additionalProperties" : { - "format" : "int64", - "type" : "integer" - } - } - } - }, - "GrantRolesBean" : { - "properties" : { - "roleIds" : { - "type" : "array", - "items" : { - "type" : "string" - } - }, - "userId" : { - "type" : "string" - } - } - }, - "UpdateOrganizationBean" : { - "properties" : { - "description" : { - "type" : "string" - } - } - }, - "UpdateApiBean" : { - "properties" : { - "description" : { - "type" : "string" - } - } - }, - "NewApiDefinitionBean" : { - "properties" : { - "definitionType" : { - "enum" : [ "External", "None", "RAML", "SwaggerJSON", "SwaggerYAML", "WADL", "WSDL" ], - "type" : "string" - }, - "definitionUrl" : { - "type" : "string" - } - } - }, - "UpdatePolicyBean" : { - "properties" : { - "configuration" : { - "type" : "string" - } - } - }, - "UpdateApiVersionBean" : { - "properties" : { - "endpoint" : { - "type" : "string" - }, - "endpointContentType" : { - "enum" : [ "json", "xml" ], - "type" : "string" - }, - "endpointProperties" : { - "type" : "object", - "additionalProperties" : { - "type" : "string" - } - }, - "endpointType" : { - "enum" : [ "rest", "soap" ], - "type" : "string" - }, - "gateways" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "gatewayId" : { - "type" : "string" - } - } - } - }, - "parsePayload" : { - "type" : "boolean" - }, - "plans" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "planId" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - } - }, - "publicAPI" : { - "type" : "boolean" - } - } - }, - "UpdateClientBean" : { - "properties" : { - "description" : { - "type" : "string" - } - } - }, - "UpdatePlanBean" : { - "properties" : { - "description" : { - "type" : "string" - } - } - }, - "UserPermissionsBean" : { - "properties" : { - "permissions" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "name" : { - "enum" : [ "apiAdmin", "apiEdit", "apiView", "clientAdmin", "clientEdit", "clientView", "orgAdmin", "orgEdit", "orgView", "planAdmin", "planEdit", "planView" ], - "type" : "string" - }, - "organizationId" : { - "type" : "string" - } - } - } - }, - "userId" : { - "type" : "string" - } - } - }, - "NewPluginBean" : { - "properties" : { - "artifactId" : { - "type" : "string" - }, - "classifier" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "groupId" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "type" : { - "type" : "string" - }, - "upgrade" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "PluginBean" : { - "properties" : { - "artifactId" : { - "type" : "string" - }, - "classifier" : { - "type" : "string" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "deleted" : { - "type" : "boolean" - }, - "description" : { - "type" : "string" - }, - "groupId" : { - "type" : "string" - }, - "id" : { - "format" : "int64", - "type" : "integer" - }, - "name" : { - "type" : "string" - }, - "type" : { - "type" : "string" - }, - "version" : { - "type" : "string" - } - } - }, - "PolicyDefinitionBean" : { - "properties" : { - "deleted" : { - "type" : "boolean" - }, - "description" : { - "type" : "string" - }, - "form" : { - "type" : "string" - }, - "formType" : { - "enum" : [ "Default", "JsonSchema" ], - "type" : "string" - }, - "icon" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "pluginId" : { - "format" : "int64", - "type" : "integer" - }, - "policyImpl" : { - "type" : "string" - }, - "templates" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "language" : { - "type" : "string" - }, - "template" : { - "type" : "string" - } - } - } - } - } - }, - "NewRoleBean" : { - "properties" : { - "autoGrant" : { - "type" : "boolean" - }, - "description" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "permissions" : { - "type" : "array", - "items" : { - "type" : "object" - } - } - } - }, - "RoleBean" : { - "properties" : { - "autoGrant" : { - "type" : "boolean" - }, - "createdBy" : { - "type" : "string" - }, - "createdOn" : { - "format" : "date", - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "permissions" : { - "type" : "array", - "items" : { - "type" : "object" - } - } - } - }, - "SearchCriteriaBean" : { - "properties" : { - "filters" : { - "type" : "array", - "items" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "operator" : { - "enum" : [ "bool_eq", "eq", "gt", "gte", "like", "lt", "lte", "neq" ], - "type" : "string" - }, - "value" : { - "type" : "string" - } - } - } - }, - "orderBy" : { - "type" : "object", - "properties" : { - "ascending" : { - "type" : "boolean" - }, - "name" : { - "type" : "string" - } - } - }, - "paging" : { - "type" : "object", - "properties" : { - "page" : { - "format" : "int32", - "type" : "integer" - }, - "pageSize" : { - "format" : "int32", - "type" : "integer" - } - } - } - } - }, - "UpdateRoleBean" : { - "properties" : { - "autoGrant" : { - "type" : "boolean" - }, - "description" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "permissions" : { - "type" : "array", - "items" : { - "type" : "object" - } - } - } - }, - "SystemStatusBean" : { - "properties" : { - "builtOn" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "id" : { - "type" : "string" - }, - "moreInfo" : { - "type" : "string" - }, - "name" : { - "type" : "string" - }, - "up" : { - "type" : "boolean" - }, - "version" : { - "type" : "string" - } - } - }, - "UserBean" : { - "properties" : { - "admin" : { - "type" : "boolean" - }, - "email" : { - "type" : "string" - }, - "fullName" : { - "type" : "string" - }, - "joinedOn" : { - "format" : "date", - "type" : "string" - }, - "username" : { - "type" : "string" - } - } - } - } - } -} diff --git a/extension-spring/pom.xml b/extension-spring/pom.xml index e22c84f5d..b0b204440 100644 --- a/extension-spring/pom.xml +++ b/extension-spring/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-spring diff --git a/extension-spring/src/main/java/io/smallrye/openapi/spring/SpringAnnotationScanner.java b/extension-spring/src/main/java/io/smallrye/openapi/spring/SpringAnnotationScanner.java index 1a46a864e..70d5a4980 100644 --- a/extension-spring/src/main/java/io/smallrye/openapi/spring/SpringAnnotationScanner.java +++ b/extension-spring/src/main/java/io/smallrye/openapi/spring/SpringAnnotationScanner.java @@ -359,7 +359,7 @@ private void processControllerMethod(final ClassInfo resourceClass, private ResourceParameters getResourceParameters(final ClassInfo resourceClass, final MethodInfo method) { - Function reader = t -> context.io().parameters().read(t); + Function reader = t -> context.io().parameterIO().read(t); return SpringParameterProcessor.process(context, currentAppPath, resourceClass, method, reader, context.getExtensions()); diff --git a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringDeleteDefinitionScanning.json b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringDeleteDefinitionScanning.json index fd74ede86..9ddddd79b 100644 --- a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringDeleteDefinitionScanning.json +++ b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringDeleteDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "delete" : { diff --git a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringGetDefinitionScanning.json b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringGetDefinitionScanning.json index 1a0415462..1326efed3 100644 --- a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringGetDefinitionScanning.json +++ b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringGetDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/helloOptional/{name}" : { "get" : { @@ -17,7 +17,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPostDefinitionScanning.json b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPostDefinitionScanning.json index 86fdcd0c6..a3e51eae1 100644 --- a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPostDefinitionScanning.json +++ b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPostDefinitionScanning.json @@ -1,9 +1,10 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -29,6 +30,7 @@ "/greeting/greetWithResponse" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -54,6 +56,7 @@ "/greeting/greetWithResponseTyped" : { "post" : { "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPutDefinitionScanning.json b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPutDefinitionScanning.json index b9f2feb69..aee6558c8 100644 --- a/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPutDefinitionScanning.json +++ b/extension-spring/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicSpringPutDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "put" : { @@ -12,6 +12,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -45,6 +46,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -78,6 +80,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/extension-vertx/pom.xml b/extension-vertx/pom.xml index a6c365b85..8e0da5837 100644 --- a/extension-vertx/pom.xml +++ b/extension-vertx/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-vertx diff --git a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java index cb93e8f16..1ea5317d8 100644 --- a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java +++ b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java @@ -310,7 +310,7 @@ private void processRouteMethod(final ClassInfo resourceClass, private ResourceParameters getResourceParameters(final ClassInfo resourceClass, final MethodInfo method) { - Function reader = t -> context.io().parameters().read(t); + Function reader = t -> context.io().parameterIO().read(t); return VertxParameterProcessor.process(context, currentAppPath, resourceClass, method, reader, context.getExtensions()); @@ -337,7 +337,7 @@ boolean shouldScan(MethodInfo resourceMethod) { } if (context.annotations().value(route, "regex") != null) { - return Objects.nonNull(context.io().operations().getAnnotation(resourceMethod)); + return Objects.nonNull(context.io().operationIO().getAnnotation(resourceMethod)); } return true; diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteDeleteDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteDeleteDefinitionScanning.json index c687a36b0..5e8778b26 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteDeleteDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteDeleteDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "delete" : { diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json index 9b2d982a7..fe2bb36d0 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/defaultGet/{name}" : { "get" : { @@ -212,7 +212,14 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Greeting" + "anyOf": [ + { + "$ref" : "#/components/schemas/Greeting" + }, + { + "type" : "null" + } + ] } } } diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json index 0c0d57625..de70ce66d 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json @@ -1,9 +1,10 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "paths": { "/greeting/greet": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -29,6 +30,7 @@ "/greeting/greetWithResponse": { "post": { "requestBody": { + "required": true, "content": { "application/json": { "schema": { diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePutDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePutDefinitionScanning.json index 2e71732af..0834f8cb4 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePutDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePutDefinitionScanning.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "paths" : { "/greeting/greet/{id}" : { "put" : { @@ -12,6 +12,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -45,6 +46,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/implementation/pom.xml b/implementation/pom.xml index 8f766f357..2a8cadb09 100644 --- a/implementation/pom.xml +++ b/implementation/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api diff --git a/pom.xml b/pom.xml index e2fe0d586..7af58bc5f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT pom SmallRye: OpenAPI Parent @@ -22,7 +22,7 @@ 3.0.3 3.2.2 3.9.1 - 3.1.1 + 4.0 1.3 2.0.0.0 1.5.3 diff --git a/release/pom.xml b/release/pom.xml index 57070397d..d1d3085cb 100644 --- a/release/pom.xml +++ b/release/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-release diff --git a/testsuite/coverage/pom.xml b/testsuite/coverage/pom.xml index 7e1ab8002..2330b4a56 100644 --- a/testsuite/coverage/pom.xml +++ b/testsuite/coverage/pom.xml @@ -4,7 +4,7 @@ io.smallrye smallrye-open-api-testsuite - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT ../ diff --git a/testsuite/data/pom.xml b/testsuite/data/pom.xml index 1e06cbedf..80bfd546f 100644 --- a/testsuite/data/pom.xml +++ b/testsuite/data/pom.xml @@ -9,10 +9,11 @@ smallrye-open-api-testsuite-data - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT SmallRye: OpenAPI Test Data + 4.0 2.0.20 17 ${java.version} @@ -37,6 +38,11 @@ smallrye-open-api-jaxrs ${project.version} + + org.eclipse.microprofile.openapi + microprofile-openapi-api + ${eclipse.microprofile.openapi.version} + ${quarkus.platform.group-id} ${quarkus.platform.artifact-id} diff --git a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-deprecated-annotation.json b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-deprecated-annotation.json index 80af8b764..0852cf568 100644 --- a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-deprecated-annotation.json +++ b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-deprecated-annotation.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "DeprecatedKotlinBean" : { diff --git a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-value-class-propname.json b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-value-class-propname.json index 34359eb85..1b30c5aa7 100644 --- a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-value-class-propname.json +++ b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.kotlin-value-class-propname.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.3", + "openapi": "3.1.0", "components": { "schemas": { "KotlinBean": { @@ -10,12 +10,10 @@ "properties": { "id": { "format": "int64", - "type": "integer", - "nullable": true + "type": ["integer", "null"] }, "name": { - "type": "string", - "nullable": true + "type": ["string", "null"] }, "description": { "type": "string" diff --git a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.prefixed-record-component-names.json b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.prefixed-record-component-names.json index 256f6344a..e2e4d2d8f 100644 --- a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.prefixed-record-component-names.json +++ b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/components.schemas.prefixed-record-component-names.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "components" : { "schemas" : { "RecordReferencingBean" : { diff --git a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/ignore.synthetic-classes-interfaces.json b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/ignore.synthetic-classes-interfaces.json index 5c681e679..f732d54bf 100644 --- a/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/ignore.synthetic-classes-interfaces.json +++ b/testsuite/data/src/test/resources/io/smallrye/openapi/testdata/ignore.synthetic-classes-interfaces.json @@ -1,5 +1,5 @@ { - "openapi" : "3.0.3", + "openapi" : "3.1.0", "info" : { "title" : "Generated API", "version" : "1.0" @@ -75,6 +75,7 @@ "post" : { "tags" : [ "PeopleResource" ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { @@ -151,6 +152,7 @@ } } ], "requestBody" : { + "required": true, "content" : { "application/json" : { "schema" : { diff --git a/testsuite/extra/pom.xml b/testsuite/extra/pom.xml index 72933b976..9023070e0 100644 --- a/testsuite/extra/pom.xml +++ b/testsuite/extra/pom.xml @@ -3,7 +3,7 @@ io.smallrye smallrye-open-api-testsuite - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT ../ diff --git a/testsuite/pom.xml b/testsuite/pom.xml index 04653b092..1c5f3d60a 100644 --- a/testsuite/pom.xml +++ b/testsuite/pom.xml @@ -20,7 +20,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-testsuite diff --git a/testsuite/tck/pom.xml b/testsuite/tck/pom.xml index 7898f150c..d8e549851 100644 --- a/testsuite/tck/pom.xml +++ b/testsuite/tck/pom.xml @@ -20,7 +20,7 @@ io.smallrye smallrye-open-api-testsuite - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-testsuite-tck diff --git a/tools/gradle-plugin/pom.xml b/tools/gradle-plugin/pom.xml index e8f902b8b..9c8653531 100644 --- a/tools/gradle-plugin/pom.xml +++ b/tools/gradle-plugin/pom.xml @@ -4,7 +4,7 @@ io.smallrye smallrye-open-api-tools - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-gradle-plugin pom diff --git a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/Configs.java b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/Configs.java index 9d939edca..403dc4989 100644 --- a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/Configs.java +++ b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/Configs.java @@ -50,6 +50,7 @@ class Configs implements SmallryeOpenApiProperties { final Property infoTitle; final Property infoVersion; final Property infoDescription; + final Property infoSummary; final Property infoTermsOfService; final Property infoContactEmail; final Property infoContactName; @@ -84,6 +85,7 @@ class Configs implements SmallryeOpenApiProperties { infoTitle = objects.property(String.class); infoVersion = objects.property(String.class); infoDescription = objects.property(String.class); + infoSummary = objects.property(String.class); infoTermsOfService = objects.property(String.class); infoContactEmail = objects.property(String.class); infoContactName = objects.property(String.class); @@ -119,6 +121,7 @@ class Configs implements SmallryeOpenApiProperties { infoTitle = objects.property(String.class).convention(ext.getInfoTitle()); infoVersion = objects.property(String.class).convention(ext.getInfoVersion()); infoDescription = objects.property(String.class).convention(ext.getInfoDescription()); + infoSummary = objects.property(String.class).convention(ext.getInfoSummary()); infoTermsOfService = objects.property(String.class).convention(ext.getInfoTermsOfService()); infoContactEmail = objects.property(String.class).convention(ext.getInfoContactEmail()); infoContactName = objects.property(String.class).convention(ext.getInfoContactName()); @@ -177,6 +180,7 @@ private Map getProperties() { addToPropertyMap(cp, SmallRyeOASConfig.INFO_TITLE, infoTitle); addToPropertyMap(cp, SmallRyeOASConfig.INFO_VERSION, infoVersion); addToPropertyMap(cp, SmallRyeOASConfig.INFO_DESCRIPTION, infoDescription); + addToPropertyMap(cp, SmallRyeOASConfig.INFO_SUMMARY, infoSummary); addToPropertyMap(cp, SmallRyeOASConfig.INFO_TERMS, infoTermsOfService); addToPropertyMap(cp, SmallRyeOASConfig.INFO_CONTACT_EMAIL, infoContactEmail); addToPropertyMap(cp, SmallRyeOASConfig.INFO_CONTACT_NAME, infoContactName); @@ -289,6 +293,10 @@ public Property getInfoDescription() { return infoDescription; } + public Property getInfoSummary() { + return infoSummary; + } + public Property getInfoTermsOfService() { return infoTermsOfService; } diff --git a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiProperties.java b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiProperties.java index 68086997b..7e6637c44 100644 --- a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiProperties.java +++ b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiProperties.java @@ -103,6 +103,8 @@ public interface SmallryeOpenApiProperties { Property getInfoDescription(); + Property getInfoSummary(); + Property getInfoTermsOfService(); Property getInfoContactEmail(); diff --git a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiTask.java b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiTask.java index bb559088c..e982d36a6 100644 --- a/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiTask.java +++ b/tools/gradle-plugin/src/main/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiTask.java @@ -370,6 +370,13 @@ public Property getInfoTermsOfService() { return properties.infoTermsOfService; } + @Input + @Optional + @Override + public Property getInfoSummary() { + return properties.infoSummary; + } + @Input @Optional @Override diff --git a/tools/gradle-plugin/src/test/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiPluginTest.java b/tools/gradle-plugin/src/test/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiPluginTest.java index 2d992dd5d..95b5b5a60 100644 --- a/tools/gradle-plugin/src/test/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiPluginTest.java +++ b/tools/gradle-plugin/src/test/java/io/smallrye/openapi/gradleplugin/SmallryeOpenApiPluginTest.java @@ -71,7 +71,7 @@ void taskPropertiesInheritance() { ext.applicationPathDisable.set(true); ext.configProperties.set(new File("/foo/bar")); ext.encoding.set("ISO-8859-1"); - ext.openApiVersion.set("3.0.0"); + ext.openApiVersion.set("999.999.999"); //intentionally invalid ext.customSchemaRegistryClass.set("foo.bar.Baz"); ext.filter.set("filter"); ext.infoContactEmail.set("info-email"); @@ -82,6 +82,7 @@ void taskPropertiesInheritance() { ext.infoLicenseUrl.set("info-license-url"); ext.infoTermsOfService.set("info-tos"); ext.infoTitle.set("info-title"); + ext.infoSummary.set("info-summary"); ext.infoVersion.set("info-version"); ext.modelReader.set("model-reader"); ext.operationIdStrategy.set(OperationIdStrategy.CLASS_METHOD); @@ -112,6 +113,7 @@ void taskPropertiesInheritance() { SmallryeOpenApiProperties::getInfoDescription, SmallryeOpenApiProperties::getInfoLicenseName, SmallryeOpenApiProperties::getInfoLicenseUrl, + SmallryeOpenApiProperties::getInfoSummary, SmallryeOpenApiProperties::getInfoTermsOfService, SmallryeOpenApiProperties::getInfoTitle, SmallryeOpenApiProperties::getInfoVersion, @@ -193,12 +195,13 @@ void smokeProject(Path buildDir, boolean withQuarkus, String taskName, String ou "}", "", "smallryeOpenApi {", - " openApiVersion.set(\"3.0.2\")", + " openApiVersion.set(\"999.999.999\")", //Intentionally invalid " schemaFilename.set(\"my-openapi-schema-file\")", " infoTitle.set(\"Info Title\")", " infoVersion.set(\"Info Version\")", " infoDescription.set(\"Info Description\")", " infoTermsOfService.set(\"Info TOS\")", + " infoSummary.set(\"Info Summary\")", " infoContactEmail.set(\"Info Email\")", " infoContactName.set(\"Info Contact\")", " infoContactUrl.set(\"https://github.com/smallrye/smallrye-open-api/issues/1231\")", @@ -287,13 +290,14 @@ private static void checkGeneratedFiles(Path buildDir, String expectedOutputFile JsonNode root = new ObjectMapper().readValue( targetOpenapiDir.resolve("my-openapi-schema-file.json").toUri().toURL(), JsonNode.class); - assertThat(root.get("openapi").asText()).isEqualTo("3.0.2"); + assertThat(root.get("openapi").asText()).isEqualTo("999.999.999"); assertThat(root.get("x-smallrye-gradle-generated").booleanValue()).isTrue(); JsonNode info = root.get("info"); assertThat(info).isNotNull(); assertThat(info.get("title").asText()).isEqualTo("Info Title"); assertThat(info.get("description").asText()).isEqualTo("Info Description"); + assertThat(info.get("summary").asText()).isEqualTo("Info Summary"); assertThat(info.get("termsOfService").asText()).isEqualTo("Info TOS"); assertThat(info.get("version").asText()).isEqualTo("Info Version"); assertThat(info.get("contact").get("email").asText()).isEqualTo("Info Email"); diff --git a/tools/maven-plugin/pom.xml b/tools/maven-plugin/pom.xml index 97e288458..5e881350e 100644 --- a/tools/maven-plugin/pom.xml +++ b/tools/maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.smallrye smallrye-open-api-tools - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-maven-plugin maven-plugin diff --git a/tools/maven-plugin/src/main/java/io/smallrye/openapi/mavenplugin/GenerateSchemaMojo.java b/tools/maven-plugin/src/main/java/io/smallrye/openapi/mavenplugin/GenerateSchemaMojo.java index 9f42a81c7..c8de6b7ba 100644 --- a/tools/maven-plugin/src/main/java/io/smallrye/openapi/mavenplugin/GenerateSchemaMojo.java +++ b/tools/maven-plugin/src/main/java/io/smallrye/openapi/mavenplugin/GenerateSchemaMojo.java @@ -195,6 +195,9 @@ public class GenerateSchemaMojo extends AbstractMojo { @Parameter(property = "infoDescription") private String infoDescription; + @Parameter(property = "infoSummary") + private String infoSummary; + @Parameter(property = "infoTermsOfService") private String infoTermsOfService; @@ -363,6 +366,7 @@ private Map getProperties() throws IOException { addToPropertyMap(cp, SmallRyeOASConfig.INFO_TITLE, infoTitle); addToPropertyMap(cp, SmallRyeOASConfig.INFO_VERSION, infoVersion); addToPropertyMap(cp, SmallRyeOASConfig.INFO_DESCRIPTION, infoDescription); + addToPropertyMap(cp, SmallRyeOASConfig.INFO_SUMMARY, infoSummary); addToPropertyMap(cp, SmallRyeOASConfig.INFO_TERMS, infoTermsOfService); addToPropertyMap(cp, SmallRyeOASConfig.INFO_CONTACT_EMAIL, infoContactEmail); addToPropertyMap(cp, SmallRyeOASConfig.INFO_CONTACT_NAME, infoContactName); diff --git a/tools/maven-plugin/src/test/java/io/smallrye/openapi/mavenplugin/BasicIT.java b/tools/maven-plugin/src/test/java/io/smallrye/openapi/mavenplugin/BasicIT.java index 6f332a1b9..5e53ebfeb 100644 --- a/tools/maven-plugin/src/test/java/io/smallrye/openapi/mavenplugin/BasicIT.java +++ b/tools/maven-plugin/src/test/java/io/smallrye/openapi/mavenplugin/BasicIT.java @@ -39,12 +39,14 @@ void basic_info(MavenExecutionResult result) throws IOException { assertEquals(properties.get("infoTitle"), schema.getInfo().getTitle()); assertEquals(properties.get("infoDescription"), schema.getInfo().getDescription()); assertEquals(properties.get("infoTermsOfService"), schema.getInfo().getTermsOfService()); + assertEquals(properties.get("infoSummary"), schema.getInfo().getSummary()); assertEquals(properties.get("infoContactName"), schema.getInfo().getContact().getName()); assertEquals(properties.get("infoContactUrl"), schema.getInfo().getContact().getUrl()); assertEquals(properties.get("infoContactEmail"), schema.getInfo().getContact().getEmail()); assertEquals(properties.get("infoLicenseName"), schema.getInfo().getLicense().getName()); - assertEquals(properties.get("infoLicenseUrl"), - schema.getInfo().getLicense().getUrl()); + assertEquals(properties.get("infoLicenseIdentifier"), + schema.getInfo().getLicense().getIdentifier()); + //The URL is not tested here due to being exclusive with Identifier assertEquals(properties.get("infoVersion"), schema.getInfo().getVersion()); List servers = schema.getServers().stream().map(Server::getUrl).collect(Collectors.toList()); diff --git a/tools/pom.xml b/tools/pom.xml index 1ae4776e2..b8d45c369 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-tools diff --git a/ui/open-api-ui-forms/pom.xml b/ui/open-api-ui-forms/pom.xml index 35e36701a..7f1b0456e 100644 --- a/ui/open-api-ui-forms/pom.xml +++ b/ui/open-api-ui-forms/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-ui-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-ui-forms diff --git a/ui/open-api-ui/pom.xml b/ui/open-api-ui/pom.xml index acc1de252..f1ca12828 100644 --- a/ui/open-api-ui/pom.xml +++ b/ui/open-api-ui/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-ui-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-ui diff --git a/ui/pom.xml b/ui/pom.xml index f08711f18..f2f5f691c 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -5,7 +5,7 @@ io.smallrye smallrye-open-api-parent - 3.12.1-SNAPSHOT + 4.0.0-SNAPSHOT smallrye-open-api-ui-parent