Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@
public interface DynamicOpenApi {

Response getOpenApi(
HttpHeaders headers, UriInfo uriInfo, String type, OpenAPISpecFilter specFilter)
throws Exception;
HttpHeaders headers, UriInfo uriInfo, String type, OpenAPISpecFilter specFilter);

Response getOpenApi(
HttpHeaders headers, ServletConfig config, Application app, UriInfo uriInfo, String yaml)
throws Exception;
HttpHeaders headers, ServletConfig config, Application app, UriInfo uriInfo, String yaml);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,61 +48,65 @@
public class DynamicOpenApiImpl extends BaseOpenApiResource
implements DynamicOpenApi, JaxRsConsumer {

private static Logger LOGGER = LoggerFactory.getLogger(DynamicOpenApiImpl.class);
private static Logger logger = LoggerFactory.getLogger(DynamicOpenApiImpl.class);
public static final MediaType YAML_TYPE = new MediaType("application", "yaml");
public static final String YAML = "application/yaml";

private OpenAPI openApiSpec;

@Inject
public DynamicOpenApiImpl() {}
public DynamicOpenApiImpl() {
super();
}

@Override
public Consumer<Set<Object>> getConsumer() {
return this::scan;
}

private synchronized void scan(Set<Object> resources) {
Set<Class<?>> resourceClasses =
resources.stream()
.flatMap(
resource -> {
if (resource instanceof DropwizardResourceConfig.SpecificBinder) {
return ((DropwizardResourceConfig.SpecificBinder) resource)
.getBindings().stream()
.filter(binding -> binding instanceof InstanceBinding)
.map(binding -> ((InstanceBinding<?>) binding).getService().getClass());
}
return Stream.of(resource.getClass());
})
.collect(Collectors.toSet());
Reader reader = new Reader(new OpenAPI());
this.openApiSpec = reader.read(resourceClasses);
openApiSpec.addServersItem(new Server().url("/rest"));
if (Objects.nonNull(openApiSpec.getComponents())) {
openApiSpec
.getComponents()
.addSecuritySchemes(
"JWT",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT"));
private void scan(Set<Object> resources) {
synchronized (this) {
Set<Class<?>> resourceClasses =
resources.stream()
.flatMap(
resource -> {
if (resource instanceof DropwizardResourceConfig.SpecificBinder) {
return ((DropwizardResourceConfig.SpecificBinder) resource)
.getBindings().stream()
.filter(binding -> binding instanceof InstanceBinding)
.map(
binding ->
((InstanceBinding<?>) binding).getService().getClass());
}
return Stream.of(resource.getClass());
})
.collect(Collectors.toSet());
Reader reader = new Reader(new OpenAPI());
this.openApiSpec = reader.read(resourceClasses);
openApiSpec.addServersItem(new Server().url("/rest"));
if (Objects.nonNull(openApiSpec.getComponents())) {
openApiSpec
.getComponents()
.addSecuritySchemes(
"JWT",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT"));
}
openApiSpec.addSecurityItem(new SecurityRequirement().addList("JWT"));
}
openApiSpec.addSecurityItem(new SecurityRequirement().addList("JWT"));
}

@Override
public Response getOpenApi(
HttpHeaders headers, ServletConfig config, Application app, UriInfo uriInfo, String type)
throws Exception {
HttpHeaders headers, ServletConfig config, Application app, UriInfo uriInfo, String type) {
return getOpenApi(headers, uriInfo, type, null);
}

@Override
public Response getOpenApi(
HttpHeaders headers, UriInfo uriInfo, String type, OpenAPISpecFilter specFilter)
throws Exception {
HttpHeaders headers, UriInfo uriInfo, String type, OpenAPISpecFilter specFilter) {
if (openApiSpec == null) {
return Response.status(404).build();
}
Expand All @@ -121,21 +125,29 @@ public Response getOpenApi(
getHeaders(headers));
}

if (StringUtils.isNotBlank(type) && type.trim().equalsIgnoreCase("yaml")) {
return Response.status(Response.Status.OK)
.entity(pretty ? Yaml.pretty(oas) : Yaml.mapper().writeValueAsString(oas))
.type("application/yaml")
.build();
} else {
return Response.status(Response.Status.OK)
.entity(pretty ? Json.pretty(oas) : Json.mapper().writeValueAsString(oas))
.type(MediaType.APPLICATION_JSON_TYPE)
try {
if (StringUtils.isNotBlank(type) && "yaml".equalsIgnoreCase(type.trim())) {
return Response.status(Response.Status.OK)
.entity(pretty ? Yaml.pretty(oas) : Yaml.mapper().writeValueAsString(oas))
.type("application/yaml")
.build();
} else {
return Response.status(Response.Status.OK)
.entity(pretty ? Json.pretty(oas) : Json.mapper().writeValueAsString(oas))
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
}
} catch (com.fasterxml.jackson.core.JsonProcessingException e) {
logger.error("Error serializing OpenAPI spec", e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error serializing OpenAPI spec: " + e.getMessage())
.type(MediaType.TEXT_PLAIN)
.build();
}
}

private static Map<String, List<String>> getQueryParams(MultivaluedMap<String, String> params) {
Map<String, List<String>> output = new HashMap<String, List<String>>();
Map<String, List<String>> output = new HashMap<>();
if (params != null) {
for (String key : params.keySet()) {
List<String> values = params.get(key);
Expand All @@ -146,7 +158,7 @@ private static Map<String, List<String>> getQueryParams(MultivaluedMap<String, S
}

private static Map<String, String> getCookies(HttpHeaders headers) {
Map<String, String> output = new HashMap<String, String>();
Map<String, String> output = new HashMap<>();
if (headers != null) {
for (String key : headers.getCookies().keySet()) {
Cookie cookie = headers.getCookies().get(key);
Expand All @@ -157,7 +169,7 @@ private static Map<String, String> getCookies(HttpHeaders headers) {
}

private static Map<String, List<String>> getHeaders(HttpHeaders headers) {
Map<String, List<String>> output = new HashMap<String, List<String>>();
Map<String, List<String>> output = new HashMap<>();
if (headers != null) {
for (String key : headers.getRequestHeaders().keySet()) {
List<String> values = headers.getRequestHeaders().get(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ public DynamicOpenApiResource(
@Content(mediaType = "text/html", schema = @Schema(type = "string"))
})
})
public Response getApiDescription(@Context HttpHeaders headers, @Context UriInfo uriInfo)
throws Exception {
if (LOGGER.isTraceEnabled())
public Response getApiDescription(@Context HttpHeaders headers, @Context UriInfo uriInfo) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("MIME {} {}", "HTML", headers.getHeaderString("Accept"));
}
return openApiViewerResource.getFile("index.html");
}

Expand All @@ -99,9 +99,10 @@ public Response getApiDescriptionJson(
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
@Context ServletConfig config,
@Context Application app)
throws Exception {
if (LOGGER.isTraceEnabled()) LOGGER.trace("MIME {})", "JSON");
@Context Application app) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("MIME: JSON");
}
return openApi.getOpenApi(headers, config, app, uriInfo, "json");
}

Expand All @@ -113,17 +114,20 @@ public Response getApiDescriptionYaml(
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
@Context ServletConfig config,
@Context Application app)
throws Exception {
if (LOGGER.isTraceEnabled()) LOGGER.trace("MIME {})", "YAML");
@Context Application app) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("MIME: YAML");
}
return openApi.getOpenApi(headers, config, app, uriInfo, "yaml");
}

@GET
@Path("/{file}")
@CacheControl(maxAge = 3600)
public Response getFile(@PathParam("file") String file) {
if (LOGGER.isTraceEnabled()) LOGGER.trace("FILE {})", file);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("FILE: {}", file);
}

if (openApiViewerResource == null) {
throw new NotFoundException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public class MustacheResolverOpenApi extends PerClassMustacheResolver
implements PartialMustacheResolver {

@Inject
MustacheResolverOpenApi() {}
MustacheResolverOpenApi() {
super();
}

@Override
public int getSortPriority() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
@AutoBind
public class OpenApiSwaggerUiResource implements OpenApiViewerResource {

private static Logger LOGGER = LoggerFactory.getLogger(OpenApiSwaggerUiResource.class);
private static Logger logger = LoggerFactory.getLogger(OpenApiSwaggerUiResource.class);

@Inject
public OpenApiSwaggerUiResource() {}
Expand All @@ -46,7 +46,10 @@ public Response getFile(String file) {
.type(getMimeType(file))
.build();
} catch (Throwable e) {
throw new NotFoundException();
if (logger.isWarnEnabled()) {
logger.warn("Error serving file '{}': {}", file, e.toString(), e);
}
throw new NotFoundException(e);
}
}

Expand Down