generating swagger-ui and controller interface using openapi.yml 25/122825/4
authorRenu Kumari <renu.kumari@bell.ca>
Thu, 22 Jul 2021 15:53:53 +0000 (11:53 -0400)
committerRenu Kumari <renu.kumari@bell.ca>
Fri, 23 Jul 2021 12:39:12 +0000 (08:39 -0400)
Issue-ID: CPS-387
Signed-off-by: Renu Kumari <renu.kumari@bell.ca>
Change-Id: I3e9742407148efcb16d8d79411e4de6738796f86

README.md
docs/api/swagger/openapi.yml
pom.xml
src/main/java/org/onap/cps/temporal/controller/rest/QueryController.java [new file with mode: 0644]
src/main/java/org/onap/cps/temporal/controller/web/QueryController.java [deleted file]
src/main/resources/application.yml
src/test/groovy/org/onap/cps/temporal/controller/rest/QueryControllerSpec.groovy [new file with mode: 0644]
src/test/groovy/org/onap/cps/temporal/controller/web/QueryControllerSpec.groovy [deleted file]
src/test/resources/application.yml

index 681634d..0a9adfa 100755 (executable)
--- a/README.md
+++ b/README.md
@@ -106,3 +106,10 @@ mvn org.liquibase:liquibase-maven-plugin:4.3.2:update \
   -Dliquibase.password=cpstemporal \
   -Dliquibase.changeLogFile=db/changelog/changelog-master.xml
 ```
+
+## Accessing services
+
+Swagger UI is available to discover service endpoints and send requests.
+
+* `http://localhost:<port-number>/swagger-ui.html`
+
index a8c27e6..9a133a3 100644 (file)
@@ -1,3 +1,21 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 Bell Canada.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
 openapi: 3.0.1
 info:
   title: ONAP Open API v3 Configuration Persistence Service - Temporal
@@ -13,7 +31,7 @@ info:
   x-planned-retirement-date: '202212'
   x-component: Modeling
 servers:
-  - url: '//localhost:8088/cps-temporal/api'
+  - url: '/cps-temporal/api'
 tags:
   - name: cps-temporal-query
     description: CPS Temporal Query
@@ -45,7 +63,19 @@ paths:
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/AnchorDataByNameResponse'
+                $ref: '#/components/schemas/AnchorHistory'
+              example:
+                nextRecordsLink: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=2
+                previousRecordsLink: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=0
+                records:
+                  - timestamp: '2021-03-21T00:00:00.000000-0:00'
+                    dataspace: my-dataspace
+                    schemaSet: my-schema-set
+                    anchor: my-anchor
+                    data:
+                      status: UP
+
+
         '400':
           $ref: '#/components/responses/BadRequest'
         '401':
@@ -61,7 +91,7 @@ paths:
       operationId: getAnchorsDataByFilter
       parameters:
         - $ref: '#/components/parameters/dataspaceName'
-        - name: schemaset-name
+        - name: schema-set-name
           in: query
           description: Schema-set name
           required: true
@@ -79,7 +109,18 @@ paths:
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/AnchorsDataByFilterResponse'
+                $ref: '#/components/schemas/AnchorHistory'
+              example:
+                nextRecordsLink: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=2
+                previousRecordsLink: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=0
+                records:
+                  - timestamp: '2021-03-21T00:00:00.000000-0:00'
+                    dataspace: my-dataspace
+                    schemaSet: my-schema-set
+                    anchor: my-anchor
+                    data:
+                      status: UP
+
         '400':
           $ref: '#/components/responses/BadRequest'
         '401':
@@ -165,6 +206,26 @@ components:
           schema:
             $ref: '#/components/schemas/ErrorMessage'
   schemas:
+    AnchorDetails:
+      type: object
+      title: AnchorDetails
+      properties:
+        timestamp:
+          type: string
+          format: date-time
+          example: '2021-03-21T00:00:00.000000-0:00'
+        dataspace:
+          type: string
+          example: 'my-dataspace'
+        schemaSet:
+          type: string
+          example: 'my-schema-set'
+        anchor:
+          type: string
+          example: 'my-anchor'
+        data:
+          type: object
+          example: { "status" : "UP" }
     AnchorHistory:
       type: object
       title: AnchorHistory
@@ -178,51 +239,9 @@ components:
         records:
           type: array
           items:
-            type: object
-            properties:
-              timestamp:
-                type: string
-                format: date-time
-                example: '2021-03-21T00:00:00.000000-0:00'
-              dataspace:
-                type: string
-                example: 'my-dataspace'
-              schemaSet:
-                type: string
-                example: 'my-schema-set'
-              anchor:
-                type: string
-                example: 'my-anchor'
-              data:
-                type: object
-                example: { "status" : "UP" }
+            $ref: '#/components/schemas/AnchorDetails'
       required:
         - records
-
-    AnchorsDataByFilterResponse:
-      allOf:     # Combines the BasicErrorModel and the inline model
-        - $ref: '#/components/schemas/AnchorHistory'
-        - title: getAnchorDataByNameResponse
-          properties:
-            nextRecordsLink:
-              type: string
-              example: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=2
-            previousRecordsLink:
-              type: string
-              example: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=0
-
-    AnchorDataByNameResponse:
-      allOf:     # Combines the BasicErrorModel and the inline model
-        - $ref: '#/components/schemas/AnchorHistory'
-        - title: getAnchorDataByNameResponse
-          properties:
-            nextRecordsLink:
-              type: string
-              example: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=2
-            previousRecordsLink:
-              type: string
-              example: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=0
-
     ErrorMessage:
       type: object
       title: Error
diff --git a/pom.xml b/pom.xml
index 161c7e5..5f82356 100755 (executable)
--- a/pom.xml
+++ b/pom.xml
@@ -15,6 +15,8 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
+
+ SPDX-License-Identifier: Apache-2.0
   ============LICENSE_END=========================================================
 -->
 
@@ -36,7 +38,6 @@
     <description>CPS Temporal Service</description>
 
     <properties>
-        <app>org.onap.cps.temporal.Application</app>
         <docker.repository.pull>nexus3.onap.org:10001/</docker.repository.pull>
         <docker.repository.push>nexus3.onap.org:10003/</docker.repository.push>
         <image.base>${docker.repository.pull}onap/integration-java11:8.0.0</image.base>
@@ -45,7 +46,8 @@
         <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
         <minimum-coverage>0.8</minimum-coverage>
         <!-- Application dependencies versions -->
-        <cps.version>1.0.1</cps.version>
+        <!--cps.version need to be changed to released Istanbul version-->
+        <cps.version>1.1.0-SNAPSHOT</cps.version>
         <mapstruct.version>1.4.2.Final</mapstruct.version>
     </properties>
 
             <artifactId>cps-events</artifactId>
             <version>1.1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-ui</artifactId>
+            <version>1.5.9</version>
+        </dependency>
         <!-- Runtime dependencies-->
         <dependency>
             <groupId>org.postgresql</groupId>
     </dependencies>
 
     <build>
+        <resources>
+            <resource>
+                <directory>docs/api</directory>
+                <targetPath>static</targetPath>
+                <filtering>true</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <version>2.3.3.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>build-info</goal>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
             </plugin>
             <plugin>
                 <!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
                       to 'Low'.
                     -->
                     <effort>Max</effort>
+                    <addSourceDirs>true</addSourceDirs>
                     <!-- Reports all bugs (other values are medium and max) -->
                     <threshold>Low</threshold>
                     <!-- Build doesn't fail if problems are found -->
                             <goal>check</goal>
                         </goals>
                         <configuration>
+                            <excludes>
+                                <exclude>org/onap/cps/temporal/controller/rest/model/*</exclude>
+                            </excludes>
                             <dataFile>${project.build.directory}/code-coverage/jacoco-ut.exec</dataFile>
                             <rules>
                                 <rule>
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>io.swagger.codegen.v3</groupId>
+                <artifactId>swagger-codegen-maven-plugin</artifactId>
+                <version>3.0.27</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <inputSpec>${project.basedir}/docs/api/swagger/openapi.yml</inputSpec>
+                            <invokerPackage>org.onap.cps.temporal.controller.rest</invokerPackage>
+                            <modelPackage>org.onap.cps.temporal.controller.rest.model</modelPackage>
+                            <apiPackage>org.onap.cps.temporal.controller.rest</apiPackage>
+                            <language>spring</language>
+                            <generateSupportingFiles>false</generateSupportingFiles>
+                            <configOptions>
+                                <sourceFolder>src/gen/java</sourceFolder>
+                                <dateLibrary>java11</dateLibrary>
+                                <interfaceOnly>true</interfaceOnly>
+                                <useTags>true</useTags>
+                            </configOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
 
        <pluginManagement>
diff --git a/src/main/java/org/onap/cps/temporal/controller/rest/QueryController.java b/src/main/java/org/onap/cps/temporal/controller/rest/QueryController.java
new file mode 100644 (file)
index 0000000..e7171a0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2021 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.temporal.controller.rest;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.onap.cps.temporal.controller.rest.model.AnchorHistory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${rest.api.base-path}")
+public class QueryController implements CpsTemporalQueryApi {
+
+    @Override
+    public ResponseEntity<AnchorHistory> getAnchorDataByName(final String dataspaceName,
+        final String anchorName, final @Valid String after, final @Valid String simplePayloadFilter,
+        final @Valid String pointInTime, final @Min(0) @Valid Integer pageNumber,
+        final @Min(0) @Max(10000) @Valid Integer pageLimit, final @Valid String sort) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+    @Override
+    public ResponseEntity<AnchorHistory> getAnchorsDataByFilter(final String dataspaceName,
+        final @NotNull @Valid String schemaSetName, final @Valid String after, final @Valid String simplePayloadFilter,
+        final @Valid String pointInTime, final @Min(0) @Valid Integer pageNumber,
+        final @Min(0) @Max(10000) @Valid Integer pageLimit, final @Valid String sort) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+}
diff --git a/src/main/java/org/onap/cps/temporal/controller/web/QueryController.java b/src/main/java/org/onap/cps/temporal/controller/web/QueryController.java
deleted file mode 100644 (file)
index fae95cc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.temporal.controller.web;
-
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Controller for query requests.
- */
-@RestController
-public class QueryController {
-
-    @GetMapping("/")
-    public String home() {
-        return "Welcome to CPS Temporal Service!";
-    }
-
-}
index 5fe30b0..0b41a07 100755 (executable)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
 # ============LICENSE_END=========================================================
 
 server:
     port: 8080
 
+rest:
+    api:
+        base-path: /cps-temporal/api
+
 spring:
     datasource:
         url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/cpstemporaldb
@@ -50,3 +56,11 @@ app:
     listener:
         data-updated:
             topic: ${CPS_CHANGE_EVENT_TOPIC:cps.cfg-state-events}
+
+springdoc:
+    swagger-ui:
+        disable-swagger-default-url: true
+        urlsPrimaryName: query
+        urls:
+            - name: query
+              url: /swagger/openapi.yml
diff --git a/src/test/groovy/org/onap/cps/temporal/controller/rest/QueryControllerSpec.groovy b/src/test/groovy/org/onap/cps/temporal/controller/rest/QueryControllerSpec.groovy
new file mode 100644 (file)
index 0000000..771a3fc
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2021 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.temporal.controller.rest
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
+import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
+import org.springframework.test.web.servlet.MockMvc
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+
+import spock.lang.Specification
+
+/**
+ * Specification for Query Controller.
+ */
+@WebMvcTest(QueryController)
+class QueryControllerSpec extends Specification {
+
+    @Autowired
+    MockMvc mvc
+
+    @Value('${rest.api.base-path}')
+    def basePath
+
+    def myDataspace = 'my-dataspace'
+    def myAnchor = 'my-anchor'
+    def mySchemaset = 'my-schemaset'
+
+    def 'Get anchors by name is not implemented.'(){
+        given: 'an endpoint'
+            def getAnchorsByNameEndpoint = "${basePath}/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/history"
+
+        when: 'get anchors by name endpoint is called'
+            def response = mvc.perform( get(getAnchorsByNameEndpoint, myDataspace, myAnchor)
+                    .contentType(MediaType.APPLICATION_JSON))
+                    .andReturn().response
+
+        then: 'received unsupported operation response'
+            response.getStatus() == HttpStatus.NOT_IMPLEMENTED.value()
+
+    }
+
+    def 'Get anchors by dataspace name is not implemented.'(){
+        given: 'an endpoint'
+            def getAnchorsByDataspaceEndpoint = "${basePath}/v1/dataspaces/{dataspace-name}/anchors/history"
+
+        when: 'get anchors by dataspace name endpoint is called'
+            def response = mvc.perform( get(getAnchorsByDataspaceEndpoint, myDataspace).queryParam('schema-set-name', mySchemaset)
+                    .contentType(MediaType.APPLICATION_JSON))
+                    .andReturn().response
+
+        then: 'received unsupported operation response'
+            response.getStatus() == HttpStatus.NOT_IMPLEMENTED.value()
+
+    }
+
+}
diff --git a/src/test/groovy/org/onap/cps/temporal/controller/web/QueryControllerSpec.groovy b/src/test/groovy/org/onap/cps/temporal/controller/web/QueryControllerSpec.groovy
deleted file mode 100644 (file)
index c834f38..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.temporal.controller.web
-
-import spock.lang.Specification
-
-/**
- * Specification for Query Controller.
- */
-class QueryControllerSpec extends Specification {
-
-    def objectUnderTest = new QueryController()
-
-    def 'Get home returns some data'() {
-        when: 'get home is invoked'
-            def response = objectUnderTest.home()
-        then: 'a response is returned'
-            ! response.empty
-    }
-
-}
index 3ac13a9..fb38742 100644 (file)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
 # ============LICENSE_END=========================================================
 
 server:
     port: 8080
 
+rest:
+    api:
+        base-path: /cps-temporal/api
+
 spring:
     datasource:
         url: ${DB_URL}