Fix swagger definition for blueprint processor 60/90360/11
authorAlexis de Talhouët <adetalhouet89@gmail.com>
Sun, 23 Jun 2019 19:30:36 +0000 (15:30 -0400)
committerAlexis de Talhouët <adetalhouet89@gmail.com>
Thu, 4 Jul 2019 19:53:42 +0000 (15:53 -0400)
Change-Id: I69ba541b4b301735a988cf01673827a79daf1f8c
Issue-ID: CCSDK-1431
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
14 files changed:
ms/blueprintsprocessor/application/pom.xml
ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/SwaggerConfig.java
ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/WebConfig.java
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt
ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt
ms/blueprintsprocessor/parent/pom.xml

index 0f9e08b..f9eead3 100755 (executable)
@@ -32,6 +32,7 @@
     <description>Blueprints Processor Application</description>
 
     <dependencies>
+
         <dependency>
             <groupId>org.onap.ccsdk.cds.controllerblueprints</groupId>
             <artifactId>blueprint-core</artifactId>
index 8ad3c08..4df55ff 100644 (file)
@@ -17,8 +17,9 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor;
 
-
+import io.swagger.annotations.Api;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 import springfox.documentation.builders.PathSelectors;
 import springfox.documentation.builders.RequestHandlerSelectors;
 import springfox.documentation.service.ApiInfo;
@@ -27,37 +28,36 @@ import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spring.web.plugins.Docket;
 
 import java.util.Collections;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;
 
 /**
  * SwaggerConfig
  *
  * @author Brinda Santh 8/13/2018
  */
-//@Configuration
-//@EnableSwagger2
-@SuppressWarnings("unused")
-@Deprecated
+@Configuration
+@EnableSwagger2WebFlux
 public class SwaggerConfig {
 
     @Bean
     public Docket api() {
         return new Docket(DocumentationType.SWAGGER_2)
-                .select()
-                .apis(RequestHandlerSelectors.any())
-                .paths(PathSelectors.any())
-                .build()
-                .apiInfo(apiInfo());
+            .select()
+            .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+            .paths(PathSelectors.any())
+            .build()
+            .apiInfo(apiInfo());
     }
 
     private ApiInfo apiInfo() {
         return new ApiInfo(
-                "Blueprints Processor API",
-                "Controller blueprints processor API for VNF Selfservice.",
-                "1.0.0",
-                "Terms of service",
-                new Contact("Brinda Santh", "www.onap.com", "bs2796@onap.com"),
-                "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", Collections.emptyList());
+            "CDS Blueprints Processor APIs",
+            "Provide APIs to interact with CBA, their related resolved resources and templates.",
+            "0.5.0",
+            null,
+            new Contact("CCSDK Team", "www.onap.org", "onap-discuss@lists.onap.org"),
+            "Apache 2.0",
+            "http://www.apache.org/licenses/LICENSE-2.0",
+            Collections.emptyList());
     }
-
-
-}
+}
\ No newline at end of file
index b453b85..32abff0 100644 (file)
@@ -27,7 +27,7 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
 import org.springframework.security.web.server.SecurityWebFilterChain;
 import org.springframework.web.reactive.config.CorsRegistry;
 import org.springframework.web.reactive.config.ResourceHandlerRegistry;
-import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
+import org.springframework.web.reactive.config.WebFluxConfigurer;
 
 /**
  * WebConfig
@@ -35,7 +35,7 @@ import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
  * @author Brinda Santh 8/13/2018
  */
 @Configuration
-public class WebConfig extends WebFluxConfigurationSupport {
+public class WebConfig implements WebFluxConfigurer {
 
     @Autowired
     private AuthenticationManager authenticationManager;
@@ -45,7 +45,8 @@ public class WebConfig extends WebFluxConfigurationSupport {
 
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
-        registry.addResourceHandler("swagger-ui.html")
+
+        registry.addResourceHandler("/swagger-ui.html**")
             .addResourceLocations("classpath:/META-INF/resources/");
 
         registry.addResourceHandler("/webjars/**")
index 7c2c11c..c98c6d6 100644 (file)
@@ -35,7 +35,7 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
     override suspend fun processNB(executionRequest: ExecutionServiceInput) {
 
         val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE)
-        val key = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY)
+        val resolutionKey = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY)
         val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
         val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID)
         val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE)
@@ -43,7 +43,7 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
 
         val properties: MutableMap<String, Any> = mutableMapOf()
         properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult?.asBoolean() ?: false
-        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key?.asText() ?: ""
+        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = resolutionKey?.asText() ?: ""
         properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId?.asText() ?: ""
         properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType?.asText() ?: ""
 
@@ -52,6 +52,8 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
 
         val jsonResponse = JsonNodeFactory.instance.objectNode()
         for (j in 1..occurrence.asInt()) {
+            val key = resolutionKey?.asText() + "-" + j
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key
 
             val response = resourceResolutionService.resolveResources(bluePrintRuntimeService,
                 nodeTemplateName,
@@ -60,7 +62,7 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
 
             // provide indexed result in output if we have multiple resolution
             if (occurrence.asInt() != 1) {
-                jsonResponse.set(key?.asText() + "-" + j, response.asJsonNode())
+                jsonResponse.set(key, response.asJsonNode())
             } else {
                 jsonResponse.setAll(response.asObjectNode())
             }
index 96c3f64..ba0adf9 100644 (file)
@@ -24,6 +24,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.R
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
@@ -175,7 +176,8 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
                                 // Invoke Apply Method
                                 resourceAssignmentProcessor.applyNB(resourceAssignment)
 
-                                if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
+                                if (BluePrintConstants.STATUS_FAILURE != resourceAssignment.status
+                                    && properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
                                     && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) {
                                     resourceResolutionDBService.write(properties,
                                         blueprintRuntimeService,
index 767a1fe..fa922cd 100644 (file)
@@ -17,7 +17,7 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
 
 import com.fasterxml.jackson.annotation.JsonFormat
-import com.fasterxml.jackson.annotation.JsonProperty
+import io.swagger.annotations.ApiModelProperty
 import org.hibernate.annotations.Proxy
 import org.springframework.data.annotation.LastModifiedDate
 import org.springframework.data.jpa.domain.support.AuditingEntityListener
@@ -42,43 +42,57 @@ class ResourceResolution : Serializable {
     @Column(name = "resource_resolution_id")
     var id: String? = null
 
+    @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
+        required = true)
     @Column(name = "resolution_key", nullable = false)
     var resolutionKey: String? = null
 
+    @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF")
     @Column(name = "resource_type", nullable = false)
     var resourceType: String? = null
 
+    @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true)
     @Column(name = "resource_id", nullable = false)
     var resourceId: String? = null
 
+    @get:ApiModelProperty(value = "Name of the CBA.", required = true)
     @Column(name = "blueprint_name", nullable = false)
     var blueprintName: String? = null
 
+    @get:ApiModelProperty(value = "Version of the CBA.", required = true)
     @Column(name = "blueprint_version", nullable = false)
     var blueprintVersion: String? = null
 
+    @get:ApiModelProperty(value = "Artifact name for which to retrieve a resolved resource.", required = true)
     @Column(name = "artifact_name", nullable = false)
     var artifactName: String? = null
 
+    @get:ApiModelProperty(value = "Whether success of failure.", required = true)
     @Column(name = "status", nullable = false)
     var status: String? = null
 
+    @get:ApiModelProperty(value = "Name of the resource.", required = true)
     @Column(name = "name", nullable = false)
     var name: String? = null
 
-    @Column(name = "dictionary_vname", nullable = false)
+    @get:ApiModelProperty(value = "Name of the data dictionary used for the resolution.", required = true)
+    @Column(name = "dictionary_name", nullable = false)
     var dictionaryName: String? = null
 
+    @get:ApiModelProperty(value = "Source associated with the data dictionary used for the resolution.", required = true)
     @Column(name = "dictionary_status", nullable = false)
     var dictionarySource: String? = null
 
+    @get:ApiModelProperty(value = "Version of the data dictionary used for the resolution.", required = true)
     @Column(name = "dictionary_version", nullable = false)
     var dictionaryVersion: Int = 0
 
+    @get:ApiModelProperty(value = "Value of the resolution.", required = true)
     @Lob
     @Column(name = "value", nullable = false)
     var value: String? = null
 
+    @get:ApiModelProperty(value = "Creation date of the resolution.", required = true)
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
     @LastModifiedDate
     @Temporal(TemporalType.TIMESTAMP)
index ea5626a..ae24a9a 100755 (executable)
@@ -17,6 +17,7 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
 
 import com.fasterxml.jackson.annotation.JsonFormat
+import io.swagger.annotations.ApiModelProperty
 import org.hibernate.annotations.Proxy
 import org.springframework.data.annotation.LastModifiedDate
 import org.springframework.data.jpa.domain.support.AuditingEntityListener
@@ -41,22 +42,29 @@ class TemplateResolution : Serializable {
     @Column(name = "template_resolution_id")
     var id: String? = null
 
+    @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
+        required = true)
     @Column(name = "resolution_key", nullable = false)
     var resolutionKey: String? = null
 
+    @get:ApiModelProperty(value = "Name of the CBA.", required = true)
     @Column(name = "blueprint_name", nullable = false)
     var blueprintName: String? = null
 
+    @get:ApiModelProperty(value = "Version of the CBA.", required = true)
     @Column(name = "blueprint_version", nullable = false)
     var blueprintVersion: String? = null
 
+    @get:ApiModelProperty(value = "Artifact name for which to retrieve a resolved resource.", required = true)
     @Column(name = "artifact_name", nullable = false)
     var artifactName: String? = null
 
+    @get:ApiModelProperty(value = "Rendered template.", required = true)
     @Lob
     @Column(name = "result", nullable = false)
     var result: String? = null
 
+    @get:ApiModelProperty(value = "Creation date of the resolution.", required = true)
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
     @LastModifiedDate
     @Temporal(TemporalType.TIMESTAMP)
index c2698c0..c45ebc1 100644 (file)
@@ -30,24 +30,32 @@ import java.util.*
  */
 
 open class ExecutionServiceInput {
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Headers providing request context.")
     lateinit var commonHeader: CommonHeader
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Provide information about the action to execute.")
     lateinit var actionIdentifiers: ActionIdentifiers
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true,
+        value = "Contain the information to be passed as input to the action." +
+                "The payload is constituted of two section: the workflow input which is the higher level block (xxx-request)" +
+                " and the input for resource resolution located within the xxx-request block, contained within xxx-properties")
     lateinit var payload: ObjectNode
+    @get:ApiModelProperty(hidden = true)
     var stepData: StepData? = null
 }
 
 open class ExecutionServiceOutput {
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Headers providing request context.")
     lateinit var commonHeader: CommonHeader
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Provide information about the action to execute.")
     lateinit var actionIdentifiers: ActionIdentifiers
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Status of the request.")
     lateinit var status: Status
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true,
+        value = "Contain the information to be passed as input to the action." +
+                "The payload is constituted of two section: the workflow input which is the higher level block (xxx-request)" +
+                " and the input for resource resolution located within the xxx-request block, contained within xxx-properties")
     lateinit var payload: ObjectNode
+    @get:ApiModelProperty(hidden = true)
     var stepData: StepData? = null
 }
 
@@ -55,53 +63,56 @@ const val ACTION_MODE_ASYNC = "async"
 const val ACTION_MODE_SYNC = "sync"
 
 open class ActionIdentifiers {
-    @get:ApiModelProperty(required = false)
+    @get:ApiModelProperty(required = false, value = "Name of the CBA.")
     lateinit var blueprintName: String
-    @get:ApiModelProperty(required = false)
+    @get:ApiModelProperty(required = false, value = "Version of the CBA.")
     lateinit var blueprintVersion: String
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Name of the workflow to execute.")
     lateinit var actionName: String
-    @get:ApiModelProperty(required = true, allowableValues = "sync, async")
+    @get:ApiModelProperty(required = true,
+        value = "Async processing is only supported for gRPC client.",
+        allowableValues = "sync, async")
     lateinit var mode: String
 }
 
 open class CommonHeader {
-    @get:ApiModelProperty(required = true, example = "2012-04-23T18:25:43.511Z")
+    @get:ApiModelProperty(required = true, value = "Date of the execution", example = "2012-04-23T18:25:43.511Z")
     @get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
     var timestamp: Date = Date()
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Identify the system/person triggering the request.")
     lateinit var originatorId: String
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Uniquely identify a request.")
     lateinit var requestId: String
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Allow for fine-grain request identifier")
     lateinit var subRequestId: String
-    @get:ApiModelProperty(required = false)
+    @get:ApiModelProperty(required = false, hidden = true)
     var flags: Flags? = null
 }
 
 open class Flags {
+    @get:ApiModelProperty(value = "Whether or not to force the action.")
     var isForce: Boolean = false
     @get:ApiModelProperty(value = "3600")
     var ttl: Int = 3600
 }
 
 open class Status {
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "HTTP status code equivalent.")
     var code: Int = 200
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Type of the event being emitted by CDS.")
     var eventType: String = ""
-    @get:ApiModelProperty(required = true, example = "2012-04-23T18:25:43.511Z")
+    @get:ApiModelProperty(required = true,
+        value = "Time when the execution ended.",
+        example = "2012-04-23T18:25:43.511Z")
     @get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
     var timestamp: Date = Date()
-    @get:ApiModelProperty(required = false)
+    @get:ApiModelProperty(required = false, value = "Error message when system failed")
     var errorMessage: String? = null
-    @get:ApiModelProperty(required = true)
+    @get:ApiModelProperty(required = true, value = "Message providing request status")
     var message: String = "success"
 }
 
 open class StepData {
     lateinit var name: String
     var properties: MutableMap<String, JsonNode> = mutableMapOf()
-}
-
-
+}
\ No newline at end of file
index c50853f..4c8fc19 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.resource.api
 
+import com.fasterxml.jackson.databind.JsonNode
+import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
 import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolution
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.http.MediaType
 import org.springframework.http.ResponseEntity
 import org.springframework.security.access.prepost.PreAuthorize
@@ -27,27 +31,42 @@ import org.springframework.web.bind.annotation.*
 
 @RestController
 @RequestMapping("/api/v1/resources")
+@Api(value = "/api/v1/resources",
+    description = "Interaction with resolved resources.")
 open class ResourceController(private var resourceResolutionDBService: ResourceResolutionDBService) {
 
-    @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
+    @RequestMapping(path = ["/health-check"],
+        method = [RequestMethod.GET],
+        produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
-    fun ping(): String = runBlocking {
-        "Success"
+    @ApiOperation(value = "Health Check", hidden = true)
+    fun resourceControllerHealthCheck(): JsonNode = runBlocking {
+        JacksonUtils.getJsonNode("Success")
     }
 
     @RequestMapping(path = [""],
         method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
-    @ApiOperation(value = "Fetch all resource values associated to a resolution key. ",
-        notes = "Retrieve a stored resource value using the blueprint metadata, artifact name and the resolution-key.",
+    @ApiOperation(value = "Get all resolved resources using the resolution key. ",
+        notes = "Retrieve all stored resolved resources using the blueprint name, blueprint version, " +
+                "artifact name and the resolution-key.",
+        response = ResourceResolution::class,
+        responseContainer = "List",
         produces = MediaType.APPLICATION_JSON_VALUE)
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun getAllFromResolutionKeyOrFromResourceTypeAndId(@RequestParam(value = "bpName", required = true) bpName: String,
-                                @RequestParam(value = "bpVersion", required = true) bpVersion: String,
-                                @RequestParam(value = "artifactName", required = false, defaultValue = "") artifactName: String,
-                                @RequestParam(value = "resolutionKey", required = false, defaultValue = "") resolutionKey: String,
-                                @RequestParam(value = "resourceType", required = false, defaultValue = "") resourceType: String,
-                                @RequestParam(value = "resourceId", required = false, defaultValue = "") resourceId: String)
+    fun getAllFromResolutionKeyOrFromResourceTypeAndId(
+        @ApiParam(value = "Name of the CBA.", required = true)
+        @RequestParam(value = "bpName", required = true) bpName: String,
+        @ApiParam(value = "Version of the CBA.", required = true)
+        @RequestParam(value = "bpVersion", required = true) bpVersion: String,
+        @ApiParam(value = "Artifact name for which to retrieve a resolved resource.", required = true)
+        @RequestParam(value = "artifactName", required = false, defaultValue = "") artifactName: String,
+        @ApiParam(value = "Resolution Key associated with the resolution.", required = false)
+        @RequestParam(value = "resolutionKey", required = false, defaultValue = "") resolutionKey: String,
+        @ApiParam(value = "Resource Type associated with the resolution.", required = false)
+        @RequestParam(value = "resourceType", required = false, defaultValue = "") resourceType: String,
+        @ApiParam(value = "Resource Id associated with the resolution.", required = false)
+        @RequestParam(value = "resourceId", required = false, defaultValue = "") resourceId: String)
             : ResponseEntity<List<ResourceResolution>> = runBlocking {
 
         if ((resolutionKey.isNotEmpty() || artifactName.isNotEmpty()) && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) {
@@ -55,9 +74,12 @@ open class ResourceController(private var resourceResolutionDBService: ResourceR
         } else if (resolutionKey.isNotEmpty() && artifactName.isNotEmpty()) {
             ResponseEntity.ok()
                 .body(resourceResolutionDBService.readWithResolutionKey(bpName, bpVersion, artifactName, resolutionKey))
-        } else if (resourceType.isNotEmpty() && resourceId.isNotEmpty()){
-                ResponseEntity.ok()
-                    .body(resourceResolutionDBService.readWithResourceIdAndResourceType(bpName, bpVersion, resourceId, resourceType))
+        } else if (resourceType.isNotEmpty() && resourceId.isNotEmpty()) {
+            ResponseEntity.ok()
+                .body(resourceResolutionDBService.readWithResourceIdAndResourceType(bpName,
+                    bpVersion,
+                    resourceId,
+                    resourceType))
         } else {
             throw ResourceException("Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.")
         }
@@ -71,10 +93,16 @@ open class ResourceController(private var resourceResolutionDBService: ResourceR
         produces = MediaType.APPLICATION_JSON_VALUE)
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun getOneFromResolutionKey(@RequestParam(value = "bpName", required = true) bpName: String,
+    fun getOneFromResolutionKey(@ApiParam(value = "Name of the CBA.", required = true)
+                                @RequestParam(value = "bpName", required = true) bpName: String,
+                                @ApiParam(value = "Version of the CBA.", required = true)
                                 @RequestParam(value = "bpVersion", required = true) bpVersion: String,
+                                @ApiParam(value = "Artifact name for which to retrieve a resolved resource.",
+                                    required = true)
                                 @RequestParam(value = "artifactName", required = true) artifactName: String,
+                                @ApiParam(value = "Resolution Key associated with the resolution.", required = true)
                                 @RequestParam(value = "resolutionKey", required = true) resolutionKey: String,
+                                @ApiParam(value = "Name of the resource to retrieve.", required = true)
                                 @RequestParam(value = "name", required = true) name: String)
             : ResponseEntity<ResourceResolution> = runBlocking {
 
index d3ebd5c..83e8130 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.resource.api
 
+import com.fasterxml.jackson.databind.JsonNode
+import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
 import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolution
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.http.MediaType
 import org.springframework.http.ResponseEntity
 import org.springframework.security.access.prepost.PreAuthorize
@@ -33,26 +37,41 @@ import org.springframework.web.bind.annotation.*
  */
 @RestController
 @RequestMapping("/api/v1/template")
+@Api(value = "/api/v1/template",
+    description = "Interaction with resolved template.")
 open class TemplateController(private val templateResolutionService: TemplateResolutionService) {
 
-    @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
+    @RequestMapping(path = ["/health-check"],
+        method = [RequestMethod.GET],
+        produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
-    fun ping(): String = runBlocking {
-        "Success"
+    @ApiOperation(value = "Health Check", hidden = true)
+    fun templateControllerHealthCheck(): JsonNode = runBlocking {
+        JacksonUtils.getJsonNode("Success")
     }
 
-    @RequestMapping(path = [""], method = [RequestMethod.GET], produces = [MediaType.TEXT_PLAIN_VALUE])
-    @ApiOperation(value = "Retrieve a meshed template.",
-        notes = "Retrieve a meshed template for a given CBA's action, identified by its blueprint name, blueprint version, " +
-                "artifact name and resolution key. And extra 'format' parameter can be passed to tell what content-type" +
+    @RequestMapping(path = [""],
+        method = [RequestMethod.GET],
+        produces = [MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE])
+    @ApiOperation(value = "Retrieve a resolved template.",
+        notes = "Retrieve a config template for a given CBA's action, identified by its blueprint name, blueprint version, " +
+                "artifact name and resolution key. An extra 'format' parameter can be passed to tell what content-type" +
                 " to expect in return")
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun get(@RequestParam(value = "bpName") bpName: String,
-            @RequestParam(value = "bpVersion") bpVersion: String,
-            @RequestParam(value = "artifactName") artifactName: String,
-            @RequestParam(value = "resolutionKey") resolutionKey: String,
-            @RequestParam(value = "format", required = false, defaultValue = "text/plain") format: String)
+    fun get(
+        @ApiParam(value = "Name of the CBA.", required = true)
+        @RequestParam(value = "bpName") bpName: String,
+        @ApiParam(value = "Version of the CBA.", required = true)
+        @RequestParam(value = "bpVersion") bpVersion: String,
+        @ApiParam(value = "Artifact name for which to retrieve a resolved resource.", required = true)
+        @RequestParam(value = "artifactName") artifactName: String,
+        @ApiParam(value = "Resolution Key associated with the resolution.", required = true)
+        @RequestParam(value = "resolutionKey") resolutionKey: String,
+        @ApiParam(value = "Expected format of the template being retrieved.",
+            defaultValue = MediaType.TEXT_PLAIN_VALUE,
+            required = true)
+        @RequestParam(value = "format", required = false, defaultValue = MediaType.TEXT_PLAIN_VALUE) format: String)
             : ResponseEntity<String> = runBlocking {
 
         val result = templateResolutionService.read(bpName, bpVersion, artifactName, resolutionKey)
@@ -68,15 +87,22 @@ open class TemplateController(private val templateResolutionService: TemplateRes
 
 
     @PostMapping("/{bpName}/{bpVersion}/{artifactName}/{resolutionKey}", produces = [MediaType.APPLICATION_JSON_VALUE])
-    @ApiOperation(value = "Store a meshed template",
-        notes = "Store a meshed template for a given CBA's action, identified by its blueprint name, blueprint version, " +
-                "artifact name and resolution key.")
+    @ApiOperation(value = "Store a resolved template",
+        notes = "Store a template for a given CBA's action, identified by its blueprint name, blueprint version, " +
+                "artifact name and resolution key.",
+        response = TemplateResolution::class,
+        produces = MediaType.APPLICATION_JSON_VALUE)
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun post(@PathVariable(value = "bpName") bpName: String,
+    fun post(@ApiParam(value = "Name of the CBA.", required = true)
+             @PathVariable(value = "bpName") bpName: String,
+             @ApiParam(value = "Version of the CBA.", required = true)
              @PathVariable(value = "bpVersion") bpVersion: String,
+             @ApiParam(value = "Artifact name for which to retrieve a resolved resource.", required = true)
              @PathVariable(value = "artifactName") artifactName: String,
+             @ApiParam(value = "Resolution Key associated with the resolution.", required = true)
              @PathVariable(value = "resolutionKey") resolutionKey: String,
+             @ApiParam(value = "Template to store.", required = true)
              @RequestBody result: String): ResponseEntity<TemplateResolution> = runBlocking {
 
         val resultStored =
index cde71d8..daab7b3 100644 (file)
@@ -77,7 +77,7 @@ class ResourceControllerTest {
     @Test
     fun `ping return Success`() {
         runBlocking {
-            webTestClient.get().uri("/api/v1/resources/ping")
+            webTestClient.get().uri("/api/v1/resources/health-check")
                 .exchange()
                 .expectStatus().isOk
                 .expectBody()
index d12d058..649f6b5 100644 (file)
@@ -72,7 +72,7 @@ class TemplateControllerTest {
     @Test
     fun `ping return Success`() {
         runBlocking {
-            webTestClient.get().uri("/api/v1/template/ping")
+            webTestClient.get().uri("/api/v1/template/health-check")
                 .exchange()
                 .expectStatus().isOk
                 .expectBody()
index eff9773..60016fb 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
+import com.fasterxml.jackson.databind.JsonNode
+import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
 import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
 import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.determineHttpStatusCode
-import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.http.HttpStatus
 import org.springframework.http.MediaType
 import org.springframework.http.ResponseEntity
 import org.springframework.http.codec.multipart.FilePart
@@ -34,43 +36,59 @@ import org.springframework.web.bind.annotation.*
 
 @RestController
 @RequestMapping("/api/v1/execution-service")
+@Api(value = "/api/v1/execution-service",
+    description = "Interaction with CBA.")
 open class ExecutionServiceController {
 
     @Autowired
     lateinit var executionServiceHandler: ExecutionServiceHandler
 
-    @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
+    @RequestMapping(path = ["/health-check"],
+        method = [RequestMethod.GET],
+        produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
-    fun ping(): String = runBlocking {
-        "Success"
+    @ApiOperation(value = "Health Check", hidden = true)
+    fun executionServiceControllerHealthCheck(): JsonNode = runBlocking {
+        JacksonUtils.getJsonNode("Success")
     }
 
     @PostMapping(path = ["/upload"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
-    @ApiOperation(value = "Upload CBA", notes = "Takes a File and load it in the runtime database")
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun upload(@RequestPart("file") filePart: FilePart): String = runBlocking {
-        executionServiceHandler.upload(filePart)
+    @ApiOperation(value = "Upload a CBA",
+        notes = "Upload the CBA package. This will also run validation on the CBA.",
+        produces = MediaType.APPLICATION_JSON_VALUE)
+    fun upload(@ApiParam(value = "The ZIP file containing the overall CBA package.", required = true)
+               @RequestPart("file") filePart: FilePart): JsonNode = runBlocking {
+        JacksonUtils.getJsonNode(executionServiceHandler.upload(filePart))
     }
 
     @DeleteMapping("/name/{name}/version/{version}")
-    @Throws(BluePrintException::class)
+    @ApiOperation(value = "Delete a CBA",
+        notes = "Delete the CBA package identified by its name and version.",
+        produces = MediaType.APPLICATION_JSON_VALUE)
     @PreAuthorize("hasRole('USER')")
-    fun deleteBlueprint(@PathVariable(value = "name") name: String,
+    fun deleteBlueprint(@ApiParam(value = "Name of the CBA.", required = true)
+                        @PathVariable(value = "name") name: String,
+                        @ApiParam(value = "Version of the CBA.", required = true)
                         @PathVariable(value = "version") version: String) = runBlocking {
         executionServiceHandler.remove(name, version)
     }
 
     @RequestMapping(path = ["/process"], method = [RequestMethod.POST], produces = [MediaType.APPLICATION_JSON_VALUE])
-    @ApiOperation(value = "Resolve Resource Mappings",
-            notes = "Takes the blueprint information and process as per the payload")
+    @ApiOperation(value = "Execute a CBA workflow (action)",
+        notes = "Execute the appropriate CBA's action based on the ExecutionServiceInput object passed as input.",
+        produces = MediaType.APPLICATION_JSON_VALUE,
+        response = ExecutionServiceOutput::class)
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun process(@RequestBody executionServiceInput: ExecutionServiceInput): ResponseEntity<ExecutionServiceOutput> = runBlocking {
-        if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
-            throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
+    fun process(@ApiParam(value = "ExecutionServiceInput payload.", required = true)
+                @RequestBody executionServiceInput: ExecutionServiceInput): ResponseEntity<ExecutionServiceOutput> =
+        runBlocking {
+            if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
+                throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
+            }
+            val processResult = executionServiceHandler.doProcess(executionServiceInput)
+            ResponseEntity(processResult, determineHttpStatusCode(processResult.status.code))
         }
-        val processResult = executionServiceHandler.doProcess(executionServiceInput)
-        ResponseEntity(processResult, determineHttpStatusCode(processResult.status.code))
-    }
 }
index b1d2889..4084f58 100755 (executable)
@@ -14,7 +14,8 @@
   ~  See the License for the specific language governing permissions and
   ~  limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onap.ccsdk.cds</groupId>
@@ -43,7 +44,9 @@
         <sli.version>${ccsdk.sli.core.version}</sli.version>
         <guava.version>27.0.1-jre</guava.version>
         <jython.version>2.7.1</jython.version>
-        <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
+        <!--        Should be using released artifact as soon as available:-->
+        <!--        https://github.com/springfox/springfox/milestone/44-->
+        <springfox.swagger2.version>3.0.0-SNAPSHOT</springfox.swagger2.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
         <powermock.version>1.7.4</powermock.version>
                 <artifactId>springfox-swagger-ui</artifactId>
                 <version>${springfox.swagger2.version}</version>
             </dependency>
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-spring-webflux</artifactId>
+                <version>${springfox.swagger2.version}</version>
+            </dependency>
 
             <!-- Common Utils Dependencies -->
             <dependency>
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-spring-webflux</artifactId>
+        </dependency>
         <dependency>
             <groupId>io.springfox</groupId>
             <artifactId>springfox-swagger-ui</artifactId>
         </dependency>
     </dependencies>
 
+    <repositories>
+        <repository>
+            <id>spring-libs-milestone</id>
+            <name>Spring Milestone Maven Repository</name>
+            <url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url>
+        </repository>
+    </repositories>
+
     <build>
         <plugins>
             <plugin>