in smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/OpenApiConverter.java [419:508]
private <T extends Trait> void addPaths(
Context<T> context,
OpenApi.Builder openApiBuilder,
OpenApiProtocol<T> protocolService,
OpenApiMapper plugin
) {
TopDownIndex topDownIndex = TopDownIndex.of(context.getModel());
Map<String, PathItem.Builder> paths = new HashMap<>();
// Add each operation connected to the service shape to the OpenAPI model.
topDownIndex.getContainedOperations(context.getService()).forEach(shape -> {
OptionalUtils.ifPresentOrElse(protocolService.createOperation(context, shape), result -> {
String method = result.getMethod();
String path = result.getUri();
PathItem.Builder pathItem = paths.computeIfAbsent(result.getUri(), (uri) -> PathItem.builder());
// Mark the operation deprecated if the trait's present.
if (shape.hasTrait(DeprecatedTrait.class)) {
result.getOperation().deprecated(true);
}
// Add security requirements to the operation.
addOperationSecurity(context, result.getOperation(), shape, plugin);
// Add the documentation trait to the operation if present.
shape.getTrait(DocumentationTrait.class)
.map(DocumentationTrait::getValue)
.ifPresent(description -> result.getOperation().description(description));
OperationObject builtOperation = result.getOperation().build();
// Pass the operation through the plugin system.
builtOperation = plugin.updateOperation(context, shape, builtOperation, method, path);
// Add tags that are on the operation.
builtOperation = addOperationTags(context, shape, builtOperation);
// Update each parameter of the operation and rebuild if necessary.
builtOperation = updateParameters(context, shape, builtOperation, method, path, plugin);
// Update each response of the operation and rebuild if necessary.
builtOperation = updateResponses(context, shape, builtOperation, method, path, plugin);
// Update the request body of the operation and rebuild if necessary.
builtOperation = updateRequestBody(context, shape, builtOperation, method, path, plugin);
// Pass the operation through the plugin system for post-processing.
builtOperation = plugin.postProcessOperation(context, shape, builtOperation, method, path);
switch (method.toLowerCase(Locale.ENGLISH)) {
case "get":
pathItem.get(builtOperation);
break;
case "put":
pathItem.put(builtOperation);
break;
case "delete":
pathItem.delete(builtOperation);
break;
case "post":
pathItem.post(builtOperation);
break;
case "patch":
pathItem.patch(builtOperation);
break;
case "head":
pathItem.head(builtOperation);
break;
case "trace":
pathItem.trace(builtOperation);
break;
case "options":
pathItem.options(builtOperation);
break;
default:
LOGGER.warning(String.format(
"The %s HTTP method of `%s` is not supported by OpenAPI",
result.getMethod(), shape.getId()));
}
}, () -> LOGGER.warning(String.format(
"The `%s` operation is not supported by the `%s` protocol (implemented by `%s`), and "
+ "was omitted",
shape.getId(),
protocolService.getClass().getName(),
context.getProtocolTrait().toShapeId()))
);
});
for (Map.Entry<String, PathItem.Builder> entry : paths.entrySet()) {
String pathName = entry.getKey();
// Enact the plugin infrastructure to update the PathItem if necessary.
PathItem pathItem = plugin.updatePathItem(context, pathName, entry.getValue().build());
openApiBuilder.putPath(pathName, pathItem);
}
}