Formatting Code base with ktlint
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / inbounds / designer-api / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / designer / api / BluePrintManagementGRPCHandler.kt
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 com.google.protobuf.ByteString
22 import com.google.protobuf.util.JsonFormat
23 import io.grpc.stub.StreamObserver
24 import kotlinx.coroutines.runBlocking
25 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler.BluePrintModelHandler
26 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader
27 import org.onap.ccsdk.cds.controllerblueprints.common.api.Status
28 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
29 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
30 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString
31 import org.onap.ccsdk.cds.controllerblueprints.core.emptyTONull
32 import org.onap.ccsdk.cds.controllerblueprints.core.utils.currentTimestamp
33 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintBootstrapInput
34 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintDownloadInput
35 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementOutput
36 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementServiceGrpc
37 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintRemoveInput
38 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput
39 import org.onap.ccsdk.cds.controllerblueprints.management.api.DownloadAction
40 import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk
41 import org.onap.ccsdk.cds.controllerblueprints.management.api.RemoveAction
42 import org.onap.ccsdk.cds.controllerblueprints.management.api.UploadAction
43 import org.slf4j.LoggerFactory
44 import org.springframework.security.access.prepost.PreAuthorize
45 import org.springframework.stereotype.Service
46
47 // TODO("Convert to coroutines handler")
48 @Service
49 open class BluePrintManagementGRPCHandler(private val bluePrintModelHandler: BluePrintModelHandler) :
50     BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase() {
51
52     private val log = LoggerFactory.getLogger(BluePrintManagementGRPCHandler::class.java)
53
54     @PreAuthorize("hasRole('USER')")
55     override fun uploadBlueprint(
56         request: BluePrintUploadInput,
57         responseObserver: StreamObserver<BluePrintManagementOutput>
58     ) {
59
60         runBlocking {
61             // TODO("catch if request id is missing")
62             log.info("request(${request.commonHeader.requestId})")
63             try {
64                 /** Get the file byte array */
65                 val byteArray = request.fileChunk.chunk.toByteArray()
66                 /** Get the Upload Action */
67                 val uploadAction = request.actionIdentifiers?.actionName.emptyTONull()
68                     ?: UploadAction.DRAFT.toString()
69
70                 when (uploadAction) {
71                     UploadAction.DRAFT.toString() -> {
72                         val blueprintModel = bluePrintModelHandler.upload(byteArray, false)
73                         responseObserver.onNext(successStatus(request.commonHeader, blueprintModel.asJsonString()))
74                     }
75                     UploadAction.PUBLISH.toString() -> {
76                         val blueprintModel = bluePrintModelHandler.upload(byteArray, true)
77                         responseObserver.onNext(successStatus(request.commonHeader, blueprintModel.asJsonString()))
78                     }
79                     UploadAction.VALIDATE.toString() -> {
80                         // TODO("Not Implemented")
81                         responseObserver.onNext(
82                             failStatus(
83                                 request.commonHeader,
84                                 "Upload action($uploadAction) not implemented",
85                                 BluePrintProcessorException("Not Implemented")
86                             )
87                         )
88                     }
89                     UploadAction.ENRICH.toString() -> {
90                         val enrichedByteArray = bluePrintModelHandler.enrichBlueprintFileSource(byteArray)
91                         responseObserver.onNext(outputWithFileBytes(request.commonHeader, enrichedByteArray))
92                     }
93                     else -> {
94                         responseObserver.onNext(
95                             failStatus(
96                                 request.commonHeader,
97                                 "Upload action($uploadAction) not implemented",
98                                 BluePrintProcessorException("Not implemented")
99                             )
100                         )
101                     }
102                 }
103             } catch (e: Exception) {
104                 responseObserver.onNext(
105                     failStatus(
106                         request.commonHeader,
107                         "request(${request.commonHeader.requestId}): Failed to upload CBA", e
108                     )
109                 )
110             } finally {
111                 responseObserver.onCompleted()
112             }
113         }
114     }
115
116     @PreAuthorize("hasRole('USER')")
117     override fun downloadBlueprint(
118         request: BluePrintDownloadInput,
119         responseObserver: StreamObserver<BluePrintManagementOutput>
120     ) {
121         runBlocking {
122             val blueprintName = request.actionIdentifiers.blueprintName
123             val blueprintVersion = request.actionIdentifiers.blueprintVersion
124             val blueprint = "blueprint $blueprintName:$blueprintVersion"
125
126             /** Get the Search Action */
127             val searchAction = request.actionIdentifiers?.actionName.emptyTONull()
128                 ?: DownloadAction.SEARCH.toString()
129
130             log.info("request(${request.commonHeader.requestId}): Received download $blueprint")
131             try {
132                 when (searchAction) {
133                     DownloadAction.SEARCH.toString() -> {
134                         val downloadByteArray = bluePrintModelHandler.download(blueprintName, blueprintVersion)
135                         responseObserver.onNext(outputWithFileBytes(request.commonHeader, downloadByteArray))
136                     }
137                     else -> {
138                         responseObserver.onNext(
139                             failStatus(
140                                 request.commonHeader,
141                                 "Search action($searchAction) not implemented",
142                                 BluePrintProcessorException("Not implemented")
143                             )
144                         )
145                     }
146                 }
147             } catch (e: Exception) {
148                 responseObserver.onNext(
149                     failStatus(
150                         request.commonHeader,
151                         "request(${request.commonHeader.requestId}): Failed to delete $blueprint", e
152                     )
153                 )
154             } finally {
155                 responseObserver.onCompleted()
156             }
157         }
158     }
159
160     @PreAuthorize("hasRole('USER')")
161     override fun removeBlueprint(
162         request: BluePrintRemoveInput,
163         responseObserver:
164         StreamObserver<BluePrintManagementOutput>
165     ) {
166
167         runBlocking {
168             val blueprintName = request.actionIdentifiers.blueprintName
169             val blueprintVersion = request.actionIdentifiers.blueprintVersion
170             val blueprint = "blueprint $blueprintName:$blueprintVersion"
171
172             log.info("request(${request.commonHeader.requestId}): Received delete $blueprint")
173
174             /** Get the Remove Action */
175             val removeAction = request.actionIdentifiers?.actionName.emptyTONull()
176                 ?: RemoveAction.DEFAULT.toString()
177
178             try {
179                 when (removeAction) {
180                     RemoveAction.DEFAULT.toString() -> {
181                         bluePrintModelHandler.deleteBlueprintModel(blueprintName, blueprintVersion)
182                         responseObserver.onNext(successStatus(request.commonHeader))
183                     }
184                     else -> {
185                         responseObserver.onNext(
186                             failStatus(
187                                 request.commonHeader,
188                                 "Remove action($removeAction) not implemented",
189                                 BluePrintProcessorException("Not implemented")
190                             )
191                         )
192                     }
193                 }
194             } catch (e: Exception) {
195                 responseObserver.onNext(
196                     failStatus(
197                         request.commonHeader,
198                         "request(${request.commonHeader.requestId}): Failed to delete $blueprint", e
199                     )
200                 )
201             } finally {
202                 responseObserver.onCompleted()
203             }
204         }
205     }
206
207     override fun bootstrapBlueprint(
208         request: BluePrintBootstrapInput,
209         responseObserver: StreamObserver<BluePrintManagementOutput>
210     ) {
211         runBlocking {
212             try {
213                 log.info("request(${request.commonHeader.requestId}): Received bootstrap request")
214                 val bootstrapRequest = BootstrapRequest().apply {
215                     loadModelType = request.loadModelType
216                     loadResourceDictionary = request.loadResourceDictionary
217                     loadCBA = request.loadCBA
218                 }
219                 /** Perform bootstrap of Model Types, Resource Definitions and CBA */
220                 bluePrintModelHandler.bootstrapBlueprint(bootstrapRequest)
221                 responseObserver.onNext(successStatus(request.commonHeader))
222             } catch (e: Exception) {
223                 responseObserver.onNext(
224                     failStatus(
225                         request.commonHeader,
226                         "request(${request.commonHeader.requestId}): Failed to bootstrap", e
227                     )
228                 )
229             } finally {
230                 responseObserver.onCompleted()
231             }
232         }
233     }
234
235     private fun outputWithFileBytes(header: CommonHeader, byteArray: ByteArray): BluePrintManagementOutput =
236         BluePrintManagementOutput.newBuilder()
237             .setCommonHeader(header)
238             .setFileChunk(FileChunk.newBuilder().setChunk(ByteString.copyFrom(byteArray)))
239             .setStatus(
240                 Status.newBuilder()
241                     .setTimestamp(currentTimestamp())
242                     .setMessage(BluePrintConstants.STATUS_SUCCESS)
243                     .setCode(200)
244                     .build()
245             )
246             .build()
247
248     private fun successStatus(header: CommonHeader, propertyContent: String? = null): BluePrintManagementOutput {
249         // Populate Response Payload
250         val propertiesBuilder = BluePrintManagementOutput.newBuilder().propertiesBuilder
251         propertyContent?.let {
252             JsonFormat.parser().merge(propertyContent, propertiesBuilder)
253         }
254         return BluePrintManagementOutput.newBuilder()
255             .setCommonHeader(header)
256             .setProperties(propertiesBuilder.build())
257             .setStatus(
258                 Status.newBuilder()
259                     .setTimestamp(currentTimestamp())
260                     .setMessage(BluePrintConstants.STATUS_SUCCESS)
261                     .setCode(200)
262                     .build()
263             )
264             .build()
265     }
266
267     private fun failStatus(header: CommonHeader, message: String, e: Exception): BluePrintManagementOutput {
268         log.error(message, e)
269         return BluePrintManagementOutput.newBuilder()
270             .setCommonHeader(header)
271             .setStatus(
272                 Status.newBuilder()
273                     .setTimestamp(currentTimestamp())
274                     .setMessage(BluePrintConstants.STATUS_FAILURE)
275                     .setErrorMessage(message)
276                     .setCode(500)
277                     .build()
278             )
279             .build()
280         //        return io.grpc.Status.INTERNAL
281         //                .withDescription(message)
282         //                .withCause(e)
283         //                .asException()
284     }
285 }