Skip to content

Commit

Permalink
Merge pull request #1977 from smallrye/main-4.0
Browse files Browse the repository at this point in the history
MicroProfile OpenAPI 4.0 to main
  • Loading branch information
MikeEdgar authored Sep 16, 2024
2 parents 069f543 + 3e0af1f commit 710ef7f
Show file tree
Hide file tree
Showing 448 changed files with 7,587 additions and 12,684 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-open-api-parent</artifactId>
<version>3.12.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>smallrye-open-api-core</artifactId>
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/io/smallrye/openapi/api/OpenApiConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public Builder enableStandardFilter(boolean enableStandardFilter) {
* <li>Set a generated value for {@code info.title} if none specified
* <li>Set a generated value for {@code info.version} if none specified
* <li>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
* </ul>
*
* @param defaultRequiredProperties
Expand Down Expand Up @@ -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);
});
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -30,6 +31,7 @@ public class ComponentsImpl extends ExtensibleImpl<Components> implements Compon
private Map<String, SecurityScheme> securitySchemes;
private Map<String, Link> links;
private Map<String, Callback> callbacks;
private Map<String, PathItem> pathItems;

/**
* @see org.eclipse.microprofile.openapi.models.Components#getSchemas()
Expand Down Expand Up @@ -338,4 +340,25 @@ public void removeCallback(String key) {
ModelUtil.remove(this.callbacks, key);
}

@Override
public Map<String, PathItem> getPathItems() {
return ModelUtil.unmodifiableMap(this.pathItems);
}

@Override
public void setPathItems(Map<String, PathItem> pathItems) {
this.pathItems = ModelUtil.replace(pathItems, LinkedHashMap<String, PathItem>::new);
}

@Override
public Components addPathItem(String name, PathItem pathItem) {
this.pathItems = ModelUtil.add(name, pathItem, this.pathItems, LinkedHashMap<String, PathItem>::new);
return this;
}

@Override
public void removePathItem(String name) {
ModelUtil.remove(this.pathItems, name);
}

}
Original file line number Diff line number Diff line change
@@ -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<String, Object> data = new LinkedHashMap<>();

protected MapBasedModelImpl() {
}

/**
* Merge all properties from another map-based model object into this one
* <p>
* 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<String, Object> getDataMap() {
return data;
}

private static <T> void mergeMap(Map<String, T> into, Map<String, T> from, Set<String> nonMergableNames) {
for (Entry<String, T> 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<String, Object>) oldValue, (Map<String, Object>) value, nonMergableNames);
} else if (oldValue instanceof List && !nonMergableNames.contains(name)) {
mergeList((List<Object>) oldValue, (List<Object>) value);
} else if (oldValue instanceof ModelImpl) {
into.put(name, MergeUtil.mergeObjects(oldValue, value));
} else {
into.put(name, value);
}
}
}
}

private static <T> void mergeList(List<T> oldValue, List<T> value) {
Set<T> contents = new HashSet<>(oldValue);
for (T element : value) {
if (!contents.contains(element)) {
oldValue.add(element);
}
}
}

protected <T> void setProperty(String propertyName, T value) {
if (value == null) {
data.remove(propertyName);
} else {
data.put(propertyName, value);
}
}

protected <T> T getProperty(String propertyName, Class<T> type) {
Object result = data.get(propertyName);
if (type.isInstance(result)) {
return type.cast(result);
} else {
return null;
}
}

@SuppressWarnings("unchecked")
protected <T> List<T> getListProperty(String propertyName) {
Object result = data.get(propertyName);
if (result instanceof List) {
return Collections.unmodifiableList((List<T>) result);
} else {
return null;
}
}

protected <T> void setListProperty(String propertyName, List<T> value) {
value = ModelUtil.replace(value, ArrayList::new);
if (value == null) {
data.remove(propertyName);
} else {
data.put(propertyName, value);
}
}

protected <T> void addToListProperty(String propertyName, T value) {
if (value != null) {
Object existing = data.get(propertyName);
List<T> list;
if (existing instanceof List) {
list = (List<T>) existing;
} else {
list = new ArrayList<>();
data.put(propertyName, list);
}
list.add(value);
}
}

protected <T> void removeFromListProperty(String propertyName, T toRemove) {
Object existing = data.get(propertyName);
if (existing instanceof List) {
List<T> list = (List<T>) existing;
ModelUtil.remove(list, toRemove);
}
}

protected <T> void setMapProperty(String propertyName, Map<String, T> value) {
value = ModelUtil.replace(value, HashMap::new);
if (value == null) {
data.remove(propertyName);
} else {
data.put(propertyName, value);
}
}

protected <T> Map<String, T> getMapProperty(String propertyName) {
Object result = data.get(propertyName);
if (result instanceof Map) {
return Collections.unmodifiableMap((Map<String, T>) data.get(propertyName));
} else {
return null;
}
}

protected <T> void addToMapProperty(String propertyName, String key, T value) {
if (value != null) {
Object existing = data.get(propertyName);
Map<String, T> map;
if (existing instanceof Map) {
map = (Map<String, T>) existing;
} else {
map = new HashMap<>();
data.put(propertyName, map);
}
map.put(key, value);
}
}

protected <T> void removeFromMapProperty(String propertyName, String key) {
Object existing = data.get(propertyName);
if (existing instanceof Map) {
Map<String, T> map = (Map<String, T>) 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<String> getNonMergableCollections() {
return Collections.emptySet();
}

}
25 changes: 25 additions & 0 deletions core/src/main/java/io/smallrye/openapi/api/models/OpenAPIImpl.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -26,6 +29,7 @@ public class OpenAPIImpl extends ExtensibleImpl<OpenAPI> implements OpenAPI, Mod
private List<SecurityRequirement> security;
private List<Tag> tags;
private Paths paths;
private Map<String, PathItem> webhooks;
private Components components;

/**
Expand Down Expand Up @@ -226,4 +230,25 @@ public Components getComponents() {
public void setComponents(Components components) {
this.components = components;
}

@Override
public Map<String, PathItem> getWebhooks() {
return ModelUtil.unmodifiableMap(this.webhooks);
}

@Override
public void setWebhooks(Map<String, PathItem> webhooks) {
this.webhooks = ModelUtil.replace(webhooks, LinkedHashMap<String, PathItem>::new);
}

@Override
public OpenAPI addWebhook(String name, PathItem webhook) {
this.webhooks = ModelUtil.add(name, webhook, this.webhooks, LinkedHashMap<String, PathItem>::new);
return this;
}

@Override
public void removeWebhook(String name) {
ModelUtil.remove(this.webhooks, name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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;
}

Expand Down
Loading

0 comments on commit 710ef7f

Please sign in to comment.