Migrate "ms/controllerblueprints" from ccsdk/apps
[ccsdk/cds.git] / ms / controllerblueprints / modules / service / src / main / kotlin / org / onap / ccsdk / apps / controllerblueprints / service / load / ModelTypeLoadService.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.ccsdk.apps.controllerblueprints.service.load
18
19 import com.att.eelf.configuration.EELFManager
20 import kotlinx.coroutines.*
21 import org.apache.commons.io.FilenameUtils
22 import org.apache.commons.lang3.text.StrBuilder
23 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
25 import org.onap.ccsdk.apps.controllerblueprints.core.data.*
26 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
27 import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType
28 import org.onap.ccsdk.apps.controllerblueprints.service.handler.ModelTypeHandler
29 import org.springframework.stereotype.Service
30 import java.io.File
31 import java.nio.charset.Charset
32
33 @Service
34 open class ModelTypeLoadService(private val modelTypeHandler: ModelTypeHandler) {
35
36     private val log = EELFManager.getInstance().getLogger(ModelTypeLoadService::class.java)
37     private val updateBySystem = "System"
38
39     open suspend fun loadPathsModelType(modelTypePaths: List<String>) {
40         modelTypePaths.forEach { runBlocking { loadPathModelType(it) } }
41     }
42
43     /**
44      * Load the Model Type file content from the defined path, Load of sequencing should be maintained.
45      */
46     open suspend fun loadPathModelType(modelTypePath: String) = runBlocking {
47         log.info(" *************************** loadModelType **********************")
48         try {
49             val errorBuilder = StrBuilder()
50
51             coroutineScope {
52                 val dataTypeFiles = File("$modelTypePath/data_type").listFiles()
53
54                 val deferredResults = mutableListOf<Deferred<Unit>>()
55
56                 for (file in dataTypeFiles) deferredResults += async {
57                     loadModelType(file, DataType::class.java, errorBuilder)
58                 }
59
60                 deferredResults.awaitAll()
61             }
62
63             coroutineScope {
64                 val artifactTypeFiles = File("$modelTypePath/artifact_type").listFiles()
65
66                 val deferredResults = mutableListOf<Deferred<Unit>>()
67
68                 for (file in artifactTypeFiles) deferredResults += async {
69                     loadModelType(file,
70                             ArtifactType::class.java, errorBuilder)
71                 }
72
73                 deferredResults.awaitAll()
74             }
75
76             coroutineScope {
77                 val relationshipTypeFiles = File("$modelTypePath/relationship_type").listFiles()
78
79                 val deferredResults = mutableListOf<Deferred<Unit>>()
80
81                 for (file in relationshipTypeFiles) deferredResults += async {
82                     loadModelType(file,
83                             RelationshipType::class.java, errorBuilder)
84                 }
85
86                 deferredResults.awaitAll()
87             }
88
89             coroutineScope {
90                 val nodeTypeFiles = File("$modelTypePath/node_type").listFiles()
91
92                 val deferredResults = mutableListOf<Deferred<Unit>>()
93
94                 for (file in nodeTypeFiles) deferredResults += async {
95                     loadModelType(file,
96                             NodeType::class.java, errorBuilder)
97                 }
98                 deferredResults.awaitAll()
99             }
100
101             if (!errorBuilder.isEmpty) {
102                 log.error(errorBuilder.toString())
103             }
104         } catch (e: Exception) {
105             log.error("Failed to loade ModelTypes under($modelTypePath)", e)
106         }
107     }
108
109     private inline fun <reified T> loadModelType(file: File, classType: Class<T>, errorBuilder: StrBuilder) {
110         try {
111             log.trace("Loading ${classType.name} (${file.name})")
112             val dataKey = FilenameUtils.getBaseName(file.name)
113             val definitionContent = file.readText(Charset.defaultCharset())
114             val definition = JacksonUtils.readValue(definitionContent, classType) as EntityType
115             //checkNotNull(definition) { "failed to get data type from file : ${file.name}" }
116
117             val modelType = ModelType()
118             val definitionType: String?
119             when (T::class) {
120                 DataType::class -> {
121                     definitionType = BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE
122                 }
123                 RelationshipType::class -> {
124                     definitionType = BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE
125                 }
126                 ArtifactType::class -> {
127                     definitionType = BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE
128                 }
129                 NodeType::class -> {
130                     definitionType = BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE
131                 }
132                 else -> {
133                     throw BluePrintException("couldn't process model type($classType) definition")
134                 }
135             }
136             modelType.definitionType = definitionType
137             modelType.derivedFrom = definition.derivedFrom
138             modelType.description = definition.description
139             modelType.definition = JacksonUtils.jsonNode(definitionContent)
140             modelType.modelName = dataKey
141             modelType.version = definition.version
142             modelType.updatedBy = updateBySystem
143             modelType.tags = (dataKey + "," + definition.derivedFrom + "," + definitionType)
144             modelTypeHandler.saveModel(modelType)
145             log.trace("${classType.name}(${file.name}) loaded successfully ")
146         } catch (e: Exception) {
147             errorBuilder.appendln("Couldn't load ${classType.name}(${file.name}: ${e.message}")
148         }
149     }
150 }