All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openl.rules.ruleservice.jaxrs.OpenApiResource Maven / Gradle / Ivy

There is a newer version: 5.27.9
Show newest version
package org.openl.rules.ruleservice.jaxrs;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.core.util.Yaml;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.servers.Server;
import org.apache.commons.lang3.StringUtils;

import org.openl.rules.openapi.OpenAPIConfiguration;
import org.openl.rules.ruleservice.core.OpenLService;

/**
 * A REST service for providing OpenAPI schema for each OpenL service independently.
 *
 * @author Yury Molchan
 */
@Path("/openapi.{type:json|yaml}")
public class OpenApiResource {

    private final Class app;
    private final ObjectMapper mapper;
    private SoftReference jsonApi; // Cached OpenAPI schema in JSON format
    private SoftReference yamlApi; // Cached OpenAPI schema in YAML format
    private final boolean authenticationEnabled;
    private final OpenLService service;

    OpenApiResource(Class app, ObjectMapper mapper, OpenLService service, boolean authenticationEnabled) {
        this.app = app;
        this.mapper = mapper;
        this.service = service;
        this.authenticationEnabled = authenticationEnabled;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON, "application/yaml"})
    @Operation(hidden = true)
    public Response getOpenAPI(@Context UriInfo uriInfo, @PathParam("type") String type) throws Exception {
        if (StringUtils.isNotBlank(type) && type.trim().equalsIgnoreCase("yaml")) {
            var openAPI = yamlApi != null ? yamlApi.get() : null;
            if (openAPI == null) {
                openAPI = Yaml.mapper().writeValueAsString(getOpenAPI(uriInfo));
                yamlApi = new SoftReference<>(openAPI);
            }
            return Response.status(Response.Status.OK).entity(openAPI).type("application/yaml").build();
        } else {
            var openAPI = jsonApi != null ? jsonApi.get() : null;
            if (openAPI == null) {
                openAPI = Json.mapper().writeValueAsString(getOpenAPI(uriInfo));
                jsonApi = new SoftReference<>(openAPI);
            }
            return Response.status(Response.Status.OK).entity(openAPI).type(MediaType.APPLICATION_JSON_TYPE).build();
        }
    }

    private OpenAPI getOpenAPI(UriInfo uriInfo) throws IOException {
        // Load default configuration
        ObjectMapper openApiMapper = Json.mapper().copy().setDefaultMergeable(true);
        var openAPI = openApiMapper.readValue(getClass().getResource("/openapi-default.json"), OpenAPI.class);
        openAPI.getInfo().setTitle(service.getName());
        var servers = new ArrayList();
        servers.add(new Server().url(StringUtils.substringBeforeLast(uriInfo.getRequestUri().toString(), "/")));
        openAPI.setServers(servers);

        // Load custom override configuration
        // https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration
        var custom = getClass().getResource("/openapi-configuration.json");
        if (custom != null) {
            var res = openApiMapper.readerForUpdating(new ConfigWrapper(openAPI)).readValue(custom);
            openAPI = ((ConfigWrapper) res).openAPI;
        }
        if (authenticationEnabled) {
            openAPI = openApiMapper.readerForUpdating(openAPI).readValue(getClass().getResource("/openapi-security.json"));
        }

        openAPI = OpenAPIConfiguration.generateOpenAPI(openAPI, app, mapper);
        return openAPI;
    }


    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ConfigWrapper {
        public final OpenAPI openAPI;

        public ConfigWrapper(OpenAPI openAPI) {
            this.openAPI = openAPI;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy