aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xms/blueprintsprocessor/application/pom.xml16
-rw-r--r--ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintDatabaseConfiguration.kt6
-rw-r--r--ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.kt5
-rw-r--r--ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorExceptionHandler.kt25
-rwxr-xr-xms/blueprintsprocessor/application/src/main/resources/application-dev.properties7
-rwxr-xr-xms/blueprintsprocessor/application/src/main/resources/application.properties8
-rw-r--r--ms/blueprintsprocessor/application/src/main/resources/error-messages_en.properties32
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/ErrorCatalogTestConfiguration.kt28
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/error/ErrorCatalogServiceTest.kt97
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/application-test.properties6
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/application.properties5
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/error-messages_en.properties32
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintException.kt27
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt109
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt22
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorHandling.kt40
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorHandling.kt36
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt44
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt6
-rwxr-xr-xms/blueprintsprocessor/parent/pom.xml30
-rwxr-xr-xms/error-catalog/README.md36
-rw-r--r--ms/error-catalog/application/pom.xml31
-rw-r--r--ms/error-catalog/core/pom.xml31
-rw-r--r--ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogException.kt112
-rw-r--r--ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogExtensions.kt32
-rw-r--r--ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCodes.kt88
-rw-r--r--ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorLibData.kt94
-rw-r--r--ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorMessageLibConstants.kt30
-rw-r--r--ms/error-catalog/pom.xml158
-rw-r--r--ms/error-catalog/services/pom.xml38
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogConfiguration.kt34
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogDBService.kt98
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogExceptionHandler.kt31
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogLoadService.kt145
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogService.kt91
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogServiceExtensions.kt25
-rwxr-xr-xms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/Domain.kt76
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/ErrorMessageModel.kt69
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/DomainRepository.kt45
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/ErrorMessageModelRepository.kt36
-rw-r--r--ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/utils/ErrorCatalogUtils.kt39
-rw-r--r--ms/pom.xml20
-rw-r--r--ms/py-executor/resource_resolution/README63
-rw-r--r--ms/py-executor/resource_resolution/authorization.py64
-rw-r--r--ms/py-executor/resource_resolution/client.py31
-rw-r--r--ms/py-executor/resource_resolution/resource_resolution.py294
-rw-r--r--ms/py-executor/resource_resolution/tests/authorization_interceptor_test.py50
-rw-r--r--ms/py-executor/resource_resolution/tests/resource_resolution_test.py105
-rw-r--r--ms/sdclistener/application/pom.xml6
-rw-r--r--ms/sdclistener/application/src/main/resources/application.yaml2
-rw-r--r--ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/SdcListenerConfigurationTest.java2
-rwxr-xr-xms/sdclistener/parent/pom.xml2
52 files changed, 2494 insertions, 65 deletions
diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml
index b75e16134..a6dd73ba6 100755
--- a/ms/blueprintsprocessor/application/pom.xml
+++ b/ms/blueprintsprocessor/application/pom.xml
@@ -46,9 +46,9 @@
<dependencies>
<dependency>
- <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
- <artifactId>blueprint-core</artifactId>
- <exclusions>
+ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+ <artifactId>blueprint-core</artifactId>
+ <exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
@@ -66,6 +66,12 @@
</exclusions>
</dependency>
+ <!-- Error Catalog Services -->
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-services</artifactId>
+ </dependency>
+
<!-- North Bound -->
<dependency>
<groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
@@ -306,6 +312,10 @@
<target>1.8</target>
</configuration>
</plugin>
+ <plugin>
+ <groupId>pl.project13.maven</groupId>
+ <artifactId>git-commit-id-plugin</artifactId>
+ </plugin>
</plugins>
</build>
diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintDatabaseConfiguration.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintDatabaseConfiguration.kt
index 58464cb10..2e268c356 100644
--- a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintDatabaseConfiguration.kt
+++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintDatabaseConfiguration.kt
@@ -31,7 +31,8 @@ import javax.sql.DataSource
@Configuration
@Import(BluePrintDBLibConfiguration::class)
@EnableJpaRepositories(
- basePackages = ["org.onap.ccsdk.cds.controllerblueprints", "org.onap.ccsdk.cds.blueprintsprocessor"],
+ basePackages = ["org.onap.ccsdk.cds.controllerblueprints", "org.onap.ccsdk.cds.blueprintsprocessor",
+ "org.onap.ccsdk.error.catalog"],
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager"
)
@@ -43,7 +44,8 @@ open class BlueprintDatabaseConfiguration(primaryDataSourceProperties: PrimaryDa
open fun primaryEntityManager(): LocalContainerEntityManagerFactoryBean {
return primaryEntityManager(
"org.onap.ccsdk.cds.controllerblueprints",
- "org.onap.ccsdk.cds.blueprintsprocessor"
+ "org.onap.ccsdk.cds.blueprintsprocessor",
+ "org.onap.ccsdk.error.catalog"
)
}
diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.kt
index 1d1baeeef..7a888f95c 100644
--- a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.kt
+++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.kt
@@ -30,7 +30,10 @@ import org.springframework.context.annotation.ComponentScan
*/
@SpringBootApplication
@EnableAutoConfiguration(exclude = [DataSourceAutoConfiguration::class, HazelcastAutoConfiguration::class])
-@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"])
+@ComponentScan(
+ basePackages = ["org.onap.ccsdk.error.catalog",
+ "org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]
+)
open class BlueprintProcessorApplication
fun main(args: Array<String>) {
diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorExceptionHandler.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorExceptionHandler.kt
new file mode 100644
index 000000000..6fcbdfdb7
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorExceptionHandler.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.onap.ccsdk.error.catalog.services.ErrorCatalogExceptionHandler
+import org.onap.ccsdk.error.catalog.services.ErrorCatalogService
+import org.springframework.web.bind.annotation.RestControllerAdvice
+
+@RestControllerAdvice("org.onap.ccsdk.cds")
+open class BlueprintProcessorExceptionHandler(private val errorCatalogService: ErrorCatalogService) :
+ ErrorCatalogExceptionHandler(errorCatalogService)
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
index fffc2f4c6..671000992 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
@@ -27,6 +27,11 @@ server.port=8081
security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
security.user.name: ccsdkapps
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.defaultDirectory=/opt/app/onap/config
+
### START -Controller Blueprints Properties
# Load Resource Source Mappings
resourceSourceMappings=processor-db=source-db,input=source-input,default=source-default,sdnc=source-rest,aai-data=source-rest,capability=source-capability,vault-data=source-rest,rest=source-rest,script=source-capability
@@ -137,4 +142,4 @@ blueprintsprocessor.messageproducer.self-service-api.topic=producer.t
#blueprintsprocessor.messageconsumer.prioritize-input.type=kafka-streams-basic-auth
#blueprintsprocessor.messageconsumer.prioritize-input.bootstrapServers=127.0.0.1:9092
#blueprintsprocessor.messageconsumer.prioritize-input.applicationId=cds-controller
-#blueprintsprocessor.messageconsumer.prioritize-input.topic=prioritize-input-topic \ No newline at end of file
+#blueprintsprocessor.messageconsumer.prioritize-input.topic=prioritize-input-topic
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties
index d6082bfa9..412fa3a33 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties
@@ -60,6 +60,11 @@ blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts
security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
security.user.name: ccsdkapps
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.defaultDirectory=/opt/app/onap/config
+
# Used in Health Check
#endpoints.user.name=ccsdkapps
#endpoints.user.password=ccsdkapps
@@ -130,5 +135,4 @@ cdslistener.healthcheck.mapping-service-name-with-service-link=[SDC Listener ser
#Actuator properties
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
-
-
+management.info.git.mode=full
diff --git a/ms/blueprintsprocessor/application/src/main/resources/error-messages_en.properties b/ms/blueprintsprocessor/application/src/main/resources/error-messages_en.properties
new file mode 100644
index 000000000..246a1d511
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/main/resources/error-messages_en.properties
@@ -0,0 +1,32 @@
+#
+# Copyright © 2018-2019 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+org.onap.ccsdk.cds.blueprintsprocessor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.sdclistener.generic_failure=cause=Internal error in SDC Listener.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.generic_process_failure=cause=Internal error while processing REST call to the Self Service API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.resolution_failure=cause=Fail to process Resource Resolution.,action=Verify the resource definitions.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.internal_error=cause=Internal error while processing Resource Resolution.,action=Verify the payload.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.invalid_file_extension=cause=Failed trying to upload a non ZIP file format.,action=Please reload your file and make sure it is in ZIP format.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/ErrorCatalogTestConfiguration.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/ErrorCatalogTestConfiguration.kt
new file mode 100644
index 000000000..74a17fa1d
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/ErrorCatalogTestConfiguration.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.uat
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(
+ basePackages = ["org.onap.ccsdk.error.catalog"]
+)
+@EnableAutoConfiguration
+open class ErrorCatalogTestConfiguration
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/error/ErrorCatalogServiceTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/error/ErrorCatalogServiceTest.kt
new file mode 100644
index 000000000..8e399fd1a
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/error/ErrorCatalogServiceTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.uat.error
+
+import org.junit.runner.RunWith
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.ErrorCatalogTestConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.grpcProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException
+import org.onap.ccsdk.error.catalog.core.ErrorCatalog
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogCodes
+import org.onap.ccsdk.error.catalog.core.ErrorMessage
+import org.onap.ccsdk.error.catalog.core.ErrorPayload
+import org.onap.ccsdk.error.catalog.services.ErrorCatalogService
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.junit4.SpringRunner
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+@RunWith(SpringRunner::class)
+@ContextConfiguration(
+ classes = [ErrorCatalogTestConfiguration::class]
+)
+@TestPropertySource(locations = ["classpath:application-test.properties"])
+class ErrorCatalogServiceTest {
+ @Autowired
+ lateinit var errorCatalogService: ErrorCatalogService
+
+ private val domain = "org.onap.ccsdk.cds.blueprintsprocessor"
+ private lateinit var errorType: String
+ private lateinit var errorCatalogHttp: ErrorCatalog
+ private lateinit var errorCatalogGrpc: ErrorCatalog
+ private lateinit var errorPayloadHttp: ErrorPayload
+ private lateinit var errorPayloadGrpc: ErrorPayload
+
+ @BeforeTest
+ fun setup() {
+ errorType = ErrorCatalogCodes.GENERIC_FAILURE
+ errorCatalogHttp = ErrorCatalog(errorType, domain, 500,
+ "Contact CDS administrator team.", "Internal error in Blueprint Processor run time.")
+ errorCatalogGrpc = ErrorCatalog(errorType, domain, 2,
+ "Contact CDS administrator team.", "Internal error in Blueprint Processor run time.")
+
+ errorPayloadHttp = ErrorPayload(500, ErrorCatalogCodes.GENERIC_FAILURE,
+ "Cause: Internal error in Blueprint Processor run time. \n Action : Contact CDS administrator team.",
+ errorMessage = ErrorMessage("org.onap.ccsdk.cds.blueprintsprocessor",
+ "Internal error in Blueprint Processor run time.", ""))
+ errorPayloadGrpc = ErrorPayload(2, ErrorCatalogCodes.GENERIC_FAILURE,
+ "Cause: Internal error in Blueprint Processor run time. \n Action : Contact CDS administrator team.",
+ errorMessage = ErrorMessage("org.onap.ccsdk.cds.blueprintsprocessor",
+ "Internal error in Blueprint Processor run time.", ""))
+ }
+
+ @Test
+ fun errorPayloadHttp() {
+ val errorPayload = errorCatalogService.errorPayload(httpProcessorException(errorType, domain,
+ "Internal error in Blueprint Processor run time."))
+ assertTrue { errorPayload.isEqualTo(errorPayloadHttp) }
+ }
+
+ @Test
+ fun errorPayloadGrpc() {
+ val errorPayload = errorCatalogService.errorPayload(grpcProcessorException(errorType, domain,
+ "Internal error in Blueprint Processor run time."))
+ assertTrue { errorPayload.isEqualTo(errorPayloadGrpc) }
+ }
+
+ @Test
+ fun getErrorCatalogHttp() {
+ val errorCatalog = errorCatalogService.getErrorCatalog(httpProcessorException(errorType, domain,
+ "Internal error in Blueprint Processor run time."))
+ assertTrue { errorCatalog == errorCatalogHttp }
+ }
+
+ @Test
+ fun getErrorCatalogGrpc() {
+ val errorCatalog = errorCatalogService.getErrorCatalog(grpcProcessorException(errorType, domain,
+ "Internal error in Blueprint Processor run time."))
+ assertTrue { errorCatalog == errorCatalogGrpc }
+ }
+}
diff --git a/ms/blueprintsprocessor/application/src/test/resources/application-test.properties b/ms/blueprintsprocessor/application/src/test/resources/application-test.properties
index 1d2565be3..83589403d 100644
--- a/ms/blueprintsprocessor/application/src/test/resources/application-test.properties
+++ b/ms/blueprintsprocessor/application/src/test/resources/application-test.properties
@@ -16,6 +16,11 @@
spring.http.log-request-details=true
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.defaultDirectory=./src/test/resources/
+
blueprintsprocessor.httpPort=0
blueprintsprocessor.grpcEnable=true
blueprintsprocessor.grpcPort=0
@@ -61,4 +66,3 @@ blueprintprocessor.healthcheck.mapping-service-name-with-service-link=[Execution
#BaseUrls for health check Cds Listener services
cdslistener.healthcheck.baseUrl=http://cds-sdc-listener:8080/
cdslistener.healthcheck.mapping-service-name-with-service-link=[SDC Listener service,/api/v1/sdclistener/healthcheck]
-
diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties
index ea14c493a..eabc141f9 100644
--- a/ms/blueprintsprocessor/application/src/test/resources/application.properties
+++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties
@@ -61,6 +61,11 @@ blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts
security.user.password:{bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
security.user.name:ccsdkapps
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.defaultDirectory=/opt/app/onap/config
+
# Executor Options
blueprintsprocessor.resourceResolution.enabled=true
blueprintsprocessor.netconfExecutor.enabled=true
diff --git a/ms/blueprintsprocessor/application/src/test/resources/error-messages_en.properties b/ms/blueprintsprocessor/application/src/test/resources/error-messages_en.properties
new file mode 100644
index 000000000..246a1d511
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/resources/error-messages_en.properties
@@ -0,0 +1,32 @@
+#
+# Copyright © 2018-2019 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+org.onap.ccsdk.cds.blueprintsprocessor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.sdclistener.generic_failure=cause=Internal error in SDC Listener.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.generic_process_failure=cause=Internal error while processing REST call to the Self Service API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.resolution_failure=cause=Fail to process Resource Resolution.,action=Verify the resource definitions.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.internal_error=cause=Internal error while processing Resource Resolution.,action=Verify the payload.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.invalid_file_extension=cause=Failed trying to upload a non ZIP file format.,action=Please reload your file and make sure it is in ZIP format.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintException.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintException.kt
index a2435da13..74e6bb6bd 100644
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintException.kt
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintException.kt
@@ -1,5 +1,6 @@
/*
* Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 - 2020 IBM, Bell Canada.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,29 +22,13 @@ package org.onap.ccsdk.cds.controllerblueprints.core
*
* @author Brinda Santh
*/
-class BluePrintException : Exception {
-
- var code: Int = 100
+class BluePrintException : BluePrintProcessorException {
constructor(cause: Throwable) : super(cause)
constructor(message: String) : super(message)
constructor(message: String, cause: Throwable) : super(message, cause)
- constructor(cause: Throwable, message: String, vararg args: Any?) : super(String.format(message, *args), cause)
-
- constructor(code: Int, cause: Throwable) : super(cause) {
- this.code = code
- }
-
- constructor(code: Int, message: String) : super(message) {
- this.code = code
- }
-
- constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {
- this.code = code
- }
-
- constructor(code: Int, cause: Throwable, message: String, vararg args: Any?) :
- super(String.format(message, *args), cause) {
- this.code = code
- }
+ constructor(cause: Throwable, message: String, vararg args: Any?) : super(cause, message, args)
+ constructor(code: Int, cause: Throwable) : super(code, cause)
+ constructor(code: Int, message: String) : super(code, message)
+ constructor(code: Int, message: String, cause: Throwable) : super(code, message, cause)
}
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt
index b0b217051..50b6614ad 100644
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt
@@ -1,6 +1,6 @@
/*
* Copyright © 2017-2018 AT&T Intellectual Property.
- * Modifications Copyright © 2018 IBM.
+ * Modifications Copyright © 2018 - 2020 IBM, Bell Canada.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,35 +17,55 @@
package org.onap.ccsdk.cds.controllerblueprints.core
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogException
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogExceptionFluent
+import org.onap.ccsdk.error.catalog.core.ErrorMessage
+
/**
*
*
* @author Brinda Santh
*/
-class BluePrintProcessorException : RuntimeException {
-
- var code: Int = 100
+open class BluePrintProcessorException : ErrorCatalogException, ErrorCatalogExceptionFluent<BluePrintProcessorException> {
constructor(message: String, cause: Throwable) : super(message, cause)
constructor(message: String) : super(message)
constructor(cause: Throwable) : super(cause)
- constructor(cause: Throwable, message: String, vararg args: Any?) : super(format(message, *args), cause)
+ constructor(cause: Throwable, message: String, vararg args: Any?) : super(cause, message, args)
+ constructor(code: Int, cause: Throwable) : super(code, cause)
+ constructor(code: Int, message: String) : super(code, message)
+ constructor(code: Int, message: String, cause: Throwable) : super(code, message, cause)
+
+ override fun code(code: Int): BluePrintProcessorException {
+ return this.updateCode(code)
+ }
+
+ override fun domain(domain: String): BluePrintProcessorException {
+ return this.updateDomain(domain)
+ }
+
+ override fun action(action: String): BluePrintProcessorException {
+ return this.updateAction(action)
+ }
- constructor(code: Int, cause: Throwable) : super(cause) {
- this.code = code
+ override fun http(type: String): BluePrintProcessorException {
+ return this.updateHttp(type)
}
- constructor(code: Int, message: String) : super(message) {
- this.code = code
+ override fun grpc(type: String): BluePrintProcessorException {
+ return this.updateGrpc(type)
}
- constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {
- this.code = code
+ override fun payloadMessage(message: String): BluePrintProcessorException {
+ return this.updatePayloadMessage(message)
}
- constructor(code: Int, cause: Throwable, message: String, vararg args: Any?) :
- super(String.format(message, *args), cause) {
- this.code = code
+ override fun addErrorPayloadMessage(message: String): BluePrintProcessorException {
+ return this.updateErrorPayloadMessage(message)
+ }
+
+ override fun addSubError(errorMessage: ErrorMessage): BluePrintProcessorException {
+ return this.updateSubError(errorMessage)
}
}
@@ -55,3 +75,64 @@ class BluePrintRetryException : RuntimeException {
constructor(cause: Throwable) : super(cause)
constructor(cause: Throwable, message: String, vararg args: Any?) : super(format(message, *args), cause)
}
+
+/** Extension Functions */
+
+fun processorException(message: String): BluePrintProcessorException {
+ return BluePrintProcessorException(message)
+}
+
+fun processorException(code: Int, message: String): BluePrintProcessorException {
+ return processorException(message).code(code)
+}
+
+fun httpProcessorException(type: String, message: String): BluePrintProcessorException {
+ return processorException(message).http(type)
+}
+
+fun grpcProcessorException(type: String, message: String): BluePrintProcessorException {
+ return processorException(message).grpc(type)
+}
+
+fun httpProcessorException(type: String, domain: String, message: String): BluePrintProcessorException {
+ val bluePrintProcessorException = processorException(message).http(type)
+ return bluePrintProcessorException.addDomainAndErrorMessage(domain, message)
+}
+
+fun grpcProcessorException(type: String, domain: String, message: String): BluePrintProcessorException {
+ val bluePrintProcessorException = processorException(message).grpc(type)
+ return bluePrintProcessorException.addDomainAndErrorMessage(domain, message)
+}
+
+fun httpProcessorException(type: String, domain: String, message: String, cause: Throwable):
+ BluePrintProcessorException {
+ val bluePrintProcessorException = processorException(message).http(type)
+ return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, cause)
+}
+
+fun grpcProcessorException(type: String, domain: String, message: String, cause: Throwable):
+ BluePrintProcessorException {
+ val bluePrintProcessorException = processorException(message).grpc(type)
+ return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, cause)
+}
+
+fun BluePrintProcessorException.updateErrorMessage(domain: String, message: String, cause: Throwable):
+ BluePrintProcessorException {
+ return this.addDomainAndErrorMessage(domain, message, cause).domain(domain)
+ .addErrorPayloadMessage(message)
+ .payloadMessage(message)
+}
+
+fun BluePrintProcessorException.updateErrorMessage(domain: String, message: String): BluePrintProcessorException {
+ return this.addDomainAndErrorMessage(domain, message).domain(domain)
+ .addErrorPayloadMessage(message)
+ .payloadMessage(message)
+}
+
+private fun BluePrintProcessorException.addDomainAndErrorMessage(
+ domain: String,
+ message: String,
+ cause: Throwable = Throwable()
+): BluePrintProcessorException {
+ return this.addSubError(ErrorMessage(domain, message, cause.message ?: "")).domain(domain)
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
index ff9aed664..1f01d1ce3 100644
--- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
@@ -211,24 +211,28 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint
}
@PostMapping(
- path = arrayOf("/workflow-spec"), produces = arrayOf(MediaType
- .APPLICATION_JSON_VALUE),
- consumes = arrayOf(MediaType.APPLICATION_JSON_VALUE)
+ path = arrayOf("/workflow-spec"), produces = arrayOf(
+ MediaType
+ .APPLICATION_JSON_VALUE
+ ),
+ consumes = arrayOf(MediaType.APPLICATION_JSON_VALUE)
)
@ResponseBody
@Throws(BluePrintException::class)
@PreAuthorize("hasRole('USER')")
suspend fun workflowSpec(@RequestBody workFlowSpecReq: WorkFlowSpecRequest):
- ResponseEntity<String> = mdcWebCoroutineScope {
+ ResponseEntity<String> = mdcWebCoroutineScope {
var json = bluePrintModelHandler.prepareWorkFlowSpec(workFlowSpecReq)
- .asJsonString()
+ .asJsonString()
ResponseEntity(json, HttpStatus.OK)
}
@GetMapping(
- path = arrayOf("/workflows/blueprint-name/{name}/version/{version" +
- "}"),
- produces = arrayOf(MediaType.APPLICATION_JSON_VALUE)
+ path = arrayOf(
+ "/workflows/blueprint-name/{name}/version/{version" +
+ "}"
+ ),
+ produces = arrayOf(MediaType.APPLICATION_JSON_VALUE)
)
@ResponseBody
@Throws(BluePrintException::class)
@@ -240,7 +244,7 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint
@PathVariable(value = "version") version: String
): ResponseEntity<String> = mdcWebCoroutineScope {
var json = bluePrintModelHandler.getWorkflowNames(name, version)
- .asJsonString()
+ .asJsonString()
ResponseEntity(json, HttpStatus.OK)
}
}
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorHandling.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorHandling.kt
new file mode 100644
index 000000000..ae91246fe
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorHandling.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.designer.api
+
+object DesignerApiDomains {
+ // Designer Api Domains Constants
+ const val DESIGNER_API = "org.onap.ccsdk.cds.blueprintsprocessor.designer.api"
+ const val DESIGNER_API_ENHANCER = "org.onap.ccsdk.cds.blueprintsprocessor.designer.api.enhancer"
+ const val DESIGNER_API_HANDLER = "org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler"
+ const val DESIGNER_API_LOAD = "org.onap.ccsdk.cds.blueprintsprocessor.designer.api.load"
+ const val DESIGNER_API_SERVICE = "org.onap.ccsdk.cds.blueprintsprocessor.designer.api.service"
+}
+
+object DesignerApiHttpErrorCodes {
+ init {
+ // Register HttpErrorCodes
+ // HttpErrorCodes.register("", 200)
+ }
+}
+
+object DesignerGrpcErrorCodes {
+ init {
+ // Register GrpcErrorCodes
+ // GrpcErrorCodes.register("", 3)
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorHandling.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorHandling.kt
new file mode 100644
index 000000000..b37cd0eda
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorHandling.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.resource.api
+
+object ResourceApiDomains {
+ // Resource Api Domains Constants
+ const val RESOURCE_API = "org.onap.ccsdk.cds.blueprintsprocessor.resource.api"
+}
+
+object ResourceApiHttpErrorCodes {
+ init {
+ // Register HttpErrorCodes
+ // HttpErrorCodes.register("", 200)
+ }
+}
+
+object ResourceGrpcErrorCodes {
+ init {
+ // Register GrpcErrorCodes
+ // GrpcErrorCodes.register("", 3)
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt
new file mode 100644
index 000000000..b76bc263a
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
+
+object SelfServiceApiDomains {
+ // SelfServiceApi Domains Constants
+ const val BLUEPRINT_PROCESSOR = "org.onap.ccsdk.cds.blueprintsprocessor"
+ const val SELF_SERVICE_API = "org.onap.ccsdk.cds.blueprintsprocessor.resource.api"
+ const val SELF_SERVICE_API_VALIDATOR = "org.onap.ccsdk.cds.blueprintsprocessor.resource.api.validator"
+ const val NETCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor"
+ const val RESOURCE_RESOLUTION = "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution"
+ const val RESTCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor"
+ const val CLI_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor"
+ const val PYTHON_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor"
+ const val SDC_LISTENER = "org.onap.ccsdk.cds.sdclistener"
+}
+
+object SelfServiceApiHttpErrorCodes {
+ init {
+ // Register HttpErrorCodes
+ // HttpErrorCodes.register("", 200)
+ }
+}
+
+object SelfServiceGrpcErrorCodes {
+ init {
+ // Register GrpcErrorCodes
+ // GrpcErrorCodes.register("", 3)
+ }
+}
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 8b268d6f8..908c04607 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
@@ -27,7 +27,9 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutp
import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.mdcWebCoroutineScope
import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.determineHttpStatusCode
import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException
import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogCodes
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
@@ -81,7 +83,9 @@ open class ExecutionServiceController {
): ResponseEntity<ExecutionServiceOutput> = mdcWebCoroutineScope {
if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
- throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
+ throw httpProcessorException(ErrorCatalogCodes.GENERIC_FAILURE,
+ SelfServiceApiDomains.BLUEPRINT_PROCESSOR,
+ "Can't process async request through the REST endpoint. Use gRPC for async processing.")
}
ph.register()
val processResult = executionServiceHandler.doProcess(executionServiceInput)
diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml
index d1de10845..8349fa79a 100755
--- a/ms/blueprintsprocessor/parent/pom.xml
+++ b/ms/blueprintsprocessor/parent/pom.xml
@@ -35,6 +35,7 @@
<sli.version>${ccsdk.sli.core.version}</sli.version>
<!-- Override CDS version from parent to be project.version -->
<ccsdk.cds.version>${project.version}</ccsdk.cds.version>
+ <error.catalog.version>${project.version}</error.catalog.version>
<dmaap.client.version>1.1.5</dmaap.client.version>
<!-- Should be using released artifact as soon as available: -->
<!-- https://github.com/springfox/springfox/milestone/44 -->
@@ -291,6 +292,30 @@
<version>${kafka.version}</version>
</dependency>
+ <!-- Error Catalog -->
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-core</artifactId>
+ <version>${error.catalog.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-services</artifactId>
+ <version>${error.catalog.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
<!-- SLI Version -->
<dependency>
<groupId>org.onap.ccsdk.sli.core</groupId>
@@ -689,6 +714,11 @@
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-core</artifactId>
+ </dependency>
</dependencies>
<repositories>
diff --git a/ms/error-catalog/README.md b/ms/error-catalog/README.md
new file mode 100755
index 000000000..d6ae56d02
--- /dev/null
+++ b/ms/error-catalog/README.md
@@ -0,0 +1,36 @@
+## How to use library
+
+##### 1. Set Error Catalog service type (Database or properties file service) in application.properties file
+
+```
+##### Error Managements #####
+## For database service type ##
+# error.catalog.type=DB
+## For database service type ##
+# error.catalog.type=properties
+error.catalog.applicationId=cds
+error.catalog.type=properties
+```
+
+##### 2. Generate exception
+
+- HTTP Error Exception
+```
+errorCatalogException: ErrorCatalogException = httpProcessorException(ErrorCatalogCodes.ERROR_TYPE,
+"Error message here...")
+```
+
+- GRPC Error Exception
+```
+errorCatalogException: ErrorCatalogException = grpcProcessorException(ErrorCatalogCodes.ERROR_TYPE,
+"Error message here...")
+```
+
+##### 3. Update an existing exception
+```
+e = errorCatalogException.code(500)
+e = errorCatalogException.action("message")
+...
+```
+
+##### 4. Add a HTTP REST Exception handler \ No newline at end of file
diff --git a/ms/error-catalog/application/pom.xml b/ms/error-catalog/application/pom.xml
new file mode 100644
index 000000000..dc9d3120b
--- /dev/null
+++ b/ms/error-catalog/application/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 2018-2019 AT&T Intellectual Property.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ 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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>error-catalog-application</artifactId>
+
+ <name>Error Catalog Application</name>
+ <description>Error Catalog Application</description>
+</project>
diff --git a/ms/error-catalog/core/pom.xml b/ms/error-catalog/core/pom.xml
new file mode 100644
index 000000000..7a46dbc7c
--- /dev/null
+++ b/ms/error-catalog/core/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 2018-2019 AT&T Intellectual Property.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ 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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>error-catalog-core</artifactId>
+
+ <name>Error Catalog Core</name>
+ <description>Error Catalog Core</description>
+</project>
diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogException.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogException.kt
new file mode 100644
index 000000000..76f9cc0f1
--- /dev/null
+++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogException.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ * Modifications Copyright © 2019-2020 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.core
+
+interface ErrorCatalogExceptionFluent<T> {
+ fun code(code: Int): T
+ fun domain(domain: String): T
+ fun action(action: String): T
+ fun http(type: String): T
+ fun grpc(type: String): T
+ fun payloadMessage(message: String): T
+ fun addErrorPayloadMessage(message: String): T
+ fun addSubError(errorMessage: ErrorMessage): T
+}
+
+open class ErrorCatalogException : RuntimeException {
+ var code: Int = -1
+ var domain: String = ""
+ var name: String = ErrorCatalogCodes.GENERIC_FAILURE
+ var action: String = ""
+ var errorPayload: ErrorPayload? = null
+ var protocol: String = ""
+ var errorPayloadMessages: MutableList<String>? = null
+
+ val messageSeparator = "${System.lineSeparator()} -> "
+
+ constructor(message: String, cause: Throwable) : super(message, cause)
+ constructor(message: String) : super(message)
+ constructor(cause: Throwable) : super(cause)
+ constructor(cause: Throwable, message: String, vararg args: Any?) : super(format(message, *args), cause)
+
+ constructor(code: Int, cause: Throwable) : super(cause) {
+ this.code = code
+ }
+
+ constructor(code: Int, message: String) : super(message) {
+ this.code = code
+ }
+
+ constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {
+ this.code = code
+ }
+
+ constructor(code: Int, cause: Throwable, message: String, vararg args: Any?) :
+ super(String.format(message, *args), cause) {
+ this.code = code
+ }
+
+ open fun <T : ErrorCatalogException> updateCode(code: Int): T {
+ this.code = code
+ return this as T
+ }
+
+ open fun <T : ErrorCatalogException> updateDomain(domain: String): T {
+ this.domain = domain
+ return this as T
+ }
+
+ open fun <T : ErrorCatalogException> updateAction(action: String): T {
+ this.action = action
+ return this as T
+ }
+
+ fun <T : ErrorCatalogException> updateHttp(type: String): T {
+ this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_HTTP
+ this.code = HttpErrorCodes.code(type)
+ return this as T
+ }
+
+ fun <T : ErrorCatalogException> updateGrpc(type: String): T {
+ this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_GRPC
+ this.code = GrpcErrorCodes.code(type)
+ return this as T
+ }
+
+ fun <T : ErrorCatalogException> updatePayloadMessage(message: String): T {
+ if (this.errorPayloadMessages == null) this.errorPayloadMessages = arrayListOf()
+ this.errorPayloadMessages!!.add(message)
+ return this as T
+ }
+
+ fun <T : ErrorCatalogException> updateErrorPayloadMessage(message: String): T {
+ if (errorPayload == null) {
+ errorPayload = ErrorPayload()
+ }
+ errorPayload!!.message = "${errorPayload!!.message} $messageSeparator $message"
+ return this as T
+ }
+
+ fun <T : ErrorCatalogException> updateSubError(errorMessage: ErrorMessage): T {
+ if (errorPayload == null) {
+ errorPayload = ErrorPayload()
+ }
+ errorPayload!!.subErrors.add(errorMessage)
+ return this as T
+ }
+}
diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogExtensions.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogExtensions.kt
new file mode 100644
index 000000000..76011b27d
--- /dev/null
+++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCatalogExtensions.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.core
+
+import org.slf4j.LoggerFactory
+import org.slf4j.helpers.MessageFormatter
+import kotlin.reflect.KClass
+
+fun <T : Any> logger(clazz: T) = LoggerFactory.getLogger(clazz.javaClass)!!
+
+fun <T : KClass<*>> logger(clazz: T) = LoggerFactory.getLogger(clazz.java)!!
+
+fun format(message: String, vararg args: Any?): String {
+ if (args != null && args.isNotEmpty()) {
+ return MessageFormatter.arrayFormat(message, args).message
+ }
+ return message
+}
diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCodes.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCodes.kt
new file mode 100644
index 000000000..241e9d238
--- /dev/null
+++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorCodes.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.core
+
+object ErrorCatalogCodes {
+ const val GENERIC_FAILURE = "GENERIC_FAILURE"
+ const val GENERIC_PROCESS_FAILURE = "GENERIC_PROCESS_FAILURE"
+ const val INVALID_FILE_EXTENSION = "INVALID_FILE_EXTENSION"
+ const val RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND"
+ const val RESOURCE_PATH_MISSING = "RESOURCE_PATH_MISSING"
+ const val RESOURCE_WRITING_FAIL = "RESOURCE_WRITING_FAIL"
+ const val IO_FILE_INTERRUPT = "IO_FILE_INTERRUPT"
+ const val INVALID_REQUEST_FORMAT = "INVALID_REQUEST_FORMAT"
+ const val UNAUTHORIZED_REQUEST = "UNAUTHORIZED_REQUEST"
+ const val REQUEST_NOT_FOUND = "REQUEST_NOT_FOUND"
+ const val CONFLICT_ADDING_RESOURCE = "CONFLICT_ADDING_RESOURCE"
+ const val DUPLICATE_DATA = "DUPLICATE_DATA"
+}
+
+object HttpErrorCodes {
+ private val store: MutableMap<String, Int> = mutableMapOf()
+
+ init {
+ store[ErrorCatalogCodes.GENERIC_FAILURE] = 500
+ store[ErrorCatalogCodes.GENERIC_PROCESS_FAILURE] = 500
+ store[ErrorCatalogCodes.INVALID_FILE_EXTENSION] = 415
+ store[ErrorCatalogCodes.RESOURCE_NOT_FOUND] = 404
+ store[ErrorCatalogCodes.RESOURCE_PATH_MISSING] = 503
+ store[ErrorCatalogCodes.RESOURCE_WRITING_FAIL] = 503
+ store[ErrorCatalogCodes.IO_FILE_INTERRUPT] = 503
+ store[ErrorCatalogCodes.INVALID_REQUEST_FORMAT] = 400
+ store[ErrorCatalogCodes.UNAUTHORIZED_REQUEST] = 401
+ store[ErrorCatalogCodes.REQUEST_NOT_FOUND] = 404
+ store[ErrorCatalogCodes.CONFLICT_ADDING_RESOURCE] = 409
+ store[ErrorCatalogCodes.DUPLICATE_DATA] = 409
+ }
+
+ fun register(type: String, code: Int) {
+ store[type] = code
+ }
+
+ fun code(type: String): Int {
+ // FIXME("Return Default Error Code , If missing")
+ return store[type]!!
+ }
+}
+
+object GrpcErrorCodes {
+ private val store: MutableMap<String, Int> = mutableMapOf()
+
+ init {
+ store[ErrorCatalogCodes.GENERIC_FAILURE] = 2
+ store[ErrorCatalogCodes.GENERIC_PROCESS_FAILURE] = 2
+ store[ErrorCatalogCodes.INVALID_FILE_EXTENSION] = 3
+ store[ErrorCatalogCodes.RESOURCE_NOT_FOUND] = 5
+ store[ErrorCatalogCodes.RESOURCE_PATH_MISSING] = 3
+ store[ErrorCatalogCodes.RESOURCE_WRITING_FAIL] = 9
+ store[ErrorCatalogCodes.IO_FILE_INTERRUPT] = 3
+ store[ErrorCatalogCodes.INVALID_REQUEST_FORMAT] = 3
+ store[ErrorCatalogCodes.UNAUTHORIZED_REQUEST] = 16
+ store[ErrorCatalogCodes.REQUEST_NOT_FOUND] = 8
+ store[ErrorCatalogCodes.CONFLICT_ADDING_RESOURCE] = 10
+ store[ErrorCatalogCodes.DUPLICATE_DATA] = 11
+ }
+
+ fun register(type: String, code: Int) {
+ store[type] = code
+ }
+
+ fun code(type: String): Int {
+ // FIXME("Return Default Error Code , If missing")
+ return store[type]!!
+ }
+}
diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorLibData.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorLibData.kt
new file mode 100644
index 000000000..b33c118de
--- /dev/null
+++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorLibData.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.core
+
+import com.fasterxml.jackson.annotation.JsonFormat
+import org.slf4j.event.Level
+import org.onap.ccsdk.error.catalog.core.ErrorMessageLibConstants.ERROR_CATALOG_DEFAULT_ERROR_CODE
+import java.time.LocalDateTime
+
+open class ErrorPayload {
+ var code: Int = ERROR_CATALOG_DEFAULT_ERROR_CODE
+ var status: String = ""
+ @get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+ var timestamp: LocalDateTime = LocalDateTime.now()
+ var message: String = ""
+ var debugMessage: String = ""
+ var logLevel: String = Level.ERROR.name
+ val subErrors: ArrayList<ErrorMessage> = ArrayList()
+
+ constructor()
+
+ constructor(
+ code: Int = ERROR_CATALOG_DEFAULT_ERROR_CODE,
+ status: String,
+ message: String,
+ logLevel: String = Level.ERROR.name,
+ debugMessage: String = ""
+ ) {
+ this.code = code
+ this.status = status
+ this.message = message
+ this.logLevel = logLevel
+ this.debugMessage = debugMessage
+ }
+
+ constructor(
+ code: Int = ERROR_CATALOG_DEFAULT_ERROR_CODE,
+ status: String,
+ message: String,
+ logLevel: String = Level.ERROR.name,
+ debugMessage: String = "",
+ errorMessage: ErrorMessage
+ ) {
+ this.code = code
+ this.status = status
+ this.message = message
+ this.logLevel = logLevel
+ this.debugMessage = debugMessage
+ this.subErrors.add(errorMessage)
+ }
+
+ fun isEqualTo(errorPayload: ErrorPayload): Boolean {
+ return (this.code == errorPayload.code && this.status == errorPayload.status && this.message == errorPayload.message &&
+ this.logLevel == errorPayload.logLevel && this.debugMessage == errorPayload.debugMessage &&
+ this.subErrors == errorPayload.subErrors)
+ }
+}
+
+/**
+ *
+ *
+ * @author Steve Siani
+ */
+data class ErrorMessage(
+ val domainId: String,
+ val message: String,
+ val cause: String
+)
+
+data class ErrorCatalog(
+ val errorId: String,
+ val domainId: String,
+ val code: Int,
+ val action: String,
+ val cause: String
+) {
+ fun getMessage(): String {
+ return "Cause: $cause ${System.lineSeparator()} Action : $action"
+ }
+}
diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorMessageLibConstants.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorMessageLibConstants.kt
new file mode 100644
index 000000000..ef56e7b79
--- /dev/null
+++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/error/catalog/core/ErrorMessageLibConstants.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.core
+
+object ErrorMessageLibConstants {
+ const val ERROR_CATALOG_DOMAIN = "org.onap.ccsdk.error.catalog"
+ const val ERROR_CATALOG_TYPE = "error.catalog.type"
+ const val ERROR_CATALOG_TYPE_PROPERTIES = "properties"
+ const val ERROR_CATALOG_TYPE_DB = "DB"
+ const val ERROR_CATALOG_PROPERTIES_FILENAME = "error-messages_en.properties"
+ const val ERROR_CATALOG_MODELS = "org.onap.ccsdk.error.catalog.domain"
+ const val ERROR_CATALOG_REPOSITORY = "org.onap.ccsdk.error.catalog.repository"
+ const val ERROR_CATALOG_DEFAULT_ERROR_CODE = 500
+ const val ERROR_CATALOG_PROTOCOL_HTTP = "http"
+ const val ERROR_CATALOG_PROTOCOL_GRPC = "grpc"
+}
diff --git a/ms/error-catalog/pom.xml b/ms/error-catalog/pom.xml
new file mode 100644
index 000000000..91e13c218
--- /dev/null
+++ b/ms/error-catalog/pom.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 2018-2019 AT&T Intellectual Property.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ 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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.cds</groupId>
+ <artifactId>ms</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Error Catalog Lib</name>
+ <description>Error Catalog Lib for ONAP Components</description>
+
+ <modules>
+ <module>application</module>
+ <module>core</module>
+ <module>services</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-services</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <!-- Kotlin Dependencies -->
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-script-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-jdk8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlinx</groupId>
+ <artifactId>kotlinx-coroutines-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlinx</groupId>
+ <artifactId>kotlinx-coroutines-reactor</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-kotlin</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-compiler-embeddable</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-scripting-jvm-host</artifactId>
+ <!--Use kotlin-compiler-embeddable as koltin-compiler wrap-->
+ <!--guava dependency creating classpath issues at runtime-->
+ <exclusions>
+ <exclusion>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-compiler</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-webflux</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>javax.persistence-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.projectreactor</groupId>
+ <artifactId>reactor-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-maven-plugin</artifactId>
+ <version>${kotlin.maven.version}</version>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <sourceDirs>
+ <sourceDir>src/main/kotlin</sourceDir>
+ </sourceDirs>
+ </configuration>
+ </execution>
+ <execution>
+ <id>test-compile</id>
+ <goals>
+ <goal>test-compile</goal>
+ </goals>
+ <configuration>
+ <sourceDirs>
+ <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
+ </sourceDirs>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/ms/error-catalog/services/pom.xml b/ms/error-catalog/services/pom.xml
new file mode 100644
index 000000000..1adbc4086
--- /dev/null
+++ b/ms/error-catalog/services/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 2018-2019 AT&T Intellectual Property.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ 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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>error-catalog-services</artifactId>
+
+ <name>Error Catalog Service</name>
+ <description>Error Catalog Service</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.error.catalog</groupId>
+ <artifactId>error-catalog-core</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogConfiguration.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogConfiguration.kt
new file mode 100644
index 000000000..8f2440e34
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogConfiguration.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ * Modifications Copyright © 2019-2020 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onap.ccsdk.error.catalog.services
+
+import org.springframework.boot.context.properties.ConfigurationProperties
+import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.context.annotation.Configuration
+import org.springframework.stereotype.Component
+
+@Configuration
+@EnableConfigurationProperties(ErrorCatalogProperties::class)
+open class ErrorCatalogConfiguration
+
+@Component
+@ConfigurationProperties(prefix = "error.catalog")
+open class ErrorCatalogProperties {
+ lateinit var type: String
+ lateinit var applicationId: String
+ var defaultDirectory: String = ""
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogDBService.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogDBService.kt
new file mode 100644
index 000000000..841bcf539
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogDBService.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ * Modifications Copyright © 2019-2020 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services
+
+import org.onap.ccsdk.error.catalog.core.ErrorMessageLibConstants
+import org.onap.ccsdk.error.catalog.services.domain.Domain
+import org.onap.ccsdk.error.catalog.services.domain.ErrorMessageModel
+import org.onap.ccsdk.error.catalog.services.repository.DomainRepository
+import org.onap.ccsdk.error.catalog.services.repository.ErrorMessageModelRepository
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
+import org.springframework.data.domain.Page
+import org.springframework.data.domain.Pageable
+import org.springframework.stereotype.Service
+
+@Service
+@ConditionalOnProperty(
+ name = [ErrorMessageLibConstants.ERROR_CATALOG_TYPE],
+ havingValue = ErrorMessageLibConstants.ERROR_CATALOG_TYPE_DB
+)
+open class ErrorCatalogDBService(
+ private val domainRepository: DomainRepository,
+ private val errorMessageModelRepository: ErrorMessageModelRepository
+) {
+
+ /**
+ * This is a getAllDomains method to retrieve all the Domain in Error Catalog Database by pages
+ *
+ * @return Page<Domain> list of the domains by page
+ </Domain> */
+ open fun getAllDomains(pageRequest: Pageable): Page<Domain> {
+ return domainRepository.findAll(pageRequest)
+ }
+
+ /**
+ * This is a getAllDomains method to retrieve all the Domain in Error Catalog Database
+ *
+ * @return List<Domain> list of the domains
+ </Domain> */
+ open fun getAllDomains(): List<Domain> {
+ return domainRepository.findAll()
+ }
+
+ /**
+ * This is a getAllDomainsByApplication method to retrieve all the Domain that belong to an application in Error Catalog Database
+ *
+ * @return List<Domain> list of the domains
+ </Domain> */
+ open fun getAllDomainsByApplication(applicationId: String): List<Domain> {
+ return domainRepository.findAllByApplicationId(applicationId)
+ }
+
+ /**
+ * This is a getAllErrorMessagesByApplication method to retrieve all the Messages that belong to an application in Error Catalog Database
+ *
+ * @return MutableMap<String, ErrorCode> list of the abstractErrorModel
+ </Domain> */
+ open fun getAllErrorMessagesByApplication(applicationId: String): MutableMap<String, ErrorMessageModel> {
+ val domains = domainRepository.findAllByApplicationId(applicationId)
+ val errorMessages = mutableMapOf<String, ErrorMessageModel>()
+ for (domain in domains) {
+ val errorMessagesFound = errorMessageModelRepository.findByDomainsId(domain.id)
+ for (errorMessageFound in errorMessagesFound) {
+ errorMessages["${domain.name}$MESSAGE_KEY_SEPARATOR${errorMessageFound.messageID}"] = errorMessageFound
+ }
+ }
+ return errorMessages
+ }
+
+ open fun saveDomain(
+ domain: String,
+ applicationId: String,
+ description: String = "",
+ errorMessageList: List<ErrorMessageModel>
+ ) {
+ val domainModel = Domain(domain, applicationId, description)
+ domainModel.errorMessages.addAll(errorMessageList)
+ domainRepository.saveAndFlush(domainModel)
+ }
+
+ companion object {
+ private const val MESSAGE_KEY_SEPARATOR = "."
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogExceptionHandler.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogExceptionHandler.kt
new file mode 100644
index 000000000..91fa97b77
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogExceptionHandler.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services
+
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogException
+import org.onap.ccsdk.error.catalog.core.ErrorPayload
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.ExceptionHandler
+
+abstract class ErrorCatalogExceptionHandler(private val errorCatalogService: ErrorCatalogService) {
+
+ @ExceptionHandler(ErrorCatalogException::class)
+ fun errorCatalogException(e: ErrorCatalogException): ResponseEntity<ErrorPayload> {
+ val errorPayload = errorCatalogService.errorPayload(e)
+ return errorPayload.toResponseEntity()
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogLoadService.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogLoadService.kt
new file mode 100644
index 000000000..d1af5fe55
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogLoadService.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ * Modifications Copyright © 2019-2020 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services
+
+import org.onap.ccsdk.error.catalog.core.ErrorMessageLibConstants
+import org.onap.ccsdk.error.catalog.core.logger
+import org.onap.ccsdk.error.catalog.services.domain.ErrorMessageModel
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
+import org.springframework.stereotype.Service
+import java.io.FileNotFoundException
+import java.io.IOException
+import java.io.InputStream
+import java.nio.file.Paths
+import java.util.Properties
+
+interface ErrorCatalogLoadService {
+
+ suspend fun loadErrorCatalog()
+
+ fun getErrorMessage(domain: String, key: String): String?
+
+ fun getErrorMessage(attribute: String): String?
+}
+
+/**
+ * Representation of Blueprint Error Message lib from database service to load the properties
+ */
+@Service
+@ConditionalOnBean(ErrorCatalogDBService::class)
+open class ErrorCatalogLoadDBService(
+ private var errorCatalogProperties: ErrorCatalogProperties,
+ private var errorCatalogDBService: ErrorCatalogDBService
+) : ErrorCatalogLoadService {
+
+ private var log = logger(ErrorCatalogLoadDBService::class)
+
+ lateinit var errorMessageInDB: Map<String, ErrorMessageModel>
+
+ override suspend fun loadErrorCatalog() {
+ log.info("Application ID: ${errorCatalogProperties.applicationId} > Initializing error catalog message from database...")
+ errorMessageInDB = getErrorMessagesFromDB()
+ }
+
+ override fun getErrorMessage(domain: String, key: String): String? {
+ return getErrorMessage("$domain.${key.toLowerCase()}")
+ }
+
+ override fun getErrorMessage(attribute: String): String? {
+ val errorMessage = findErrorMessage(attribute)
+ return prepareErrorMessage(errorMessage)
+ }
+
+ /**
+ * Parses the error-messages.properties file which contains error messages
+ */
+ private suspend fun getErrorMessagesFromDB(): Map<String, ErrorMessageModel> {
+ return errorCatalogDBService.getAllErrorMessagesByApplication(errorCatalogProperties.applicationId)
+ }
+
+ private fun findErrorMessage(attribute: String): ErrorMessageModel? {
+ return if (errorMessageInDB.containsKey(attribute)) {
+ errorMessageInDB[attribute]
+ } else {
+ null
+ }
+ }
+
+ private fun prepareErrorMessage(errorMessage: ErrorMessageModel?): String? {
+ return if (errorMessage != null) {
+ "cause=${errorMessage.cause}, action=${errorMessage.action}"
+ } else {
+ null
+ }
+ }
+}
+
+/**
+ * Representation of Blueprint Error Message lib property service to load the properties
+ */
+@Service
+@ConditionalOnProperty(
+ name = [ErrorMessageLibConstants.ERROR_CATALOG_TYPE],
+ havingValue = ErrorMessageLibConstants.ERROR_CATALOG_TYPE_PROPERTIES
+)
+open class ErrorCatalogLoadPropertyService(private var errorCatalogProperties: ErrorCatalogProperties) :
+ ErrorCatalogLoadService {
+
+ private val propertyFileName = ErrorMessageLibConstants.ERROR_CATALOG_PROPERTIES_FILENAME
+ private var propertyFileBaseDirectory = Paths.get(errorCatalogProperties.defaultDirectory)
+ private var propertyFilePath = propertyFileBaseDirectory.resolve(propertyFileName)
+
+ private var log = logger(ErrorCatalogLoadPropertyService::class)
+
+ lateinit var properties: Properties
+
+ override suspend fun loadErrorCatalog() {
+ log.info("Application ID: ${errorCatalogProperties.applicationId} > Initializing error catalog message from properties...")
+ properties = parseErrorMessagesProps()
+ }
+
+ override fun getErrorMessage(domain: String, key: String): String? {
+ return getErrorMessage("$domain.${key.toLowerCase()}")
+ }
+
+ override fun getErrorMessage(attribute: String): String? {
+ return properties.getProperty(attribute)
+ }
+
+ /**
+ * Parses the error-messages.properties file which contains error messages
+ */
+ private fun parseErrorMessagesProps(): Properties {
+ var inputStream: InputStream? = null
+ val props = Properties()
+ try {
+ inputStream = propertyFilePath.toFile().inputStream()
+ props.load(inputStream)
+ } catch (e: FileNotFoundException) {
+ log.error("Application ID: ${errorCatalogProperties.applicationId} > Property File '$propertyFileName}' " +
+ "not found in the application directory.")
+ } catch (e: IOException) {
+ log.error("Application ID: ${errorCatalogProperties.applicationId} > Fail to load property file " +
+ "'$propertyFileName}' for message errors.")
+ } finally {
+ inputStream!!.close()
+ }
+ return props
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogService.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogService.kt
new file mode 100644
index 000000000..e55e552d9
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogService.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ * Modifications Copyright © 2019-2020 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services
+
+import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.error.catalog.core.ErrorCatalog
+import org.onap.ccsdk.error.catalog.core.ErrorCatalogException
+import org.onap.ccsdk.error.catalog.core.ErrorMessageLibConstants
+import org.onap.ccsdk.error.catalog.core.ErrorPayload
+import org.onap.ccsdk.error.catalog.core.GrpcErrorCodes
+import org.onap.ccsdk.error.catalog.core.HttpErrorCodes
+import org.onap.ccsdk.error.catalog.services.utils.ErrorCatalogUtils
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
+import org.springframework.stereotype.Service
+import javax.annotation.PostConstruct
+
+@Service
+@ConditionalOnBean(ErrorCatalogLoadService::class)
+open class ErrorCatalogService(private var errorCatalogLoadService: ErrorCatalogLoadService) {
+
+ @PostConstruct
+ open fun init() = runBlocking {
+ errorCatalogLoadService.loadErrorCatalog()
+ }
+
+ fun errorPayload(errorCatalogException: ErrorCatalogException): ErrorPayload {
+ val errorCatalog = getErrorCatalog(errorCatalogException)
+ val errorPayload = ErrorPayload(errorCatalog.code, errorCatalog.errorId, errorCatalog.getMessage())
+ errorPayload.subErrors.addAll(errorCatalogException.errorPayload!!.subErrors)
+ if (errorCatalogException.cause != null) {
+ errorPayload.debugMessage = errorCatalogException.cause!!.printStackTrace().toString()
+ }
+ return errorPayload
+ }
+
+ fun getErrorCatalog(errorCatalogException: ErrorCatalogException): ErrorCatalog {
+ val errorMessage = getMessage(errorCatalogException.domain, errorCatalogException.name)
+ val errorCode =
+ if (errorCatalogException.code == -1) {
+ getProtocolErrorCode(
+ errorCatalogException.protocol,
+ errorCatalogException.name
+ )
+ } else {
+ errorCatalogException.code
+ }
+ val action: String
+ val errorCause: String
+ if (errorMessage.isNullOrEmpty()) {
+ action = errorCatalogException.action
+ errorCause = errorCatalogException.message ?: ""
+ } else {
+ action = ErrorCatalogUtils.readErrorActionFromMessage(errorMessage)
+ errorCause = errorCatalogException.message ?: ErrorCatalogUtils.readErrorCauseFromMessage(errorMessage)
+ }
+
+ return ErrorCatalog(
+ errorCatalogException.name,
+ errorCatalogException.domain,
+ errorCode,
+ action,
+ errorCause
+ )
+ }
+
+ private fun getProtocolErrorCode(protocol: String, type: String): Int {
+ return when (protocol) {
+ ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_GRPC -> GrpcErrorCodes.code(type)
+ else -> HttpErrorCodes.code(type)
+ }
+ }
+
+ private fun getMessage(domain: String, key: String): String? {
+ return errorCatalogLoadService.getErrorMessage(domain, key)
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogServiceExtensions.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogServiceExtensions.kt
new file mode 100644
index 000000000..41481623a
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/ErrorCatalogServiceExtensions.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services
+
+import org.onap.ccsdk.error.catalog.core.ErrorPayload
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+
+fun ErrorPayload.toResponseEntity(): ResponseEntity<ErrorPayload> {
+ return ResponseEntity(this, HttpStatus.resolve(this.code)!!)
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/Domain.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/Domain.kt
new file mode 100755
index 000000000..50a05b231
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/Domain.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services.domain
+
+import java.io.Serializable
+import javax.persistence.CascadeType
+import javax.persistence.Column
+import javax.persistence.Entity
+import javax.persistence.FetchType
+import javax.persistence.Id
+import javax.persistence.Lob
+import javax.persistence.ManyToMany
+import javax.persistence.Table
+import javax.persistence.UniqueConstraint
+import java.util.UUID
+import javax.persistence.JoinTable
+import javax.persistence.JoinColumn
+
+/**
+ * Provide ErrorCode Entity
+ *
+ * @author Steve Siani
+ * @version 1.0
+ */
+
+@Entity
+@Table(name = "ERROR_DOMAINS", uniqueConstraints = [UniqueConstraint(columnNames = ["name", "application_id"])])
+class Domain : Serializable {
+ @Id
+ var id: String = UUID.randomUUID().toString()
+
+ @Column(name = "name")
+ lateinit var name: String
+
+ @Column(name = "application_id")
+ lateinit var applicationId: String
+
+ @Lob
+ @Column(name = "description")
+ var description: String = ""
+
+ @ManyToMany(fetch = FetchType.EAGER, cascade = [CascadeType.ALL])
+ @JoinTable(
+ name = "ERROR_DOMAINS_ERROR_MESSAGES",
+ joinColumns = [JoinColumn(name = "domain_id", referencedColumnName = "id")],
+ inverseJoinColumns = [JoinColumn(name = "message_id", referencedColumnName = "id")]
+ )
+ @Column(name = "error_msg")
+ val errorMessages: MutableSet<ErrorMessageModel> = mutableSetOf()
+
+ constructor()
+
+ constructor(name: String, applicationId: String, description: String) {
+ this.name = name
+ this.description = description
+ this.applicationId = applicationId
+ }
+
+ companion object {
+ private const val serialVersionUID = 1L
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/ErrorMessageModel.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/ErrorMessageModel.kt
new file mode 100644
index 000000000..73e143095
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/domain/ErrorMessageModel.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services.domain
+
+import java.io.Serializable
+import java.util.UUID
+import javax.persistence.CascadeType
+import javax.persistence.Column
+import javax.persistence.Entity
+import javax.persistence.FetchType
+import javax.persistence.Id
+import javax.persistence.Lob
+import javax.persistence.ManyToMany
+import javax.persistence.Table
+import javax.persistence.UniqueConstraint
+
+/**
+ * Provide Error Message Model Entity
+ *
+ * @author Steve Siani
+ * @version 1.0
+ */
+@Entity
+@Table(name = "ERROR_MESSAGES", uniqueConstraints = [UniqueConstraint(columnNames = ["message_id"])])
+class ErrorMessageModel : Serializable {
+
+ @Id
+ var id: String = UUID.randomUUID().toString()
+
+ @Column(name = "message_id", nullable = false)
+ lateinit var messageID: String
+
+ @Lob
+ @Column(name = "cause")
+ var cause: String = ""
+
+ @Lob
+ @Column(name = "action")
+ lateinit var action: String
+
+ @ManyToMany(mappedBy = "errorMessages", fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST])
+ val domains: MutableSet<Domain> = mutableSetOf()
+
+ companion object {
+ private const val serialVersionUID = 1L
+ }
+
+ constructor()
+
+ constructor(messageId: String, cause: String, action: String) {
+ this.messageID = messageId
+ this.cause = cause
+ this.action = action
+ }
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/DomainRepository.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/DomainRepository.kt
new file mode 100644
index 000000000..700340b10
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/DomainRepository.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services.repository
+
+import org.onap.ccsdk.error.catalog.services.domain.Domain
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+/**
+ * @param <T> Model
+ */
+@Repository
+interface DomainRepository : JpaRepository<Domain, String> {
+
+ /**
+ * This is a findByNameAndApplicationId method
+ *
+ * @param name name
+ * @param applicationId applicationId
+ * @return Optional<T>
+ */
+ fun findByNameAndApplicationId(name: String, applicationId: String): Domain?
+
+ /**
+ * This is a findAllByApplicationId method
+ *
+ * @param applicationId applicationId
+ * @return List<T>
+ */
+ fun findAllByApplicationId(applicationId: String): List<Domain>
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/ErrorMessageModelRepository.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/ErrorMessageModelRepository.kt
new file mode 100644
index 000000000..084474970
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/repository/ErrorMessageModelRepository.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.error.catalog.services.repository
+
+import org.onap.ccsdk.error.catalog.services.domain.ErrorMessageModel
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+/**
+ * @param <T> Model
+ */
+@Repository
+interface ErrorMessageModelRepository : JpaRepository<ErrorMessageModel, String> {
+
+ /**
+ * This is a findByDomains method
+ *
+ * @param domainId domainId
+ * @return List<T>
+ */
+ fun findByDomainsId(domainId: String): List<ErrorMessageModel>
+}
diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/utils/ErrorCatalogUtils.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/utils/ErrorCatalogUtils.kt
new file mode 100644
index 000000000..673082eed
--- /dev/null
+++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/error/catalog/services/utils/ErrorCatalogUtils.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2020 IBM, Bell Canada.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onap.ccsdk.error.catalog.services.utils
+
+object ErrorCatalogUtils {
+ private const val REGEX_PATTERN = "^cause=(.*),action=(.*)"
+ private val regex = REGEX_PATTERN.toRegex()
+
+ fun readErrorCauseFromMessage(message: String): String {
+ val matchResults = regex.matchEntire(message)
+ return matchResults!!.groupValues[1]
+ }
+
+ fun readErrorActionFromMessage(message: String): String {
+ val matchResults = regex.matchEntire(message)
+ return matchResults!!.groupValues[2]
+ }
+}
+
+fun Exception.errorCauseOrDefault(): Throwable {
+ return this.cause ?: Throwable()
+}
+
+fun Exception.errorMessageOrDefault(): String {
+ return this.message ?: ""
+}
diff --git a/ms/pom.xml b/ms/pom.xml
index 7ec3f39a2..7a0168f5b 100644
--- a/ms/pom.xml
+++ b/ms/pom.xml
@@ -32,9 +32,29 @@
<description>Micro-services</description>
<modules>
+ <module>error-catalog</module>
<module>blueprintsprocessor</module>
<module>py-executor</module>
<module>command-executor</module>
<module>sdclistener</module>
</modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>pl.project13.maven</groupId>
+ <artifactId>git-commit-id-plugin</artifactId>
+ <version>4.0.0</version>
+ <configuration>
+ <includeOnlyProperties>
+ <includeOnlyProperty>^git.build.(time|version)$</includeOnlyProperty>
+ <includeOnlyProperty>^git.commit.id.(abbrev|full)$</includeOnlyProperty>
+ </includeOnlyProperties>
+ <commitIdGenerationMode>full</commitIdGenerationMode>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
</project>
diff --git a/ms/py-executor/resource_resolution/README b/ms/py-executor/resource_resolution/README
index 222dae499..353600445 100644
--- a/ms/py-executor/resource_resolution/README
+++ b/ms/py-executor/resource_resolution/README
@@ -77,4 +77,67 @@ if __name__ == "__main__":
for response in client.process(generate_messages()):
print(response)
+```
+
+### Authorizarion header
+
+```
+from proto.BluePrintCommon_pb2 import ActionIdentifiers, CommonHeader
+from proto.BluePrintProcessing_pb2 import ExecutionServiceInput
+from resource_resolution.client import Client as ResourceResolutionClient
+
+
+def generate_messages():
+ commonHeader = CommonHeader()
+ commonHeader.requestId = "1234"
+ commonHeader.subRequestId = "1234-1"
+ commonHeader.originatorId = "CDS"
+
+ actionIdentifiers = ActionIdentifiers()
+ actionIdentifiers.blueprintName = "sample-cba"
+ actionIdentifiers.blueprintVersion = "1.0.0"
+ actionIdentifiers.actionName = "SampleScript"
+
+ input = ExecutionServiceInput(commonHeader=commonHeader, actionIdentifiers=actionIdentifiers)
+
+ commonHeader2 = CommonHeader()
+ commonHeader2.requestId = "1235"
+ commonHeader2.subRequestId = "1234-2"
+ commonHeader2.originatorId = "CDS"
+
+ input2 = ExecutionServiceInput(commonHeader=commonHeader2, actionIdentifiers=actionIdentifiers)
+
+ yield from [input, input2]
+
+
+if __name__ == "__main__":
+ with ResourceResolutionClient("127.0.0.1:9111", use_header_auth=True, header_auth_token="Token test") as client:
+ for response in client.process(generate_messages()):
+ print(response)
+
+```
+
+# ResourceResoulution helper class
+
+## How to use examples
+
+### Insecure channel
+
+```
+from resource_resolution.resource_resolution import ResourceResolution, WorkflowExecution, WorkflowExecutionResult
+
+
+if __name__ == "__main__":
+ with ResourceResolution(use_header_auth=True, header_auth_token="Basic token") as rr:
+ for response in rr.execute_workflows( # type: WorkflowExecutionResult
+ WorkflowExecution(
+ blueprint_name="blueprintName",
+ blueprint_version="1.0",
+ workflow_name="resource-assignment"
+ )
+ ):
+ if response.has_error:
+ print(response.error_message)
+ else:
+ print(response.payload)
``` \ No newline at end of file
diff --git a/ms/py-executor/resource_resolution/authorization.py b/ms/py-executor/resource_resolution/authorization.py
new file mode 100644
index 000000000..ae5954ecc
--- /dev/null
+++ b/ms/py-executor/resource_resolution/authorization.py
@@ -0,0 +1,64 @@
+"""Copyright 2020 Deutsche Telekom.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from collections import namedtuple
+from typing import Any, Callable, List
+
+from grpc import ClientCallDetails, StreamStreamClientInterceptor
+
+
+class NewClientCallDetails(
+ namedtuple("_ClientCallDetails", ("method", "timeout", "metadata", "credentials")), ClientCallDetails
+):
+ """Namedtuple class to store metadata.
+
+ It's impossible to change original metadata in ClientCallDetails object
+ passed as a parameter to intercept method, so this class is going to get
+ original metadata tuple and add the authorization one.
+ """
+
+ pass
+
+
+class AuthTokenInterceptor(StreamStreamClientInterceptor):
+ """Interceptor class to set authorization header.
+
+ Set authorization header (but it can be any header also) for a gRPC call.
+ """
+
+ def __init__(self, token: str, header: str = "authorization") -> None:
+ """Initialize interceptor.
+
+ Set token and header which should be set into call. By default header is "authorization".
+ Header have to be lowercase.
+
+ Args:
+ token (str): Token value to be set.
+ header (str, optional): Header name. It must be lowercase. Defaults to "authorization".
+ """
+ self.token: str = token
+ if not header.islower():
+ raise ValueError("Header must be lowercase.")
+ self.header: str = header
+
+ def intercept_stream_stream(
+ self, continuation: Callable, client_call_details: ClientCallDetails, request_iterator: Any
+ ) -> Any:
+ """Add header into metadata."""
+ metadata: List = list(client_call_details.metadata) if client_call_details.metadata is not None else []
+ metadata.append((self.header, self.token,))
+ new_client_call_details: NewClientCallDetails = NewClientCallDetails(
+ client_call_details.method, client_call_details.timeout, metadata, client_call_details.credentials
+ )
+ return continuation(new_client_call_details, request_iterator)
diff --git a/ms/py-executor/resource_resolution/client.py b/ms/py-executor/resource_resolution/client.py
index 89087745c..fee168628 100644
--- a/ms/py-executor/resource_resolution/client.py
+++ b/ms/py-executor/resource_resolution/client.py
@@ -14,12 +14,20 @@ limitations under the License.
"""
from logging import Logger, getLogger
from types import TracebackType
-from typing import Iterable, List, Optional, Type
-
-from grpc import Channel, insecure_channel, secure_channel, ssl_channel_credentials
+from typing import Iterable, Optional, Type
+
+from grpc import (
+ Channel,
+ insecure_channel,
+ intercept_channel,
+ secure_channel,
+ ssl_channel_credentials,
+)
from proto.BluePrintProcessing_pb2 import ExecutionServiceInput, ExecutionServiceOutput
from proto.BluePrintProcessing_pb2_grpc import BluePrintProcessingServiceStub
+from .authorization import AuthTokenInterceptor
+
class Client:
"""Resource resoulution client class."""
@@ -28,20 +36,29 @@ class Client:
self,
server_address: str,
*,
+ # TLS/SSL configuration
use_ssl: bool = False,
root_certificates: bytes = None,
private_key: bytes = None,
certificate_chain: bytes = None,
+ # Authentication header configuration
+ use_header_auth: bool = False,
+ header_auth_token: str = None,
) -> None:
"""Client class initialization.
:param server_address: Address to server to connect.
:param use_ssl: Boolean flag to determine if secure channel should be created or not. Keyword argument.
:param root_certificates: The PEM-encoded root certificates. None if it shouldn't be used. Keyword argument.
- :param private_key: The PEM-encoded private key as a byte string, or None if no private key should be used. Keyword argument.
- :param certificate_chain: The PEM-encoded certificate chain as a byte string to use or or None if no certificate chain should be used. Keyword argument.
+ :param private_key: The PEM-encoded private key as a byte string, or None if no private key should be used.
+ Keyword argument.
+ :param certificate_chain: The PEM-encoded certificate chain as a byte string to use or or None if
+ no certificate chain should be used. Keyword argument.
+ :param use_header_auth: Boolean flag to determine if authorization headed shoud be added for every call or not.
+ Keyword argument.
+ :param header_auth_token: Authorization token value. Keyword argument.
"""
- self.logger = getLogger(__name__)
+ self.logger: Logger = getLogger(__name__)
if use_ssl:
self.channel: Channel = secure_channel(
server_address, ssl_channel_credentials(root_certificates, private_key, certificate_chain)
@@ -50,6 +67,8 @@ class Client:
else:
self.channel: Channel = insecure_channel(server_address)
self.logger.debug(f"Create insecure channel to connect to {server_address}")
+ if use_header_auth:
+ self.channel: Channel = intercept_channel(self.channel, AuthTokenInterceptor(header_auth_token))
self.stub: BluePrintProcessingServiceStub = BluePrintProcessingServiceStub(self.channel)
def close(self) -> None:
diff --git a/ms/py-executor/resource_resolution/resource_resolution.py b/ms/py-executor/resource_resolution/resource_resolution.py
new file mode 100644
index 000000000..e4f162f8f
--- /dev/null
+++ b/ms/py-executor/resource_resolution/resource_resolution.py
@@ -0,0 +1,294 @@
+"""Copyright 2020 Deutsche Telekom.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from enum import Enum, unique
+from logging import Logger, getLogger
+from types import TracebackType
+from typing import Any, Dict, Generator, Optional, Type
+
+from google.protobuf import json_format
+
+from proto.BluePrintProcessing_pb2 import ExecutionServiceInput, ExecutionServiceOutput
+
+from .client import Client
+
+
+@unique
+class WorkflowMode(Enum):
+ """Workflow mode enumerator.
+
+ Workflow can be executed in two modes: synchronously and asynchronously.
+ This enumerator stores valid values to set the mode: SYNC for synchronously mode and ASYNC for asynchronously.
+ """
+
+ SYNC = "sync"
+ ASYNC = "async"
+
+
+class WorkflowExecution:
+ """Wokflow execution class.
+
+ Describes workflow to call. Set blueprint name and version and workflow name to execute.
+ Workflow inputs are optional, by default set to empty directory.
+ Workflow mode is also optional. It is set by default to call workflow synchronously.
+ """
+
+ def __init__(
+ self,
+ blueprint_name: str,
+ blueprint_version: str,
+ workflow_name: str,
+ workflow_inputs: Dict[str, Any] = None,
+ workflow_mode: WorkflowMode = WorkflowMode.SYNC,
+ ) -> None:
+ """Initialize workflow execution.
+
+ Get all needed information to execute workflow.
+
+ Args:
+ blueprint_name (str): Blueprint name to execute workflow from.
+ blueprint_version (str): Blueprint version.
+ workflow_name (str): Name of the workflow to execute
+ workflow_inputs (Dict[str, Any], optional): Key-value workflow inputs. Defaults to None.
+ workflow_mode (WorkflowMode, optional): Workflow execution mode. It can be run synchronously or
+ asynchronously. Defaults to WorkflowMode.SYNC.
+ """
+ self.blueprint_name: str = blueprint_name
+ self.blueprint_version: str = blueprint_version
+ self.workflow_name: str = workflow_name
+ if workflow_inputs is None:
+ workflow_inputs = {}
+ self.workflow_inputs: Dict[str, Any] = workflow_inputs
+ self.workflow_mode: WorkflowMode = workflow_mode
+
+ @property
+ def message(self) -> ExecutionServiceInput:
+ """Workflow execution protobuf message.
+
+ This message is going to be sent to gRPC server to execute workflow.
+
+ Returns:
+ ExecutionServiceInput: Properly filled protobuf message.
+ """
+ execution_msg: ExecutionServiceInput = ExecutionServiceInput()
+ execution_msg.actionIdentifiers.mode = self.workflow_mode.value
+ execution_msg.actionIdentifiers.blueprintName = self.blueprint_name
+ execution_msg.actionIdentifiers.blueprintVersion = self.blueprint_version
+ execution_msg.actionIdentifiers.actionName = self.workflow_name
+ execution_msg.payload.update({f"{self.workflow_name}-request": self.workflow_inputs})
+ return execution_msg
+
+
+class WorkflowExecutionResult:
+ """Result of workflow execution.
+
+ Store both workflow data and the result returns by server.
+ """
+
+ def __init__(self, workflow_execution: WorkflowExecution, execution_output: ExecutionServiceOutput) -> None:
+ """Initialize workflow execution result object.
+
+ Stores workflow execution data and execution result.
+
+ Args:
+ workflow_execution (WorkflowExecution): WorkflowExecution object which was used to call request.
+ execution_output (ExecutionServiceOutput): gRPC server response.
+ """
+ self.workflow_execution: WorkflowExecution = workflow_execution
+ self.execution_output: ExecutionServiceOutput = execution_output
+
+ @property
+ def blueprint_name(self) -> str:
+ """Name of blueprint used to call workflow.
+
+ This value is taken from server response not request (should be the same).
+
+ Returns:
+ str: Blueprint name
+ """
+ return self.execution_output.actionIdentifiers.blueprintName
+
+ @property
+ def blueprint_version(self) -> str:
+ """Blueprint version.
+
+ This value is taken from server response not request (should be the same).
+
+ Returns:
+ str: Blueprint version
+ """
+ return self.execution_output.actionIdentifiers.blueprintVersion
+
+ @property
+ def workflow_name(self) -> str:
+ """Workflow name.
+
+ This value is taken from server response not request (should be the same).
+
+ Returns:
+ str: Workflow name
+ """
+ return self.execution_output.actionIdentifiers.actionName
+
+ @property
+ def has_error(self) -> bool:
+ """Returns bool if request returns error or not.
+
+ Returns:
+ bool: True if response has status code different than 200
+ """
+ return self.execution_output.status.code != 200
+
+ @property
+ def error_message(self) -> str:
+ """Error message.
+
+ This property is available only if response has error. Otherwise AttributeError will be raised.
+
+ Raises:
+ AttributeError: Response has 200 response code and hasn't error message.
+
+ Returns:
+ str: Error message returned by server
+ """
+ if self.has_error:
+ return self.execution_output.status.errorMessage
+ raise AttributeError("Execution does not finish with error")
+
+ @property
+ def payload(self) -> dict:
+ """Response payload.
+
+ Payload retured by the server is migrated to Python dict.
+
+ Returns:
+ dict: Response's payload.
+ """
+ return json_format.MessageToDict(self.execution_output.payload)
+
+
+class ResourceResolution:
+ """Resource resolution class.
+
+ Helper class to connect to blueprintprocessor's gRPC server, send request to execute workflow and parse responses.
+ Blueprint with workflow must be deployed before workflow request.
+ It's possible to create both secre or unsecure connection (without SSL/TLS).
+ """
+
+ def __init__(
+ self,
+ *,
+ server_address: str = "127.0.0.1",
+ server_port: int = "9111",
+ use_ssl: bool = False,
+ root_certificates: bytes = None,
+ private_key: bytes = None,
+ certificate_chain: bytes = None,
+ # Authentication header configuration
+ use_header_auth: bool = False,
+ header_auth_token: str = None,
+ ) -> None:
+ """Resource resolution object initialization.
+
+ Args:
+ server_address (str, optional): gRPC server address. Defaults to "127.0.0.1".
+ server_port (int, optional): gRPC server address port. Defaults to "9111".
+ use_ssl (bool, optional): Boolean flag to determine if secure channel should be created or not.
+ Defaults to False.
+ root_certificates (bytes, optional): The PEM-encoded root certificates. None if it shouldn't be used.
+ Defaults to None.
+ private_key (bytes, optional): The PEM-encoded private key as a byte string, or None if no private key
+ should be used. Defaults to None.
+ certificate_chain (bytes, optional): The PEM-encoded certificate chain as a byte string to use or or None if
+ no certificate chain should be used. Defaults to None.
+ use_header_auth (bool, optional): Boolean flag to determine if authorization headed shoud be added for
+ every call or not. Defaults to False.
+ header_auth_token (str, optional): Authorization token value. Defaults to None.
+ """
+ # Logger
+ self.logger: Logger = getLogger(__name__)
+ # Client settings
+ self.client_server_address: str = server_address
+ self.client_server_port: str = server_port
+ self.client_use_ssl: bool = use_ssl
+ self.client_root_certificates: bytes = root_certificates
+ self.client_private_key: bytes = private_key
+ self.client_certificate_chain: bytes = certificate_chain
+ self.client_use_header_auth: bool = use_header_auth
+ self.client_header_auth_token: str = header_auth_token
+ self.client: Client = None
+
+ def __enter__(self) -> "ResourceResolution":
+ """Enter ResourceResolution instance context.
+
+ Client connection is created.
+ """
+ self.client = Client(
+ server_address=f"{self.client_server_address}:{self.client_server_port}",
+ use_ssl=self.client_use_ssl,
+ root_certificates=self.client_root_certificates,
+ private_key=self.client_private_key,
+ certificate_chain=self.client_certificate_chain,
+ use_header_auth=self.client_use_header_auth,
+ header_auth_token=self.client_header_auth_token,
+ )
+ return self
+
+ def __exit__(
+ self,
+ unused_exc_type: Optional[Type[BaseException]],
+ unused_exc_value: Optional[BaseException],
+ unused_traceback: Optional[TracebackType],
+ ) -> None:
+ """Exit ResourceResolution instance context.
+
+ Client connection is closed.
+ """
+ self.client.close()
+
+ def execute_workflows(self, *workflows: WorkflowExecution) -> Generator[WorkflowExecutionResult, None, None]:
+ """Execute provided workflows.
+
+ Workflows are going to be execured using one gRPC API call. Depends of implementation that may has
+ some consequences. In some cases if any request fails all requests after that won't be called.
+
+ Responses and zipped with workflows and WorkflowExecutionResult object is initialized and yielded.
+
+ Raises:
+ AttributeError: Raises if client object is not created. It occurs only if you not uses context manager.
+ Then user have to create client instance for ResourceResolution object by himself calling:
+ ```
+ resource_resoulution.client = Client(
+ server_address=f"{resource_resoulution.client_server_address}:{resource_resoulution.client_server_port}",
+ use_ssl=resource_resoulution.client_use_ssl,
+ root_certificates=resource_resoulution.client_root_certificates,
+ private_key=resource_resoulution.client_private_key,
+ certificate_chain=resource_resoulution.client_certificate_chain,
+ use_header_auth=resource_resoulution.client_use_header_auth,
+ header_auth_token=resource_resoulution.client_header_auth_token,
+ )
+ ```
+ Remeber also to close client connection.
+
+ Returns:
+ Generator[WorkflowExecutionResult, None, None]: WorkflowExecutionResult object
+ with both WorkflowExection object and server response for it's request.
+ """
+ self.logger.debug("Execute workflows")
+ if not self.client:
+ raise AttributeError("gRPC client not connected")
+
+ for response, workflow in zip(self.client.process((workflow.message for workflow in workflows)), workflows):
+ yield WorkflowExecutionResult(workflow, response)
diff --git a/ms/py-executor/resource_resolution/tests/authorization_interceptor_test.py b/ms/py-executor/resource_resolution/tests/authorization_interceptor_test.py
new file mode 100644
index 000000000..4b03f0b36
--- /dev/null
+++ b/ms/py-executor/resource_resolution/tests/authorization_interceptor_test.py
@@ -0,0 +1,50 @@
+"""Copyright 2020 Deutsche Telekom.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from unittest.mock import MagicMock, _Call
+
+import pytest
+
+from resource_resolution.authorization import AuthTokenInterceptor, NewClientCallDetails
+
+
+def test_resource_resolution_auth_token_interceptor():
+ """Test AuthTokenInterceptor class.
+
+ - Checks if it's correctly set default value.
+ - Checks if it's correctly set passed values.
+ - Checks if it's correctly checked if all header characters are lowercase.
+ - Checks if continuation function is called with headers setted
+ """
+ interceptor: AuthTokenInterceptor = AuthTokenInterceptor("test_token", header="header")
+ assert interceptor.token == "test_token"
+ assert interceptor.header == "header"
+
+ interceptor: AuthTokenInterceptor = AuthTokenInterceptor("test_token")
+ assert interceptor.token == "test_token"
+ assert interceptor.header == "authorization"
+
+ with pytest.raises(ValueError):
+ AuthTokenInterceptor("test_token", header="Auth")
+
+ continuation_mock: MagicMock = MagicMock()
+ client_call_details: MagicMock = MagicMock()
+ request_iterator: MagicMock = MagicMock()
+
+ interceptor.intercept_stream_stream(continuation_mock, client_call_details, request_iterator)
+ continuation_mock.assert_called_once()
+ client_call_details_argument: _Call = continuation_mock.call_args_list[0][0][0] # Get NewClientCallDetails instance
+ assert isinstance(client_call_details_argument, NewClientCallDetails)
+ assert client_call_details_argument.metadata[0] == (interceptor.header, interceptor.token)
diff --git a/ms/py-executor/resource_resolution/tests/resource_resolution_test.py b/ms/py-executor/resource_resolution/tests/resource_resolution_test.py
new file mode 100644
index 000000000..8a41357e6
--- /dev/null
+++ b/ms/py-executor/resource_resolution/tests/resource_resolution_test.py
@@ -0,0 +1,105 @@
+"""Copyright 2020 Deutsche Telekom.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from google.protobuf import json_format
+from pytest import raises
+
+from resource_resolution.resource_resolution import (
+ ExecutionServiceInput,
+ ExecutionServiceOutput,
+ WorkflowExecution,
+ WorkflowExecutionResult,
+ WorkflowMode,
+)
+
+
+def test_workflow_execution_class():
+ """Workflow execution class tests.
+
+ - Test initialization and default values
+ - Test request message formatting
+ """
+ # Without inputs
+ workflow_execution: WorkflowExecution = WorkflowExecution("test blueprint", "test version", "test workflow")
+ assert workflow_execution.blueprint_name == "test blueprint"
+ assert workflow_execution.blueprint_version == "test version"
+ assert workflow_execution.workflow_name == "test workflow"
+ assert workflow_execution.workflow_inputs == {}
+ assert workflow_execution.workflow_mode == WorkflowMode.SYNC
+
+ msg: ExecutionServiceInput = workflow_execution.message
+ msg_dict: dict = json_format.MessageToDict(msg)
+ assert msg_dict["actionIdentifiers"]["blueprintName"] == "test blueprint"
+ assert msg_dict["actionIdentifiers"]["blueprintVersion"] == "test version"
+ assert msg_dict["actionIdentifiers"]["actionName"] == "test workflow"
+ assert msg_dict["actionIdentifiers"]["mode"] == "sync"
+ assert list(msg_dict["payload"].keys())[0] == "test workflow-request"
+ assert msg_dict["payload"]["test workflow-request"] == {}
+
+ # With inputs
+ workflow_execution: WorkflowExecution = WorkflowExecution(
+ "test blueprint2",
+ "test version2",
+ "test workflow2",
+ workflow_inputs={"test": "test"},
+ workflow_mode=WorkflowMode.ASYNC,
+ )
+ assert workflow_execution.blueprint_name == "test blueprint2"
+ assert workflow_execution.blueprint_version == "test version2"
+ assert workflow_execution.workflow_name == "test workflow2"
+ assert workflow_execution.workflow_inputs == {"test": "test"}
+ assert workflow_execution.workflow_mode == WorkflowMode.ASYNC
+
+ msg: ExecutionServiceInput = workflow_execution.message
+ msg_dict: dict = json_format.MessageToDict(msg)
+ assert msg_dict["actionIdentifiers"]["blueprintName"] == "test blueprint2"
+ assert msg_dict["actionIdentifiers"]["blueprintVersion"] == "test version2"
+ assert msg_dict["actionIdentifiers"]["actionName"] == "test workflow2"
+ assert msg_dict["actionIdentifiers"]["mode"] == "async"
+ assert list(msg_dict["payload"].keys())[0] == "test workflow2-request"
+ assert msg_dict["payload"]["test workflow2-request"] == {"test": "test"}
+
+
+def test_workflow_execution_result_class():
+ """Workflow execution result class tests.
+
+ - Test initizalization and default values
+ - Test `has_error` property
+ - Test `error_message` property
+ - Test payload formatting
+ """
+ workflow_execution: WorkflowExecution = WorkflowExecution("test blueprint", "test version", "test workflow")
+ execution_output: ExecutionServiceOutput = ExecutionServiceOutput()
+ execution_output.actionIdentifiers.blueprintName = "test blueprint"
+ execution_output.actionIdentifiers.blueprintVersion = "test version"
+ execution_output.actionIdentifiers.actionName = "test workflow"
+ execution_output.status.code = 200
+
+ execution_result: WorkflowExecutionResult = WorkflowExecutionResult(workflow_execution, execution_output)
+ assert not execution_result.has_error
+ with raises(AttributeError):
+ execution_result.error_message
+ assert execution_result.payload == {}
+ assert execution_result.blueprint_name == "test blueprint"
+ assert execution_result.blueprint_version == "test version"
+ assert execution_result.workflow_name == "test workflow"
+
+ execution_output.payload.update({"test_key": "test_value"})
+ execution_result: WorkflowExecutionResult = WorkflowExecutionResult(workflow_execution, execution_output)
+ assert execution_result.payload == {"test_key": "test_value"}
+
+ execution_output.status.code = 500
+ assert execution_result.has_error
+ assert execution_result.error_message == ""
diff --git a/ms/sdclistener/application/pom.xml b/ms/sdclistener/application/pom.xml
index 88d8d1b2f..72f552cdd 100644
--- a/ms/sdclistener/application/pom.xml
+++ b/ms/sdclistener/application/pom.xml
@@ -63,7 +63,6 @@
<dependency>
<groupId>org.onap.sdc.sdc-distribution-client</groupId>
<artifactId>sdc-distribution-client</artifactId>
- <version>1.3.0</version>
</dependency>
<dependency>
@@ -112,6 +111,11 @@
</dependency>
<dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<scope>compile</scope>
diff --git a/ms/sdclistener/application/src/main/resources/application.yaml b/ms/sdclistener/application/src/main/resources/application.yaml
index 424f0a5c0..d07d8ae61 100644
--- a/ms/sdclistener/application/src/main/resources/application.yaml
+++ b/ms/sdclistener/application/src/main/resources/application.yaml
@@ -2,7 +2,7 @@ listenerservice:
config:
asdcAddress: ${asdcAddress:localhost:8443}
messageBusAddress: ${messageBusAddress:localhost}
- user: ${sdcusername:vid}
+ user: ${sdcusername:cds}
password: ${password:Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U}
pollingInterval: ${pollingInterval:15}
pollingTimeout: ${pollingTimeout:60}
diff --git a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/SdcListenerConfigurationTest.java b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/SdcListenerConfigurationTest.java
index 26757a657..8275bc084 100644
--- a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/SdcListenerConfigurationTest.java
+++ b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/SdcListenerConfigurationTest.java
@@ -37,7 +37,7 @@ public class SdcListenerConfigurationTest {
public void testCdsSdcListenerConfiguration() {
assertEquals(listenerConfiguration.getAsdcAddress(), "localhost:8443");
assertEquals(listenerConfiguration.getMsgBusAddress().stream().findFirst().get(), "localhost");
- assertEquals(listenerConfiguration.getUser(), "vid");
+ assertEquals(listenerConfiguration.getUser(), "cds");
assertEquals(listenerConfiguration.getPassword(), "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U");
assertEquals(listenerConfiguration.getPollingInterval(), 15);
assertEquals(listenerConfiguration.getPollingTimeout(), 60);
diff --git a/ms/sdclistener/parent/pom.xml b/ms/sdclistener/parent/pom.xml
index eaa1d60f4..2cbc79dcc 100755
--- a/ms/sdclistener/parent/pom.xml
+++ b/ms/sdclistener/parent/pom.xml
@@ -40,7 +40,7 @@
<mockk.version>1.9</mockk.version>
<dmaap.client.version>1.1.5</dmaap.client.version>
<mockkserver.version>5.5.1</mockkserver.version>
- <sdc-distribution-client.version>1.3.0</sdc-distribution-client.version>
+ <sdc-distribution-client.version>1.4.0</sdc-distribution-client.version>
<jmockit.version>1.19</jmockit.version>
<reactorcore.version>3.2.6.RELEASE</reactorcore.version>
</properties>