Blueprints Processor Metrics 59/114359/1
authorJulien Fontaine <julien.fontaine@bell.ca>
Tue, 27 Oct 2020 21:45:39 +0000 (17:45 -0400)
committerJulien Fontaine <julien.fontaine@bell.ca>
Wed, 28 Oct 2020 14:14:09 +0000 (10:14 -0400)
Add counter and timer for Blueprints Processor process to get success/failure and execution time for each blueprint execution using blueprint name, version and action.

Issue-ID: CCSDK-2950
Change-Id: I38e8997de26effe69ec2ee9e2b6ed0da14de4a43
Signed-off-by: Julien Fontaine <julien.fontaine@bell.ca>
Signed-off-by: Jozsef Csongvai <jozsef.csongvai@bell.ca>
ms/blueprintsprocessor/modules/inbounds/health-api-common/pom.xml
ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/SelfServiceMetricConstants.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/utils/Utils.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumerTest.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceControllerTest.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/utils/UtilsTest.kt

index 93c9d18..2bfcbe3 100644 (file)
             <groupId>org.onap.ccsdk.cds.blueprintsprocessor.modules</groupId>
             <artifactId>rest-lib</artifactId>
         </dependency>
+
+        <!-- Micrometer Prometheus -->
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
index f136af3..706dd45 100755 (executable)
                 </exclusion>
             </exclusions>
         </dependency>
+
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
     </dependencies>
 </project>
index 4a7171c..89a9637 100644 (file)
@@ -18,6 +18,8 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
 import io.grpc.stub.StreamObserver
+import io.micrometer.core.instrument.MeterRegistry
+import io.micrometer.core.instrument.Timer
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
@@ -27,6 +29,9 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.Status
 import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.toProto
+import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.SelfServiceMetricConstants.COUNTER_PROCESS
+import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.SelfServiceMetricConstants.TIMER_PROCESS
+import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.cbaMetricTags
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractServiceFunction
 import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
@@ -45,7 +50,8 @@ class ExecutionServiceHandler(
     private val blueprintsProcessorCatalogService: BluePrintCatalogService,
     private val bluePrintWorkflowExecutionService:
         BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput>,
-    private val publishAuditService: PublishAuditService
+    private val publishAuditService: PublishAuditService,
+    private val meterRegistry: MeterRegistry
 ) {
 
     private val log = LoggerFactory.getLogger(ExecutionServiceHandler::class.toString())
@@ -75,6 +81,7 @@ class ExecutionServiceHandler(
                     "Failed to process request, 'actionIdentifiers.mode' not specified. Valid value are: 'sync' or 'async'.",
                     true
                 )
+                meterRegistry.counter(COUNTER_PROCESS, cbaMetricTags(executionServiceOutput)).increment()
                 publishAuditService.publishExecutionOutput(executionServiceInput.correlationUUID, executionServiceOutput)
                 responseObserver.onNext(
                     executionServiceOutput.toProto()
@@ -93,8 +100,10 @@ class ExecutionServiceHandler(
 
         log.info("processing request id $requestId")
 
+        // Audit input
         publishAuditService.publishExecutionInput(executionServiceInput)
 
+        val sample = Timer.start()
         try {
             /** Check Blueprint is needed for this request */
             if (checkServiceFunction(executionServiceInput)) {
@@ -120,7 +129,11 @@ class ExecutionServiceHandler(
             log.error("fail processing request id $requestId", e)
             executionServiceOutput = response(executionServiceInput, e.localizedMessage ?: e.message ?: e.toString(), true)
         }
+        // Update process metrics
+        sample.stop(meterRegistry.timer(TIMER_PROCESS, cbaMetricTags(executionServiceInput)))
+        meterRegistry.counter(COUNTER_PROCESS, cbaMetricTags(executionServiceOutput)).increment()
 
+        // Audit output
         publishAuditService.publishExecutionOutput(executionServiceInput.correlationUUID, executionServiceOutput)
         return executionServiceOutput
     }
diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/SelfServiceMetricConstants.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/SelfServiceMetricConstants.kt
new file mode 100644 (file)
index 0000000..97c7324
--- /dev/null
@@ -0,0 +1,21 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
+
+object SelfServiceMetricConstants {
+
+    private const val METRICS_PREFIX = "cds.cba"
+
+    private const val PROCESS_PREFIX = "$METRICS_PREFIX.process"
+
+    // TAGS
+    const val TAG_BP_NAME = "blueprint_name"
+    const val TAG_BP_VERSION = "blueprint_version"
+    const val TAG_BP_ACTION = "blueprint_action"
+    const val TAG_BP_STATUS = "status"
+    const val TAG_BP_OUTCOME = "outcome"
+
+    // COUNTERS
+    const val COUNTER_PROCESS = "$PROCESS_PREFIX.counter"
+
+    // TIMERS
+    const val TIMER_PROCESS = "$PROCESS_PREFIX.timer"
+}
index 66cdbef..08cae09 100644 (file)
  */
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils
 
+import io.micrometer.core.instrument.Tag
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
+import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.SelfServiceMetricConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
 import org.springframework.http.HttpStatus
 import org.springframework.http.codec.multipart.FilePart
@@ -60,3 +64,23 @@ fun determineHttpStatusCode(statusCode: Int): HttpStatus {
         return HttpStatus.valueOf(INTERNAL_SERVER_ERROR_HTTP_STATUS_CODE)
     }
 }
+
+fun cbaMetricTags(executionServiceInput: ExecutionServiceInput): MutableList<Tag> =
+    executionServiceInput.actionIdentifiers.let {
+        mutableListOf(
+            Tag.of(SelfServiceMetricConstants.TAG_BP_NAME, it.blueprintName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_VERSION, it.blueprintVersion),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_ACTION, it.actionName)
+        )
+    }
+
+fun cbaMetricTags(executionServiceOutput: ExecutionServiceOutput): MutableList<Tag> =
+    executionServiceOutput.let {
+        mutableListOf(
+            Tag.of(SelfServiceMetricConstants.TAG_BP_NAME, it.actionIdentifiers.blueprintName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_VERSION, it.actionIdentifiers.blueprintVersion),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_ACTION, it.actionIdentifiers.actionName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_STATUS, it.status.code.toString()),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_OUTCOME, it.status.message)
+        )
+    }
index 8cfd562..0d79368 100644 (file)
@@ -21,6 +21,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 import com.google.protobuf.util.JsonFormat
 import io.grpc.stub.StreamObserver
 import io.grpc.testing.GrpcServerRule
+import io.micrometer.core.instrument.MeterRegistry
 import org.junit.Assert
 import org.junit.Rule
 import org.junit.Test
@@ -33,6 +34,7 @@ import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceIn
 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.mock.mockito.MockBean
 import org.springframework.test.annotation.DirtiesContext
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
@@ -52,6 +54,9 @@ class BluePrintProcessingGRPCHandlerTest {
 
     private val log = LoggerFactory.getLogger(BluePrintProcessingGRPCHandlerTest::class.java)
 
+    @MockBean
+    lateinit var meterRegistry: MeterRegistry
+
     @get:Rule
     val grpcServerRule = GrpcServerRule().directExecutor()
 
index 4a11aee..7f82ec0 100644 (file)
@@ -16,6 +16,7 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
+import io.micrometer.core.instrument.MeterRegistry
 import io.mockk.coEvery
 import io.mockk.mockk
 import kotlinx.coroutines.delay
@@ -27,6 +28,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertyConfiguratio
 import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BluePrintMessageLibPropertyService
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.mock.mockito.MockBean
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
 import org.springframework.test.context.junit4.SpringRunner
@@ -43,6 +45,9 @@ import kotlin.test.assertNotNull
 @TestPropertySource(locations = ["classpath:application-test.properties"])
 class BluePrintProcessingKafkaConsumerTest {
 
+    @MockBean
+    lateinit var meterRegistry: MeterRegistry
+
     @Autowired
     lateinit var bluePrintMessageLibPropertyService: BluePrintMessageLibPropertyService
 
index ce78aab..d7d7aaa 100644 (file)
@@ -17,6 +17,7 @@
  */
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
+import io.micrometer.core.instrument.simple.SimpleMeterRegistry
 import kotlinx.coroutines.runBlocking
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,7 +46,8 @@ import kotlin.test.assertTrue
 @ContextConfiguration(
     classes = [
         ExecutionServiceHandler::class, BluePrintCoreConfiguration::class,
-        BluePrintCatalogService::class, SelfServiceApiTestConfiguration::class, ErrorCatalogTestConfiguration::class
+        BluePrintCatalogService::class, SelfServiceApiTestConfiguration::class,
+        ErrorCatalogTestConfiguration::class, SimpleMeterRegistry::class
     ]
 )
 @TestPropertySource(locations = ["classpath:application-test.properties"])
index 86ed0ea..0a89c57 100644 (file)
@@ -16,6 +16,8 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
+import io.micrometer.core.instrument.MeterRegistry
+import io.mockk.coVerify
 import io.mockk.Runs
 import io.mockk.coEvery
 import io.mockk.coVerify
@@ -32,6 +34,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractService
 import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.mock.mockito.MockBean
 import org.springframework.context.ApplicationContext
 import org.springframework.stereotype.Service
 import org.springframework.test.context.ContextConfiguration
@@ -51,6 +54,9 @@ import kotlin.test.assertTrue
 @TestPropertySource(locations = ["classpath:application-test.properties"])
 class ExecutionServiceHandlerTest {
 
+    @MockBean
+    lateinit var meterRegistry: MeterRegistry
+
     @Autowired
     lateinit var applicationContext: ApplicationContext
 
@@ -74,7 +80,7 @@ class ExecutionServiceHandlerTest {
             }
         }
         runBlocking {
-            val executionServiceHandler = ExecutionServiceHandler(mockk(), mockk(), mockk(), mockk())
+            val executionServiceHandler = ExecutionServiceHandler(mockk(), mockk(), mockk(), mockk(), mockk(relaxed = true))
             val isServiceFunction = executionServiceHandler.checkServiceFunction(executionServiceInput)
             assertTrue(isServiceFunction, "failed to checkServiceFunction")
             val executionServiceOutput = executionServiceHandler.executeServiceFunction(executionServiceInput)
@@ -102,7 +108,8 @@ class ExecutionServiceHandlerTest {
             mockk(),
             mockk(),
             mockk(),
-            publishAuditService
+            publishAuditService,
+            mockk(relaxed = true)
         )
 
         coEvery { publishAuditService.publishExecutionInput(ExecutionServiceInput()) } just Runs
index db27911..2238968 100644 (file)
@@ -1,8 +1,14 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils
 
+import io.micrometer.core.instrument.Tag
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.Status
+import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.SelfServiceMetricConstants
 import org.springframework.http.HttpStatus
 import org.springframework.test.context.junit4.SpringRunner
 
@@ -23,4 +29,52 @@ class UtilsTest {
         val nonExistentHttpStatusCode = determineHttpStatusCode(999999)
         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, nonExistentHttpStatusCode)
     }
+
+    @Test
+    fun testCbaMetricExecutionInputTags() {
+        val executionServiceInput = ExecutionServiceInput().apply {
+            actionIdentifiers = ActionIdentifiers().apply {
+                blueprintName = "bpName"
+                blueprintVersion = "1.0.0"
+                actionName = "bpAction"
+            }
+        }
+
+        val expectedTags = mutableListOf(
+            Tag.of(SelfServiceMetricConstants.TAG_BP_NAME, executionServiceInput.actionIdentifiers.blueprintName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_VERSION, executionServiceInput.actionIdentifiers.blueprintVersion),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_ACTION, executionServiceInput.actionIdentifiers.actionName)
+        )
+
+        val metricTag = cbaMetricTags(executionServiceInput)
+
+        assertEquals(expectedTags, metricTag)
+    }
+
+    @Test
+    fun testCbaMetricExecutionOutputTags() {
+        val executionServiceOutput = ExecutionServiceOutput().apply {
+            actionIdentifiers = ActionIdentifiers().apply {
+                blueprintName = "bpName"
+                blueprintVersion = "1.0.0"
+                actionName = "bpAction"
+            }
+            status = Status().apply {
+                code = 200
+                message = "success"
+            }
+        }
+
+        val expectedTags = mutableListOf(
+            Tag.of(SelfServiceMetricConstants.TAG_BP_NAME, executionServiceOutput.actionIdentifiers.blueprintName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_VERSION, executionServiceOutput.actionIdentifiers.blueprintVersion),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_ACTION, executionServiceOutput.actionIdentifiers.actionName),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_STATUS, executionServiceOutput.status.code.toString()),
+            Tag.of(SelfServiceMetricConstants.TAG_BP_OUTCOME, executionServiceOutput.status.message)
+        )
+
+        val metricTag = cbaMetricTags(executionServiceOutput)
+
+        assertEquals(expectedTags, metricTag)
+    }
 }