From 2791db21e7d7f7d31ea402fe978dab216a41367f Mon Sep 17 00:00:00 2001 From: Alexis de Talhouët Date: Sun, 23 Jun 2019 15:30:36 -0400 Subject: Fix swagger definition for blueprint processor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I69ba541b4b301735a988cf01673827a79daf1f8c Issue-ID: CCSDK-1431 Signed-off-by: Alexis de Talhouët --- ms/blueprintsprocessor/application/pom.xml | 1 + .../cds/blueprintsprocessor/SwaggerConfig.java | 38 +++++++------- .../ccsdk/cds/blueprintsprocessor/WebConfig.java | 7 +-- .../resolution/ResourceResolutionComponent.kt | 8 +-- .../resolution/ResourceResolutionService.kt | 4 +- .../resource/resolution/db/ResourceResolution.kt | 18 ++++++- .../resource/resolution/db/TemplateResolution.kt | 8 +++ .../core/api/data/BlueprintProcessorData.kt | 59 +++++++++++++--------- .../resource/api/ResourceController.kt | 58 +++++++++++++++------ .../resource/api/TemplateController.kt | 58 +++++++++++++++------ .../api/ResourceControllerTest.kt | 2 +- .../resource/api/TemplateControllerTest.kt | 2 +- .../selfservice/api/ExecutionServiceController.kt | 54 +++++++++++++------- ms/blueprintsprocessor/parent/pom.xml | 24 ++++++++- 14 files changed, 236 insertions(+), 105 deletions(-) diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index 0f9e08b5f..f9eead39e 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -32,6 +32,7 @@ Blueprints Processor Application + org.onap.ccsdk.cds.controllerblueprints blueprint-core diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/SwaggerConfig.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/SwaggerConfig.java index 8ad3c08f2..4df55ffde 100644 --- a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/SwaggerConfig.java +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/SwaggerConfig.java @@ -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 diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/WebConfig.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/WebConfig.java index b453b8581..32abff011 100644 --- a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/WebConfig.java +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/WebConfig.java @@ -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/**") diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt index 7c2c11c06..c98c6d6bd 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt @@ -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 = 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()) } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index 96c3f644c..ba0adf967 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -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, diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt index 767a1feaf..fa922cde5 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt @@ -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) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt index ea5626a80..ae24a9ac2 100755 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt @@ -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) diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt index c2698c026..c45ebc127 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt +++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt @@ -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 = mutableMapOf() -} - - +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt index c50853ff2..4c8fc193c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt @@ -16,10 +16,14 @@ 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> = 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 = runBlocking { diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt index d3ebd5c49..83e813079 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt @@ -16,10 +16,14 @@ 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 = 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 = runBlocking { val resultStored = diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt index cde71d86c..daab7b3bb 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt @@ -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() diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt index d12d05804..649f6b5fe 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt @@ -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() diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt index eff977348..60016fb98 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt @@ -17,15 +17,17 @@ 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 = 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 = + 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)) - } } diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index b1d288979..4084f58f2 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -14,7 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + 4.0.0 org.onap.ccsdk.cds @@ -43,7 +44,9 @@ ${ccsdk.sli.core.version} 27.0.1-jre 2.7.1 - 2.9.2 + + + 3.0.0-SNAPSHOT 1.4.197 1.2.2 1.7.4 @@ -86,6 +89,11 @@ springfox-swagger-ui ${springfox.swagger2.version} + + io.springfox + springfox-spring-webflux + ${springfox.swagger2.version} + @@ -521,6 +529,10 @@ + + io.springfox + springfox-spring-webflux + io.springfox springfox-swagger-ui @@ -584,6 +596,14 @@ + + + spring-libs-milestone + Spring Milestone Maven Repository + http://oss.jfrog.org/artifactory/oss-snapshot-local/ + + + -- cgit 1.2.3-korg