use of org.eclipse.microprofile.openapi.models.Operation in project Payara by payara.
the class BaseProcessor method process.
@Override
public OpenAPI process(OpenAPI api, OpenApiConfiguration config) {
// Set the OpenAPI version if it hasn't been set
if (api.getOpenapi() == null) {
api.setOpenapi("3.0.0");
}
// Set the info if it hasn't been set
if (api.getInfo() == null) {
api.setInfo(new InfoImpl().title("Deployed Resources").version("1.0.0"));
}
if (config != null) {
// Add the config specified servers
if (!config.getServers().isEmpty()) {
// Clear all the other servers
api.setServers(new ArrayList<>());
// Add all the specified ones
config.getServers().forEach(serverUrl -> api.addServer(new ServerImpl().url(serverUrl)));
}
// Add the default server if there are none
if (api.getServers().isEmpty()) {
for (URL baseURL : baseURLs) {
api.addServer(new ServerImpl().url(baseURL.toString()).description("Default Server."));
}
}
// Add the path servers
for (Entry<String, Set<String>> entry : config.getPathServerMap().entrySet()) {
// Get the normalised path
String path = normaliseUrl(entry.getKey());
// If the path doesn't exist, create it
if (!api.getPaths().hasPathItem(path)) {
api.getPaths().addPathItem(path, new PathItemImpl());
}
// Clear the current list of servers
api.getPaths().getPathItem(path).setServers(new ArrayList<>());
// Add each url
for (String serverUrl : entry.getValue()) {
api.getPaths().getPathItem(path).addServer(new ServerImpl().url(serverUrl));
}
}
// Add the operation servers
for (Entry<String, Set<String>> entry : config.getOperationServerMap().entrySet()) {
// Find the matching operation
for (PathItem pathItem : api.getPaths().getPathItems().values()) {
for (Operation operation : pathItem.getOperations().values()) {
if (operation.getOperationId().equals(entry.getKey())) {
// Clear the current list of servers
operation.setServers(new ArrayList<>());
// Add each server url to the operation
for (String serverUrl : entry.getValue()) {
operation.addServer(new ServerImpl().url(serverUrl));
}
}
}
}
}
}
removeEmptyPaths(api.getPaths());
return api;
}
use of org.eclipse.microprofile.openapi.models.Operation in project Payara by payara.
the class ModelInvariantsTest method addKeyValueIgnoresNull.
@Test
public void addKeyValueIgnoresNull() {
BiPredicate<Extensible<?>, String> hasExtension = (obj, key) -> obj.getExtensions().containsKey(key);
assertAddIgnoresNull(new CallbackImpl(), Callback::addPathItem, Callback::hasPathItem);
assertAddIgnoresNull(new CallbackImpl(), Callback::addExtension, hasExtension);
assertAddIgnoresNull(new ExampleImpl(), Example::addExtension, hasExtension);
assertAddIgnoresNull(new HeaderImpl(), Header::addExample, (obj, key) -> obj.getExamples().containsKey(key));
assertAddIgnoresNull(new HeaderImpl(), Header::addExtension, hasExtension);
assertAddIgnoresNull(new ContactImpl(), Contact::addExtension, hasExtension);
assertAddIgnoresNull(new InfoImpl(), Info::addExtension, hasExtension);
assertAddIgnoresNull(new LicenseImpl(), License::addExtension, hasExtension);
assertAddIgnoresNull(new LinkImpl(), Link::addParameter, (obj, key) -> obj.getParameters().containsKey(key));
assertAddIgnoresNull(new LinkImpl(), Link::addExtension, hasExtension);
assertAddIgnoresNull(new ContentImpl(), Content::addMediaType, Content::hasMediaType);
assertAddIgnoresNull(new DiscriminatorImpl(), Discriminator::addMapping, (obj, key) -> obj.getMapping().containsKey(key));
assertAddIgnoresNull(new EncodingImpl(), Encoding::addHeader, (obj, key) -> obj.getHeaders().containsKey(key));
assertAddIgnoresNull(new EncodingImpl(), Encoding::addExtension, hasExtension);
assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addEncoding, (obj, key) -> obj.getEncoding().containsKey(key));
assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addExample, (obj, key) -> obj.getExamples().containsKey(key));
assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addExtension, hasExtension);
assertAddIgnoresNull(new SchemaImpl(), Schema::addProperty, (obj, key) -> obj.getProperties().containsKey(key));
assertAddIgnoresNull(new SchemaImpl(), Schema::addExtension, hasExtension);
assertAddIgnoresNull(new XMLImpl(), XML::addExtension, hasExtension);
assertAddIgnoresNull(new ParameterImpl(), Parameter::addExample, (obj, key) -> obj.getExamples().containsKey(key));
assertAddIgnoresNull(new ParameterImpl(), Parameter::addExtension, hasExtension);
assertAddIgnoresNull(new RequestBodyImpl(), RequestBody::addExtension, hasExtension);
assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addHeader, (obj, key) -> obj.getHeaders().containsKey(key));
assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addLink, (obj, key) -> obj.getLinks().containsKey(key));
assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addExtension, hasExtension);
assertAddIgnoresNull(new APIResponsesImpl(), APIResponses::addAPIResponse, APIResponses::hasAPIResponse);
assertAddIgnoresNull(new APIResponsesImpl(), APIResponses::addExtension, hasExtension);
assertAddIgnoresNull(new OAuthFlowImpl(), OAuthFlow::addExtension, hasExtension);
assertAddIgnoresNull(new OAuthFlowsImpl(), OAuthFlows::addExtension, hasExtension);
assertAddIgnoresNull(new SecuritySchemeImpl(), SecurityScheme::addExtension, hasExtension);
assertAddIgnoresNull(new ServerImpl(), Server::addExtension, hasExtension);
assertAddIgnoresNull(new ServerVariableImpl(), ServerVariable::addExtension, hasExtension);
assertAddIgnoresNull(new TagImpl(), Tag::addExtension, hasExtension);
assertAddIgnoresNull(new ComponentsImpl(), Components::addCallback, (obj, key) -> obj.getCallbacks().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addExample, (obj, key) -> obj.getExamples().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addHeader, (obj, key) -> obj.getHeaders().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addLink, (obj, key) -> obj.getLinks().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addParameter, (obj, key) -> obj.getParameters().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addRequestBody, (obj, key) -> obj.getRequestBodies().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addResponse, (obj, key) -> obj.getResponses().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addSchema, (obj, key) -> obj.getSchemas().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addSecurityScheme, (obj, key) -> obj.getSecuritySchemes().containsKey(key));
assertAddIgnoresNull(new ComponentsImpl(), Components::addExtension, hasExtension);
assertAddIgnoresNull(new ExternalDocumentationImpl(), ExternalDocumentation::addExtension, hasExtension);
assertAddIgnoresNull(new OpenAPIImpl(), OpenAPI::addExtension, hasExtension);
assertAddIgnoresNull(new OperationImpl(), Operation::addCallback, (obj, key) -> obj.getCallbacks().containsKey(key));
assertAddIgnoresNull(new OperationImpl(), Operation::addExtension, hasExtension);
assertAddIgnoresNull(new PathItemImpl(), PathItem::addExtension, hasExtension);
assertAddIgnoresNull(new PathsImpl(), Paths::addPathItem, Paths::hasPathItem);
assertAddIgnoresNull(new PathsImpl(), Paths::addExtension, hasExtension);
}
use of org.eclipse.microprofile.openapi.models.Operation in project wildfly-swarm by wildfly-swarm.
the class OpenApiAnnotationScanner method processJaxRsMethod.
/**
* Process a single JAX-RS method to produce an OpenAPI Operation.
* @param openApi
* @param resource
* @param method
* @param methodAnno
* @param methodType
* @param resourceTags
*/
private void processJaxRsMethod(OpenAPIImpl openApi, ClassInfo resource, MethodInfo method, AnnotationInstance methodAnno, HttpMethod methodType, Set<String> resourceTags) {
LOG.debugf("Processing jax-rs method: {0}", method.toString());
// Figure out the path for the operation. This is a combination of the App, Resource, and Method @Path annotations
String path;
if (method.hasAnnotation(OpenApiConstants.DOTNAME_PATH)) {
AnnotationInstance pathAnno = method.annotation(OpenApiConstants.DOTNAME_PATH);
String methodPath = pathAnno.value().asString();
path = makePath(this.currentAppPath, this.currentResourcePath, methodPath);
} else {
path = makePath(this.currentAppPath, this.currentResourcePath);
}
// Get or create a PathItem to hold the operation
PathItem pathItem = ModelUtil.paths(openApi).get(path);
if (pathItem == null) {
pathItem = new PathItemImpl();
ModelUtil.paths(openApi).addPathItem(path, pathItem);
}
// Figure out the current @Produces and @Consumes (if any)
currentConsumes = null;
currentProduces = null;
AnnotationInstance consumesAnno = method.annotation(OpenApiConstants.DOTNAME_CONSUMES);
if (consumesAnno == null) {
consumesAnno = JandexUtil.getClassAnnotation(method.declaringClass(), OpenApiConstants.DOTNAME_CONSUMES);
}
AnnotationInstance producesAnno = method.annotation(OpenApiConstants.DOTNAME_PRODUCES);
if (producesAnno == null) {
producesAnno = JandexUtil.getClassAnnotation(method.declaringClass(), OpenApiConstants.DOTNAME_PRODUCES);
}
if (consumesAnno != null) {
AnnotationValue annotationValue = consumesAnno.value();
if (annotationValue != null) {
currentConsumes = annotationValue.asStringArray();
} else {
currentConsumes = OpenApiConstants.DEFAULT_CONSUMES;
}
}
if (producesAnno != null) {
AnnotationValue annotationValue = producesAnno.value();
if (annotationValue != null) {
currentProduces = annotationValue.asStringArray();
} else {
currentProduces = OpenApiConstants.DEFAULT_PRODUCES;
}
}
Operation operation = new OperationImpl();
// ///////////////////////////////////////
if (method.hasAnnotation(OpenApiConstants.DOTNAME_OPERATION)) {
AnnotationInstance operationAnno = method.annotation(OpenApiConstants.DOTNAME_OPERATION);
// If the operation is marked as hidden, just bail here because we don't want it as part of the model.
if (operationAnno.value(OpenApiConstants.PROP_HIDDEN) != null && operationAnno.value(OpenApiConstants.PROP_HIDDEN).asBoolean()) {
return;
}
// Otherwise, set various bits of meta-data from the values in the @Operation annotation
operation.setSummary(JandexUtil.stringValue(operationAnno, OpenApiConstants.PROP_SUMMARY));
operation.setDescription(JandexUtil.stringValue(operationAnno, OpenApiConstants.PROP_DESCRIPTION));
operation.setOperationId(JandexUtil.stringValue(operationAnno, OpenApiConstants.PROP_OPERATION_ID));
operation.setDeprecated(JandexUtil.booleanValue(operationAnno, OpenApiConstants.PROP_DEPRECATED));
}
// Process tags - @Tag and @Tags annotations combines with the resource tags we've already found (passed in)
// ///////////////////////////////////////
boolean hasOpTags = false;
Set<String> tags = new HashSet<>();
if (method.hasAnnotation(OpenApiConstants.DOTNAME_TAG)) {
hasOpTags = true;
AnnotationInstance tagAnno = method.annotation(OpenApiConstants.DOTNAME_TAG);
if (JandexUtil.isRef(tagAnno)) {
String tagRef = JandexUtil.stringValue(tagAnno, OpenApiConstants.PROP_REF);
tags.add(tagRef);
} else if (JandexUtil.isEmpty(tagAnno)) {
// Nothing to do here. The @Tag() was empty.
} else {
Tag tag = readTag(tagAnno);
if (tag.getName() != null) {
openApi.addTag(tag);
tags.add(tag.getName());
}
}
}
if (method.hasAnnotation(OpenApiConstants.DOTNAME_TAGS)) {
hasOpTags = true;
AnnotationInstance tagsAnno = method.annotation(OpenApiConstants.DOTNAME_TAGS);
AnnotationValue tagsArrayVal = tagsAnno.value();
if (tagsArrayVal != null) {
AnnotationInstance[] tagsArray = tagsArrayVal.asNestedArray();
for (AnnotationInstance tagAnno : tagsArray) {
if (JandexUtil.isRef(tagAnno)) {
String tagRef = JandexUtil.stringValue(tagAnno, OpenApiConstants.PROP_REF);
tags.add(tagRef);
} else {
Tag tag = readTag(tagAnno);
if (tag.getName() != null) {
openApi.addTag(tag);
tags.add(tag.getName());
}
}
}
}
List<String> listValue = JandexUtil.stringListValue(tagsAnno, OpenApiConstants.PROP_REFS);
if (listValue != null) {
tags.addAll(listValue);
}
}
if (!hasOpTags) {
tags.addAll(resourceTags);
}
if (!tags.isEmpty()) {
operation.setTags(new ArrayList<>(tags));
}
// Process @Parameter annotations
// ///////////////////////////////////////
List<AnnotationInstance> parameterAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_PARAMETER, OpenApiConstants.DOTNAME_PARAMETERS);
for (AnnotationInstance annotation : parameterAnnotations) {
Parameter parameter = readParameter(annotation);
if (parameter == null) {
// Param was hidden
continue;
}
AnnotationTarget target = annotation.target();
// If the target is METHOD_PARAMETER, then the @Parameter is on one of the method's arguments (THIS ONE WE CARE ABOUT)
if (target != null && target.kind() == Kind.METHOD_PARAMETER) {
In in = parameterIn(target.asMethodParameter());
parameter.setIn(in);
// if the Parameter model we read does *NOT* have a Schema at this point, then create one from the method argument's type
if (!ModelUtil.parameterHasSchema(parameter)) {
Type paramType = JandexUtil.getMethodParameterType(method, target.asMethodParameter().position());
Schema schema = typeToSchema(paramType);
ModelUtil.setParameterSchema(parameter, schema);
}
} else {
// TODO if the @Parameter is on the method, we could perhaps find the one it refers to by name
// and use its type to create a Schema (if missing)
}
operation.addParameter(parameter);
}
// Now process any jax-rs parameters that were NOT annotated with @Parameter (do not yet exist in the model)
List<Type> parameters = method.parameters();
for (int idx = 0; idx < parameters.size(); idx++) {
JaxRsParameterInfo paramInfo = JandexUtil.getMethodParameterJaxRsInfo(method, idx);
if (paramInfo != null && !ModelUtil.operationHasParameter(operation, paramInfo.name)) {
Type paramType = parameters.get(idx);
Parameter parameter = new ParameterImpl();
parameter.setName(paramInfo.name);
parameter.setIn(paramInfo.in);
parameter.setRequired(true);
Schema schema = typeToSchema(paramType);
parameter.setSchema(schema);
operation.addParameter(parameter);
}
}
// TODO @Parameter can be located on a field - what does that mean?
// TODO need to handle the case where we have @BeanParam annotations
// Process any @RequestBody annotation
// ///////////////////////////////////////
// note: the @RequestBody annotation can be found on a method argument *or* on the method
List<AnnotationInstance> requestBodyAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_REQUEST_BODY, null);
for (AnnotationInstance annotation : requestBodyAnnotations) {
RequestBody requestBody = readRequestBody(annotation);
// TODO if the method argument type is Request, don't generate a Schema!
if (!ModelUtil.requestBodyHasSchema(requestBody)) {
Type requestBodyType = null;
if (annotation.target().kind() == AnnotationTarget.Kind.METHOD_PARAMETER) {
requestBodyType = JandexUtil.getMethodParameterType(method, annotation.target().asMethodParameter().position());
} else if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {
requestBodyType = JandexUtil.getRequestBodyParameterClassType(method);
}
if (requestBodyType != null) {
Schema schema = typeToSchema(requestBodyType);
ModelUtil.setRequestBodySchema(requestBody, schema, currentConsumes);
}
}
operation.setRequestBody(requestBody);
}
// method declares that it @Consumes data
if (operation.getRequestBody() == null && currentConsumes != null) {
Type requestBodyType = JandexUtil.getRequestBodyParameterClassType(method);
if (requestBodyType != null) {
Schema schema = typeToSchema(requestBodyType);
if (schema != null) {
RequestBody requestBody = new RequestBodyImpl();
ModelUtil.setRequestBodySchema(requestBody, schema, currentConsumes);
operation.setRequestBody(requestBody);
}
}
}
// Process @APIResponse annotations
// ///////////////////////////////////////
List<AnnotationInstance> apiResponseAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_API_RESPONSE, OpenApiConstants.DOTNAME_API_RESPONSES);
for (AnnotationInstance annotation : apiResponseAnnotations) {
String responseCode = JandexUtil.stringValue(annotation, OpenApiConstants.PROP_RESPONSE_CODE);
if (responseCode == null) {
responseCode = APIResponses.DEFAULT;
}
APIResponse response = readResponse(annotation);
APIResponses responses = ModelUtil.responses(operation);
responses.addApiResponse(responseCode, response);
}
// If there are no responses from annotations, try to create a response from the method return value.
if (operation.getResponses() == null || operation.getResponses().isEmpty()) {
createResponseFromJaxRsMethod(method, operation);
}
// Process @SecurityRequirement annotations
// /////////////////////////////////////////
List<AnnotationInstance> securityRequirementAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_SECURITY_REQUIREMENT, OpenApiConstants.DOTNAME_SECURITY_REQUIREMENTS);
securityRequirementAnnotations.addAll(JandexUtil.getRepeatableAnnotation(resource, OpenApiConstants.DOTNAME_SECURITY_REQUIREMENT, OpenApiConstants.DOTNAME_SECURITY_REQUIREMENTS));
for (AnnotationInstance annotation : securityRequirementAnnotations) {
SecurityRequirement requirement = readSecurityRequirement(annotation);
if (requirement != null) {
operation.addSecurityRequirement(requirement);
}
}
// Process @Callback annotations
// ///////////////////////////////////////
List<AnnotationInstance> callbackAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_CALLBACK, OpenApiConstants.DOTNAME_CALLBACKS);
Map<String, Callback> callbacks = new LinkedHashMap<>();
for (AnnotationInstance annotation : callbackAnnotations) {
String name = JandexUtil.stringValue(annotation, OpenApiConstants.PROP_NAME);
if (name == null && JandexUtil.isRef(annotation)) {
name = JandexUtil.nameFromRef(annotation);
}
if (name != null) {
callbacks.put(name, readCallback(annotation));
}
if (!callbacks.isEmpty()) {
operation.setCallbacks(callbacks);
}
}
// Process @Server annotations
// /////////////////////////////////
List<AnnotationInstance> serverAnnotations = JandexUtil.getRepeatableAnnotation(method, OpenApiConstants.DOTNAME_SERVER, OpenApiConstants.DOTNAME_SERVERS);
if (serverAnnotations.isEmpty()) {
serverAnnotations.addAll(JandexUtil.getRepeatableAnnotation(method.declaringClass(), OpenApiConstants.DOTNAME_SERVER, OpenApiConstants.DOTNAME_SERVERS));
}
for (AnnotationInstance annotation : serverAnnotations) {
Server server = readServer(annotation);
operation.addServer(server);
}
// /////////////////////////////////////////
switch(methodType) {
case DELETE:
pathItem.setDELETE(operation);
break;
case GET:
pathItem.setGET(operation);
break;
case HEAD:
pathItem.setHEAD(operation);
break;
case OPTIONS:
pathItem.setOPTIONS(operation);
break;
case PATCH:
pathItem.setPATCH(operation);
break;
case POST:
pathItem.setPOST(operation);
break;
case PUT:
pathItem.setPUT(operation);
break;
case TRACE:
pathItem.setTRACE(operation);
break;
default:
break;
}
}
use of org.eclipse.microprofile.openapi.models.Operation in project wildfly-swarm by wildfly-swarm.
the class OpenApiAnnotationScanner method readCallbackOperation.
/**
* Reads a single CallbackOperation annotation.
* @param operationAnno
* @return
*/
private Operation readCallbackOperation(AnnotationInstance annotation) {
if (annotation == null) {
return null;
}
LOG.debug("Processing a single @CallbackOperation annotation.");
Operation operation = new OperationImpl();
operation.setSummary(JandexUtil.stringValue(annotation, OpenApiConstants.PROP_SUMMARY));
operation.setDescription(JandexUtil.stringValue(annotation, OpenApiConstants.PROP_DESCRIPTION));
operation.setExternalDocs(readExternalDocs(annotation.value(OpenApiConstants.PROP_EXTERNAL_DOCS)));
operation.setParameters(readCallbackOperationParameters(annotation.value(OpenApiConstants.PROP_PARAMETERS)));
operation.setRequestBody(readRequestBody(annotation.value(OpenApiConstants.PROP_REQUEST_BODY)));
operation.setResponses(readCallbackOperationResponses(annotation.value(OpenApiConstants.PROP_RESPONSES)));
operation.setSecurity(readSecurity(annotation.value(OpenApiConstants.PROP_SECURITY)));
operation.setExtensions(readExtensions(annotation.value(OpenApiConstants.PROP_EXTENSIONS)));
return operation;
}
Aggregations