b7badb53b28078732b1361f68fb61efdf1f1b997
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2019 Bell Canada.
4  * Modifications Copyright © 2019 IBM.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api
20
21 import io.grpc.StatusException
22 import io.grpc.stub.StreamObserver
23 import kotlinx.coroutines.runBlocking
24 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader
25 import org.onap.ccsdk.cds.controllerblueprints.common.api.Status
26 import org.onap.ccsdk.cds.controllerblueprints.core.*
27 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
28 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
29 import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache
30 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils
31 import org.onap.ccsdk.cds.controllerblueprints.core.utils.currentTimestamp
32 import org.onap.ccsdk.cds.controllerblueprints.management.api.*
33 import org.slf4j.LoggerFactory
34 import org.springframework.security.access.prepost.PreAuthorize
35 import org.springframework.stereotype.Service
36 import java.io.File
37 import java.util.*
38
39 @Service
40 open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
41                                           private val blueprintsProcessorCatalogService: BluePrintCatalogService)
42     : BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase() {
43
44     private val log = LoggerFactory.getLogger(BluePrintManagementGRPCHandler::class.java)
45
46     @PreAuthorize("hasRole('USER')")
47     override fun uploadBlueprint(request: BluePrintUploadInput, responseObserver:
48     StreamObserver<BluePrintManagementOutput>) {
49         runBlocking {
50
51             log.info("request(${request.commonHeader.requestId})")
52             val uploadId = UUID.randomUUID().toString()
53             val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, uploadId)
54             val blueprintWorking = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, uploadId)
55             try {
56                 val cbaFile = normalizedFile(blueprintArchive, "cba.zip")
57
58                 saveToDisk(request, cbaFile)
59
60                 val uploadAction = request.actionIdentifiers?.actionName.emptyTONull()
61                         ?: UploadAction.DRAFT.toString()
62
63                 when (uploadAction) {
64                     UploadAction.DRAFT.toString() -> {
65                         val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(uploadId, cbaFile, false)
66                         responseObserver.onNext(successStatus("Successfully uploaded CBA($blueprintId)...",
67                                 request.commonHeader))
68                     }
69                     UploadAction.PUBLISH.toString() -> {
70                         val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(uploadId, cbaFile, true)
71                         responseObserver.onNext(successStatus("Successfully uploaded CBA($blueprintId)...",
72                                 request.commonHeader))
73                     }
74                     UploadAction.VALIDATE.toString() -> {
75                         //TODO("Not Implemented")
76                         responseObserver.onError(failStatus("Not Implemented",
77                                 BluePrintProcessorException("Not Implemented")))
78                     }
79                     UploadAction.ENRICH.toString() -> {
80                         //TODO("Not Implemented")
81                         responseObserver.onError(failStatus("Not Implemented",
82                                 BluePrintProcessorException("Not Implemented")))
83                     }
84                 }
85                 responseObserver.onCompleted()
86             } catch (e: Exception) {
87                 responseObserver.onError(failStatus("request(${request.commonHeader.requestId}): Failed to upload CBA", e))
88             } finally {
89                 // Clean blueprint script cache
90                 val cacheKey = BluePrintFileUtils
91                         .compileCacheKey(normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, uploadId))
92                 BluePrintCompileCache.cleanClassLoader(cacheKey)
93                 deleteNBDir(blueprintArchive)
94                 deleteNBDir(blueprintWorking)
95             }
96         }
97     }
98
99     @PreAuthorize("hasRole('USER')")
100     override fun removeBlueprint(request: BluePrintRemoveInput, responseObserver:
101     StreamObserver<BluePrintManagementOutput>) {
102
103         runBlocking {
104             val blueprintName = request.blueprintName
105             val blueprintVersion = request.blueprintVersion
106             val blueprint = "blueprint $blueprintName:$blueprintVersion"
107
108             log.info("request(${request.commonHeader.requestId}): Received delete $blueprint")
109
110
111             try {
112                 blueprintsProcessorCatalogService.deleteFromDatabase(blueprintName, blueprintVersion)
113                 responseObserver.onNext(successStatus("Successfully deleted $blueprint", request.commonHeader))
114                 responseObserver.onCompleted()
115             } catch (e: Exception) {
116                 responseObserver.onError(failStatus("request(${request.commonHeader.requestId}): Failed to delete $blueprint", e))
117             }
118         }
119     }
120
121     private fun saveToDisk(request: BluePrintUploadInput, cbaFile: File) {
122         log.info("request(${request.commonHeader.requestId}): Writing CBA File under :${cbaFile.absolutePath}")
123
124         // Recreate Folder
125         cbaFile.parentFile.reCreateDirs()
126
127         // Write the File
128         cbaFile.writeBytes(request.fileChunk.chunk.toByteArray()).apply {
129             log.info("request(${request.commonHeader.requestId}): CBA file(${cbaFile.absolutePath} written successfully")
130         }
131
132     }
133
134     private fun successStatus(message: String, header: CommonHeader): BluePrintManagementOutput =
135             BluePrintManagementOutput.newBuilder()
136                     .setCommonHeader(header)
137                     .setStatus(Status.newBuilder()
138                             .setTimestamp(currentTimestamp())
139                             .setMessage(message)
140                             .setCode(200)
141                             .build())
142                     .build()
143
144     private fun failStatus(message: String, e: Exception): StatusException {
145         log.error(message, e)
146         return io.grpc.Status.INTERNAL
147                 .withDescription(message)
148                 .withCause(e)
149                 .asException()
150     }
151 }