Adding swagger to schema service apis 14/141614/6 master
authorMithun Menon <mithun.menon@t-systems.com>
Mon, 4 Aug 2025 17:12:54 +0000 (19:12 +0200)
committermithun.menon@t-systems.com <mithun.menon@t-systems.com>
Tue, 12 Aug 2025 08:26:07 +0000 (10:26 +0200)
To add swagger implementation in schema service
Issue-ID: AAI-4196
Change-Id: I8f1f1d1747ae2befbf8376c93eb33b7c54c5a24d
Signed-off-by: tushar.mohanty@t-systems.com <tushar.mohanty@t-systems.com>
Signed-off-by: mithun.menon@t-systems.com <mithun.menon@t-systems.com>
aai-schema-service/pom.xml
aai-schema-service/src/main/java/org/onap/aai/schemaservice/SchemaServiceApp.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/edges/EdgeResource.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/healthcheck/EchoResource.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/nodeschema/NodeSchemaChecksumResource.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/nodeschema/NodeSchemaResource.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/query/QueryResource.java
aai-schema-service/src/main/java/org/onap/aai/schemaservice/versions/VersionResource.java

index 0bc5d4b..498f85c 100644 (file)
@@ -77,6 +77,8 @@
         <schema.uri.base.path>/aai/schema-service</schema.uri.base.path>
         <!-- End of Default ONAP Schema Properties -->
 
+        <!-- Swagger version for open api json creation -->
+           <swagger.version>2.2.35</swagger.version>
     </properties>
     <profiles>
         <!-- Docker profile to be used for building docker image and pushing to nexus -->
             <artifactId>logstash-logback-encoder</artifactId>
             <version>6.6</version>
         </dependency>
+        <dependency>
+            <groupId>io.swagger.core.v3</groupId>
+            <artifactId>swagger-jaxrs2</artifactId>
+           <version>${swagger.version}</version>
+        </dependency>
     </dependencies>
     <build>
         <resources>
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>io.swagger.core.v3</groupId>
+                <artifactId>swagger-maven-plugin</artifactId>
+                       <version>${swagger.version}</version>
+                <executions>
+                    <execution>
+                        <id>generate-openapi</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>resolve</goal>
+                        </goals>
+                        <configuration>
+                            <attachSwaggerArtifact>false</attachSwaggerArtifact>
+                            <outputPath>${project.build.directory}/generated-swagger-docs</outputPath>
+                            <outputFileName>openapi</outputFileName>
+                            <outputFormat>JSON</outputFormat>
+                            <resourcePackages>
+                                <resourcePackage>org.onap.aai.schemaservice</resourcePackage>
+                            </resourcePackages>
+                            <prettyPrint>true</prettyPrint>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
     <reporting>
index 65232be..74f7095 100644 (file)
@@ -38,6 +38,9 @@ import org.springframework.context.annotation.ComponentScan;
 import org.springframework.core.env.Environment;
 import org.springframework.core.env.Profiles;
 
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.info.Info;
+
 @SpringBootApplication
 // Component Scan provides a way to look for spring beans
 // It only searches beans in the following packages
@@ -47,6 +50,7 @@ import org.springframework.core.env.Profiles;
     exclude = {DataSourceAutoConfiguration.class,
         DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
 @ComponentScan(basePackages = {"org.onap.aai.schemaservice", "org.onap.aai.aaf"})
+@OpenAPIDefinition(info = @Info(title = "ONAP Schema Service APIs", description = "Provides schema management and validation APIs for ONAP components.", version = "1.0.0"))
 public class SchemaServiceApp {
 
     private static final Logger logger = LoggerFactory.getLogger(SchemaServiceApp.class.getName());
index 5147ece..79aba4c 100644 (file)
 package org.onap.aai.schemaservice.edges;
 
 import com.google.gson.Gson;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 
 import java.util.Optional;
@@ -46,6 +52,7 @@ import org.springframework.web.bind.annotation.RestController;
 @Path("/v1")
 @RestController
 @RequiredArgsConstructor
+@Tag(name = "ONAP Schema Service - Edge Rules", description = "Provides access to ONAP edge rules for a given schema version in JSON format.")
 public class EdgeResource extends RESTAPI {
 
     private final EdgeService edgeService;
@@ -54,7 +61,15 @@ public class EdgeResource extends RESTAPI {
 
     @GET
     @Path("/edgerules")
-    @Produces({"application/json"})
+    @Produces({ "application/json" })
+    @Operation(summary = "Retrieve edge rules by version", description = "Returns the JSON-formatted edge rules for the specified ONAP schema version.", parameters = {
+            @Parameter(name = "version", description = "Schema version", required = true, example = "v30")
+    }, responses = {
+            @ApiResponse(responseCode = "200", description = "Edge rules retrieved successfully", content = @Content(mediaType = "application/json")),
+            @ApiResponse(responseCode = "400", description = "Missing or invalid version", content = @Content(mediaType = "application/json")),
+            @ApiResponse(responseCode = "404", description = "Edge rules not found", content = @Content(mediaType = "application/json")),
+            @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = "application/json"))
+    })
     public Response retrieveSchema(@QueryParam("version") String version,
         @Context HttpHeaders headers, @Context UriInfo info) {
         Response response = null;
index 97aa2e2..9c702e4 100644 (file)
@@ -35,82 +35,102 @@ import org.onap.aai.logging.ErrorLogHelper;
 import org.onap.aai.restcore.RESTAPI;
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 /**
  * The Class EchoResponse.
  */
 @Path("/util")
 @RestController
+@Tag(name = "Health Check", description = "Endpoints for verifying service availability and connectivity.")
 public class EchoResource extends RESTAPI {
 
-    /**
-     * Simple health-check API that echos back the X-FromAppId and X-TransactionId to clients.
-     * If there is a query string, a transaction gets logged into hbase, proving the application is
-     * connected to the data store.
-     * If there is no query string, no transaction logging is done to hbase.
-     *
-     * @param headers the headers
-     * @param req the req
-     * @param uriInfo uri information
-     * @return the response
-     */
-    @GET
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/echo")
-    public Response echoResult(@Context HttpHeaders headers, @Context HttpServletRequest req,
-        @Context UriInfo uriInfo) {
-        Response response = null;
-
-        AAIException ex = null;
-        String fromAppId = null;
-        String transId = null;
-
-        try {
-            fromAppId = getFromAppId(headers);
-            transId = getTransId(headers);
-        } catch (AAIException e) {
-            ArrayList<String> templateVars = new ArrayList<String>();
-            templateVars.add("Headers missing");
-            return Response
-                .status(e.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper
-                    .getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
-                .build();
-        }
-
-        try {
-
-            HashMap<AAIException, ArrayList<String>> exceptionList =
-                new HashMap<AAIException, ArrayList<String>>();
-
-            ArrayList<String> templateVars = new ArrayList<String>();
-            templateVars.add(fromAppId);
-            templateVars.add(transId);
-
-            exceptionList.put(new AAIException("AAI_0002", "OK"), templateVars);
-
-            response = Response
-                .status(Status.OK).entity(ErrorLogHelper
-                    .getRESTAPIInfoResponse(new ArrayList<>(headers.getAcceptableMediaTypes()), exceptionList))
-                .build();
-
-        } catch (Exception e) {
-            ex = new AAIException("AAI_4000", e);
-            ArrayList<String> templateVars = new ArrayList<String>();
-            templateVars.add(Action.GET.name());
-            templateVars.add(fromAppId + " " + transId);
-
-            response = Response
-                .status(Status.INTERNAL_SERVER_ERROR).entity(ErrorLogHelper
-                    .getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
-                .build();
-
-        } finally {
-            if (ex != null) {
-                ErrorLogHelper.logException(ex);
-            }
-
+        /**
+         * Simple health-check API that echos back the X-FromAppId and X-TransactionId
+         * to clients.
+         * If there is a query string, a transaction gets logged into hbase, proving the
+         * application is
+         * connected to the data store.
+         * If there is no query string, no transaction logging is done to hbase.
+         *
+         * @param headers the headers
+         * @param req     the req
+         * @param uriInfo uri information
+         * @return the response
+         */
+        @GET
+        @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+        @Path("/echo")
+        @Operation(summary = "Health check endpoint", description = "Echos back the X-FromAppId and X-TransactionId headers. If a query string is provided, it logs a transaction to the data store; otherwise, no logging occurs.", responses = {
+                        @ApiResponse(responseCode = "200", description = "Health check successful; IDs echoed back", content = {
+                                        @Content(mediaType = "application/xml"),
+                                        @Content(mediaType = "application/json")
+                        }),
+                        @ApiResponse(responseCode = "400", description = "Missing required headers", content = @Content(mediaType = "application/json")),
+                        @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = "application/json"))
+        })
+        public Response echoResult(@Context HttpHeaders headers, @Context HttpServletRequest req,
+                        @Context UriInfo uriInfo) {
+                Response response = null;
+
+                AAIException ex = null;
+                String fromAppId = null;
+                String transId = null;
+
+                try {
+                        fromAppId = getFromAppId(headers);
+                        transId = getTransId(headers);
+                } catch (AAIException e) {
+                        ArrayList<String> templateVars = new ArrayList<String>();
+                        templateVars.add("Headers missing");
+                        return Response
+                                        .status(e.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper
+                                                        .getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
+                                                                        templateVars))
+                                        .build();
+                }
+
+                try {
+
+                        HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<AAIException, ArrayList<String>>();
+
+                        ArrayList<String> templateVars = new ArrayList<String>();
+                        templateVars.add(fromAppId);
+                        templateVars.add(transId);
+
+                        exceptionList.put(new AAIException("AAI_0002", "OK"), templateVars);
+
+                        response = Response
+                                        .status(Status.OK).entity(ErrorLogHelper
+                                                        .getRESTAPIInfoResponse(
+                                                                        new ArrayList<>(headers
+                                                                                        .getAcceptableMediaTypes()),
+                                                                        exceptionList))
+                                        .build();
+
+                } catch (Exception e) {
+                        ex = new AAIException("AAI_4000", e);
+                        ArrayList<String> templateVars = new ArrayList<String>();
+                        templateVars.add(Action.GET.name());
+                        templateVars.add(fromAppId + " " + transId);
+
+                        response = Response
+                                        .status(Status.INTERNAL_SERVER_ERROR).entity(ErrorLogHelper
+                                                        .getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex,
+                                                                        templateVars))
+                                        .build();
+
+                } finally {
+                        if (ex != null) {
+                                ErrorLogHelper.logException(ex);
+                        }
+
+                }
+
+                return response;
         }
 
-        return response;
-    }
-
 }
index e3b57df..f644bef 100644 (file)
@@ -18,7 +18,6 @@
  * ============LICENSE_END=========================================================
  */
 
-
 package org.onap.aai.schemaservice.nodeschema;
 
 import java.util.Map;
@@ -37,8 +36,15 @@ import javax.ws.rs.core.UriInfo;
 
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 @Path("/v1")
 @RestController
+@Tag(name = "ONAP Schema Service - Checksums", description = "Provides checksum values for different schema versions used in ONAP.")
 public class NodeSchemaChecksumResource {
 
     private final NodeSchemaService nodeSchemaService;
@@ -47,16 +53,19 @@ public class NodeSchemaChecksumResource {
     public NodeSchemaChecksumResource(NodeSchemaService nodeSchemaService, SchemaVersions schemaVersions) {
         this.nodeSchemaService = nodeSchemaService;
         Map<SchemaVersion, Long> checksumMap = schemaVersions.getVersions().stream()
-            .collect(Collectors.toMap(
-                version -> version,
-                version -> getChecksumForSchemaVersion(version))
-            );
+                .collect(Collectors.toMap(
+                        version -> version,
+                        version -> getChecksumForSchemaVersion(version)));
         checksumResponse = new ChecksumResponse(checksumMap);
     }
 
     @GET
     @Path("/nodes/checksums")
-    @Produces({"application/json"})
+    @Produces({ "application/json" })
+    @Operation(summary = "Get schema checksums by version", description = "Returns a map of schema versions to their CRC32 checksum values for ONAP schema service.", responses = {
+            @ApiResponse(responseCode = "200", description = "Checksum data retrieved successfully", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ChecksumResponse.class))),
+            @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = "application/json"))
+    })
     public Response getChecksumByVersion(@Context HttpHeaders headers, @Context UriInfo info) {
         return Response.ok(checksumResponse).build();
     }
index bab6711..ccb46cd 100644 (file)
@@ -38,8 +38,15 @@ import org.onap.aai.schemaservice.nodeschema.validation.AAISchemaValidationExcep
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 @Path("/v1")
 @RestController
+@Tag(name = "ONAP Schema Service - Node Schemas", description = "Provides access to specific ONAP node schemas in XML format.")
 public class NodeSchemaResource extends RESTAPI {
 
     private final NodeSchemaService nodeSchemaService;
@@ -53,9 +60,17 @@ public class NodeSchemaResource extends RESTAPI {
 
     @GET
     @Path("/nodes")
-    @Produces({"application/xml"})
+    @Produces({ "application/xml" })
+    @Operation(summary = "Retrieve node schema by version", description = "Returns the XML schema for the specified ONAP node schema version.", parameters = {
+            @Parameter(name = "version", description = "Schema version", required = true, example = "v30")
+    }, responses = {
+            @ApiResponse(responseCode = "200", description = "Schema retrieved successfully", content = @Content(mediaType = "application/xml")),
+            @ApiResponse(responseCode = "400", description = "Missing or invalid version", content = @Content(mediaType = "application/json")),
+            @ApiResponse(responseCode = "404", description = "Schema not found", content = @Content(mediaType = "application/json")),
+            @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = "application/json"))
+    })
     public Response retrieveSchema(@QueryParam("version") String version,
-        @Context HttpHeaders headers, @Context UriInfo info) {
+            @Context HttpHeaders headers, @Context UriInfo info) {
         Response response;
         Optional<String> optionalSchema = nodeSchemaService.fetch(version);
         try {
@@ -80,10 +95,10 @@ public class NodeSchemaResource extends RESTAPI {
             response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex);
         } catch (AAISchemaValidationException ex) {
             response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET,
-                new AAIException("AAI_3051", version));
+                    new AAIException("AAI_3051", version));
         } catch (Exception ex) {
             response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET,
-                new AAIException("AAI_4000"));
+                    new AAIException("AAI_4000"));
         }
 
         return response;
index 2f13b5b..086fae9 100644 (file)
@@ -26,17 +26,25 @@ import javax.ws.rs.core.Response;
 
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 
 @Path("/v1")
 @RestController
 @RequiredArgsConstructor
+@Tag(name = "ONAP Schema Service - Queries", description = "APIs to retrieve stored queries for ONAP schema service.")
 public class QueryResource {
 
     private final QueryService queryService;
 
     @GET
     @Path("/stored-queries")
+    @Operation(summary = "Retrieve stored queries", description = "Returns the list of stored queries available in the system.", responses = {
+            @ApiResponse(responseCode = "200", description = "List retrieved successfully", content = @Content(mediaType = "application/json"))
+    })
     public Response retrieveStoredQueries() {
         return Response.ok().entity(queryService.getStoredQueries()).build();
     }
index 80ba0db..ee676c1 100644 (file)
@@ -22,6 +22,10 @@ package org.onap.aai.schemaservice.versions;
 
 import com.google.gson.Gson;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 
 import javax.ws.rs.GET;
@@ -35,6 +39,7 @@ import org.springframework.web.bind.annotation.RestController;
 @Path("/v1")
 @RestController
 @RequiredArgsConstructor
+@Tag(name = "ONAP Schema Service - Version Info", description = "Provides version details for the ONAP schema service application.")
 public class VersionResource {
 
     private final VersionService versionService;
@@ -42,7 +47,10 @@ public class VersionResource {
 
     @GET
     @Path("/versions")
-    @Produces({MediaType.APPLICATION_JSON})
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Get version information", description = "Returns version details for the application.", responses = {
+            @ApiResponse(responseCode = "200", description = "Version information retrieved successfully", content = @Content(mediaType = "application/json"))
+    })
     public Response getVersions() {
         return Response.ok(gson.toJson(versionService.getVersionInfo())).build();
     }