Add grpc TLS property lib services. 38/97438/1
authorBrinda Santh <bs2796@att.com>
Tue, 22 Oct 2019 20:14:00 +0000 (16:14 -0400)
committerBrinda Santh <bs2796@att.com>
Tue, 22 Oct 2019 20:14:00 +0000 (16:14 -0400)
Issue-ID: CCSDK-1853
Signed-off-by: Brinda Santh <bs2796@att.com>
Change-Id: I92c8b39a6db0bf7c1fe7e9928e4eddaef8a30f07

14 files changed:
ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcService.kt [moved from ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt with 79% similarity]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyServiceTest.kt
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-private-key.pem [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-public-key-cert.pem [new file with mode: 0644]
ms/blueprintsprocessor/parent/pom.xml

index 5945e29..15cabb2 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
   ~  Copyright © 2019 IBM.
+  ~  Modifications 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.
@@ -42,5 +43,9 @@
             <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
             <artifactId>processor-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-testing</artifactId>
+        </dependency>
     </dependencies>
 </project>
index 1bef3a0..0ec049a 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 IBM.
+ *  Modifications 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.
 
 package org.onap.ccsdk.cds.blueprintsprocessor.grpc
 
+import com.fasterxml.jackson.databind.JsonNode
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.springframework.context.annotation.ComponentScan
 import org.springframework.context.annotation.Configuration
 
@@ -23,10 +28,25 @@ import org.springframework.context.annotation.Configuration
 @ComponentScan
 open class BluePrintGrpcLibConfiguration
 
+/**
+ * Exposed Dependency Service by this GRPC Lib Module
+ */
+fun BluePrintDependencyService.grpcLibPropertyService(): BluePrintGrpcLibPropertyService =
+        instance(GRPCLibConstants.SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY)
+
+fun BluePrintDependencyService.grpcClientService(selector: String): BluePrintGrpcClientService {
+    return grpcLibPropertyService().blueprintGrpcClientService(selector)
+}
+
+fun BluePrintDependencyService.grpcClientService(jsonNode: JsonNode): BluePrintGrpcClientService {
+    return grpcLibPropertyService().blueprintGrpcClientService(jsonNode)
+}
+
 class GRPCLibConstants {
     companion object {
         const val SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY = "blueprint-grpc-lib-property-service"
         const val TYPE_TOKEN_AUTH = "token-auth"
         const val TYPE_BASIC_AUTH = "basic-auth"
+        const val TYPE_TLS_AUTH = "tls-auth"
     }
 }
\ No newline at end of file
index 76e60bd..47d16fb 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 IBM.
+ *  Modifications 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.
 
 package org.onap.ccsdk.cds.blueprintsprocessor.grpc
 
+/** GRPC Server Properties */
+open class GrpcServerProperties {
+    lateinit var type: String
+    var port: Int = -1
+}
+
+open class TokenAuthGrpcServerProperties : GrpcServerProperties() {
+    lateinit var token: String
+}
+
+open class TLSAuthGrpcServerProperties : GrpcServerProperties() {
+    lateinit var certChain: String
+    lateinit var privateKey: String
+    /** Below Used only for Mutual TLS */
+    var trustCertCollection: String? = null
+}
+
+/** GRPC Client Properties */
 open class GrpcClientProperties {
     lateinit var type: String
     lateinit var host: String
@@ -26,6 +45,13 @@ open class TokenAuthGrpcClientProperties : GrpcClientProperties() {
     lateinit var token: String
 }
 
+open class TLSAuthGrpcClientProperties : GrpcClientProperties() {
+    var trustCertCollection: String? = null
+    /** Below Used only for Mutual TLS */
+    var clientCertChain: String? = null
+    var clientPrivateKey: String? = null
+}
+
 open class BasicAuthGrpcClientProperties : GrpcClientProperties() {
     lateinit var username: String
     lateinit var password: String
index a1d2188..f4933a3 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 IBM.
+ *  Modifications 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.
@@ -18,17 +19,56 @@ package org.onap.ccsdk.cds.blueprintsprocessor.grpc.service
 
 import com.fasterxml.jackson.databind.JsonNode
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GrpcClientProperties
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.*
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.returnNullIfMissing
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.stereotype.Service
 
 @Service(GRPCLibConstants.SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY)
 open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: BluePrintProperties) {
 
+    /** GRPC Server Lib Property Service */
+    fun grpcServerProperties(jsonNode: JsonNode): GrpcServerProperties {
+        return when (val type = jsonNode.get("type").textValue()) {
+            GRPCLibConstants.TYPE_TOKEN_AUTH -> {
+                JacksonUtils.readValue(jsonNode, TokenAuthGrpcServerProperties::class.java)!!
+            }
+            GRPCLibConstants.TYPE_TLS_AUTH -> {
+                JacksonUtils.readValue(jsonNode, TLSAuthGrpcServerProperties::class.java)!!
+            }
+            else -> {
+                throw BluePrintProcessorException("Grpc type($type) not supported")
+            }
+        }
+    }
+
+    fun grpcServerProperties(prefix: String): GrpcServerProperties {
+        val type = bluePrintProperties.propertyBeanType(
+                "$prefix.type", String::class.java)
+        return when (type) {
+            GRPCLibConstants.TYPE_TOKEN_AUTH -> {
+                tokenAuthGrpcServerProperties(prefix)
+            }
+            GRPCLibConstants.TYPE_TLS_AUTH -> {
+                tlsAuthGrpcServerProperties(prefix)
+            }
+            else -> {
+                throw BluePrintProcessorException("Grpc type($type) not supported")
+            }
+        }
+    }
+
+    private fun tokenAuthGrpcServerProperties(prefix: String): TokenAuthGrpcServerProperties {
+        return bluePrintProperties.propertyBeanType(prefix, TokenAuthGrpcServerProperties::class.java)
+    }
+
+    private fun tlsAuthGrpcServerProperties(prefix: String): TLSAuthGrpcServerProperties {
+        return bluePrintProperties.propertyBeanType(prefix, TLSAuthGrpcServerProperties::class.java)
+    }
+
+    /** GRPC Client Lib Property Service */
+
     fun blueprintGrpcClientService(jsonNode: JsonNode): BluePrintGrpcClientService {
         val restClientProperties = grpcClientProperties(jsonNode)
         return blueprintGrpcClientService(restClientProperties)
@@ -42,11 +82,15 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
 
 
     fun grpcClientProperties(jsonNode: JsonNode): GrpcClientProperties {
-        val type = jsonNode.get("type").textValue()
+        val type = jsonNode.get("type").returnNullIfMissing()?.textValue()
+                ?: BluePrintProcessorException("missing type property")
         return when (type) {
             GRPCLibConstants.TYPE_TOKEN_AUTH -> {
                 JacksonUtils.readValue(jsonNode, TokenAuthGrpcClientProperties::class.java)!!
             }
+            GRPCLibConstants.TYPE_TLS_AUTH -> {
+                JacksonUtils.readValue(jsonNode, TLSAuthGrpcClientProperties::class.java)!!
+            }
             GRPCLibConstants.TYPE_BASIC_AUTH -> {
                 JacksonUtils.readValue(jsonNode, BasicAuthGrpcClientProperties::class.java)!!
             }
@@ -63,6 +107,9 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
             GRPCLibConstants.TYPE_TOKEN_AUTH -> {
                 tokenAuthGrpcClientProperties(prefix)
             }
+            GRPCLibConstants.TYPE_TLS_AUTH -> {
+                tlsAuthGrpcClientProperties(prefix)
+            }
             GRPCLibConstants.TYPE_BASIC_AUTH -> {
                 basicAuthGrpcClientProperties(prefix)
             }
@@ -75,12 +122,15 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
 
     fun blueprintGrpcClientService(grpcClientProperties: GrpcClientProperties):
             BluePrintGrpcClientService {
-        when (grpcClientProperties) {
+        return when (grpcClientProperties) {
             is TokenAuthGrpcClientProperties -> {
-                return TokenAuthGrpcClientService(grpcClientProperties)
+                TokenAuthGrpcClientService(grpcClientProperties)
+            }
+            is TLSAuthGrpcClientProperties -> {
+                TLSAuthGrpcClientService(grpcClientProperties)
             }
             is BasicAuthGrpcClientProperties -> {
-                return BasicAuthGrpcClientService(grpcClientProperties)
+                BasicAuthGrpcClientService(grpcClientProperties)
             }
             else -> {
                 throw BluePrintProcessorException("couldn't get grpc service for type(${grpcClientProperties.type})")
@@ -92,6 +142,10 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
         return bluePrintProperties.propertyBeanType(prefix, TokenAuthGrpcClientProperties::class.java)
     }
 
+    private fun tlsAuthGrpcClientProperties(prefix: String): TLSAuthGrpcClientProperties {
+        return bluePrintProperties.propertyBeanType(prefix, TLSAuthGrpcClientProperties::class.java)
+    }
+
     private fun basicAuthGrpcClientProperties(prefix: String): BasicAuthGrpcClientProperties {
         return bluePrintProperties.propertyBeanType(prefix, BasicAuthGrpcClientProperties::class.java)
     }
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 IBM.
+ *  Modifications 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.
 package org.onap.ccsdk.cds.blueprintsprocessor.grpc.service
 
 import io.grpc.ManagedChannel
+import io.grpc.netty.NettyServerBuilder
+
+interface BluePrintGrpcServerService {
+    fun serverBuilder(): NettyServerBuilder
+}
 
 interface BluePrintGrpcClientService {
     suspend fun channel(): ManagedChannel
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt
new file mode 100644 (file)
index 0000000..a70cbbc
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.ManagedChannel
+import io.grpc.internal.DnsNameResolverProvider
+import io.grpc.internal.PickFirstLoadBalancerProvider
+import io.grpc.netty.GrpcSslContexts
+import io.grpc.netty.NettyChannelBuilder
+import io.netty.handler.ssl.SslContext
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcClientLoggingInterceptor
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
+
+class TLSAuthGrpcClientService(private val tlsAuthGrpcClientProperties: TLSAuthGrpcClientProperties)
+    : BluePrintGrpcClientService {
+
+    override suspend fun channel(): ManagedChannel {
+        return NettyChannelBuilder
+                .forAddress(tlsAuthGrpcClientProperties.host, tlsAuthGrpcClientProperties.port)
+                .nameResolverFactory(DnsNameResolverProvider())
+                .loadBalancerFactory(PickFirstLoadBalancerProvider())
+                .intercept(GrpcClientLoggingInterceptor())
+                .sslContext(sslContext())
+                .build()
+    }
+
+    fun sslContext(): SslContext {
+        val builder = GrpcSslContexts.forClient()
+        if (tlsAuthGrpcClientProperties.trustCertCollection != null) {
+            builder.trustManager(normalizedFile(tlsAuthGrpcClientProperties.trustCertCollection!!))
+        }
+        if (tlsAuthGrpcClientProperties.clientCertChain != null
+                && tlsAuthGrpcClientProperties.clientPrivateKey != null) {
+            builder.keyManager(normalizedFile(tlsAuthGrpcClientProperties.clientCertChain!!),
+                    normalizedFile(tlsAuthGrpcClientProperties.clientPrivateKey!!))
+        }
+        return builder.build()
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt
new file mode 100644 (file)
index 0000000..fc73d43
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.netty.GrpcSslContexts
+import io.grpc.netty.NettyServerBuilder
+import io.netty.handler.ssl.ClientAuth
+import io.netty.handler.ssl.SslContext
+import io.netty.handler.ssl.SslContextBuilder
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
+
+
+class TLSAuthGrpcServerService(private val tlsAuthGrpcServerProperties: TLSAuthGrpcServerProperties)
+    : BluePrintGrpcServerService {
+
+    override fun serverBuilder(): NettyServerBuilder {
+        return NettyServerBuilder
+                .forPort(tlsAuthGrpcServerProperties.port)
+                .sslContext(sslContext())
+    }
+
+    fun sslContext(): SslContext {
+        val sslClientContextBuilder = SslContextBuilder
+                .forServer(normalizedFile(tlsAuthGrpcServerProperties.certChain),
+                        normalizedFile(tlsAuthGrpcServerProperties.privateKey))
+
+        tlsAuthGrpcServerProperties.trustCertCollection?.let { trustCertFile ->
+            sslClientContextBuilder.trustManager(normalizedFile(trustCertFile))
+            sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE)
+        }
+        return GrpcSslContexts.configure(sslClientContextBuilder).build()
+    }
+
+}
\ No newline at end of file
index 8df218f..b7ddc15 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 IBM.
+ *  Modifications 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.
@@ -22,9 +23,8 @@ import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BluePrintGrpcLibConfiguration
-import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.*
+import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
@@ -42,11 +42,25 @@ import kotlin.test.assertTrue
     "blueprintsprocessor.grpcclient.sample.port=50505",
     "blueprintsprocessor.grpcclient.sample.username=sampleuser",
     "blueprintsprocessor.grpcclient.sample.password=sampleuser",
+
     "blueprintsprocessor.grpcclient.token.type=token-auth",
     "blueprintsprocessor.grpcclient.token.host=127.0.0.1",
     "blueprintsprocessor.grpcclient.token.port=50505",
     "blueprintsprocessor.grpcclient.token.username=sampleuser",
-    "blueprintsprocessor.grpcclient.token.password=sampleuser"
+    "blueprintsprocessor.grpcclient.token.password=sampleuser",
+
+    "blueprintsprocessor.grpcserver.tls-sample.type=tls-auth",
+    "blueprintsprocessor.grpcserver.tls-sample.port=50505",
+    "blueprintsprocessor.grpcserver.tls-sample.certChain=server1.pem",
+    "blueprintsprocessor.grpcserver.tls-sample.privateKey=server1.key",
+    "blueprintsprocessor.grpcserver.tls-sample.trustCertCollection=ca.pem",
+
+    "blueprintsprocessor.grpcclient.tls-sample.type=tls-auth",
+    "blueprintsprocessor.grpcclient.tls-sample.host=127.0.0.1",
+    "blueprintsprocessor.grpcclient.tls-sample.port=50505",
+    "blueprintsprocessor.grpcclient.tls-sample.trustCertCollection=ca.pem",
+    "blueprintsprocessor.grpcclient.tls-sample.clientCertChain=client.pem",
+    "blueprintsprocessor.grpcclient.tls-sample.clientPrivateKey=client.key"
 ])
 class BluePrintGrpcLibPropertyServiceTest {
 
@@ -129,4 +143,52 @@ class BluePrintGrpcLibPropertyServiceTest {
                 .blueprintGrpcClientService(actualObj)
         assertTrue(svc is BasicAuthGrpcClientService)
     }
+
+    @Test
+    fun testGrpcClientTLSProperties() {
+        val properties = bluePrintGrpcLibPropertyService
+                .grpcClientProperties("blueprintsprocessor.grpcclient.tls-sample") as TLSAuthGrpcClientProperties
+        assertNotNull(properties, "failed to create property bean")
+        assertNotNull(properties.host, "failed to get host property in property bean")
+        assertNotNull(properties.port, "failed to get host property in property bean")
+        assertNotNull(properties.trustCertCollection, "failed to get trustCertCollection property in property bean")
+        assertNotNull(properties.clientCertChain, "failed to get clientCertChain property in property bean")
+        assertNotNull(properties.clientPrivateKey, "failed to get clientPrivateKey property in property bean")
+
+        val configDsl = """{
+            "type" : "tls-auth",
+            "host" : "localhost",
+            "port" : "50505",
+            "trustCertCollection" : "server1.pem",
+            "clientCertChain" : "server1.key",
+            "clientPrivateKey" : "ca.pem"
+            }           
+        """.trimIndent()
+        val jsonProperties = bluePrintGrpcLibPropertyService
+                .grpcClientProperties(configDsl.jsonAsJsonType()) as TLSAuthGrpcClientProperties
+        assertNotNull(jsonProperties, "failed to create property bean from json")
+    }
+
+    @Test
+    fun testGrpcServerTLSProperties() {
+        val properties = bluePrintGrpcLibPropertyService
+                .grpcServerProperties("blueprintsprocessor.grpcserver.tls-sample") as TLSAuthGrpcServerProperties
+        assertNotNull(properties, "failed to create property bean")
+        assertNotNull(properties.port, "failed to get host property in property bean")
+        assertNotNull(properties.trustCertCollection, "failed to get trustCertCollection property in property bean")
+        assertNotNull(properties.certChain, "failed to get certChain property in property bean")
+        assertNotNull(properties.privateKey, "failed to get privateKey property in property bean")
+
+        val configDsl = """{
+            "type" : "tls-auth",
+            "port" : "50505",
+            "certChain" : "server1.pem",
+            "privateKey" : "server1.key",
+            "trustCertCollection" : "ca.pem"
+            }           
+        """.trimIndent()
+        val jsonProperties = bluePrintGrpcLibPropertyService
+                .grpcServerProperties(configDsl.jsonAsJsonType()) as TLSAuthGrpcServerProperties
+        assertNotNull(jsonProperties, "failed to create property bean from json")
+    }
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt
new file mode 100644 (file)
index 0000000..a084250
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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.grpc.service
+
+import com.github.marcoferrer.krotoplus.coroutines.client.clientCallBidiStreaming
+import com.google.protobuf.util.JsonFormat
+import kotlinx.coroutines.channels.consumeEach
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_SYNC
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties
+import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers
+import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader
+import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc
+import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput
+import java.util.*
+import kotlin.test.Test
+import kotlin.test.assertNotNull
+
+class BluePrintGrpcServerTest {
+
+    private val tlsAuthGrpcServerProperties = TLSAuthGrpcServerProperties().apply {
+        port = 50052
+        type = GRPCLibConstants.TYPE_TLS_AUTH
+        certChain = "src/test/resources/tls-manual/my-public-key-cert.pem"
+        privateKey = "src/test/resources/tls-manual/my-private-key.pem"
+    }
+
+    private val tlsAuthGrpcClientProperties = TLSAuthGrpcClientProperties().apply {
+        host = "localhost"
+        port = 50052
+        type = GRPCLibConstants.TYPE_TLS_AUTH
+        trustCertCollection = "src/test/resources/tls-manual/my-public-key-cert.pem"
+    }
+
+    @Test
+    fun testGrpcTLSContext() {
+        val tlsAuthGrpcServerService = TLSAuthGrpcServerService(tlsAuthGrpcServerProperties)
+        val sslContext = tlsAuthGrpcServerService.sslContext()
+        assertNotNull(sslContext, "failed to create grpc server ssl context")
+
+        val tlsAuthGrpcClientService = TLSAuthGrpcClientService(tlsAuthGrpcClientProperties)
+        val clientSslContext = tlsAuthGrpcClientService.sslContext()
+        assertNotNull(clientSslContext, "failed to create grpc client ssl context")
+    }
+
+    /** TLS Client Integration testing, GRPC TLS Junit testing is not supported. */
+    //@Test
+    fun testGrpcTLSServerIntegration() {
+        runBlocking {
+            val tlsAuthGrpcClientService = TLSAuthGrpcClientService(tlsAuthGrpcClientProperties)
+            val grpcChannel = tlsAuthGrpcClientService.channel()
+            /** Get Send and Receive Channel for bidirectional process method*/
+            val (reqChannel, resChannel) = clientCallBidiStreaming(BluePrintProcessingServiceGrpc.getProcessMethod(),
+                    grpcChannel)
+            launch {
+                resChannel.consumeEach {
+                    log.info("Received Response")
+                }
+            }
+            val request = getRequest("12345")
+            reqChannel.send(request)
+        }
+    }
+
+    private fun getRequest(requestId: String): ExecutionServiceInput {
+        val commonHeader = CommonHeader.newBuilder()
+                .setTimestamp("2012-04-23T18:25:43.511Z")
+                .setOriginatorId("System")
+                .setRequestId(requestId)
+                .setSubRequestId("$requestId-" + UUID.randomUUID().toString()).build()
+        val actionIdentifier = ActionIdentifiers.newBuilder()
+                .setActionName("SampleScript")
+                .setBlueprintName("sample-cba")
+                .setBlueprintVersion("1.0.0")
+                .setMode(ACTION_MODE_SYNC)
+                .build()
+        val jsonContent = """{ "key1" : "value1" }"""
+        val payloadBuilder = ExecutionServiceInput.newBuilder().payloadBuilder
+        JsonFormat.parser().merge(jsonContent, payloadBuilder)
+
+        return ExecutionServiceInput.newBuilder()
+                .setCommonHeader(commonHeader)
+                .setActionIdentifiers(actionIdentifier)
+                .setPayload(payloadBuilder.build())
+                .build()
+    }
+
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt
new file mode 100644 (file)
index 0000000..c6991af
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.stub.StreamObserver
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcServerLoggingInterceptor
+import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType
+import org.onap.ccsdk.cds.controllerblueprints.common.api.Status
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc
+import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput
+import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput
+
+
+val log = logger(MockTLSBluePrintProcessingServer::class)
+
+/** For Integration testing stat this server, Set the working path to run this method */
+fun main() {
+    try {
+        val tlsAuthGrpcServerProperties = TLSAuthGrpcServerProperties().apply {
+            port = 50052
+            type = GRPCLibConstants.TYPE_TLS_AUTH
+            certChain = "src/test/resources/tls-manual/my-public-key-cert.pem"
+            privateKey = "src/test/resources/tls-manual/my-private-key.pem"
+        }
+        val server = TLSAuthGrpcServerService(tlsAuthGrpcServerProperties).serverBuilder()
+                .intercept(GrpcServerLoggingInterceptor())
+                .addService(MockTLSBluePrintProcessingServer())
+                .build()
+        server.start()
+        log.info("GRPC Serve started(${server.isShutdown}) on port(${server.port})...")
+        server.awaitTermination()
+    } catch (e: Exception) {
+        log.error("Failed to start tls grpc integration server", e)
+    }
+
+}
+
+class MockTLSBluePrintProcessingServer : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() {
+    override fun process(responseObserver: StreamObserver<ExecutionServiceOutput>): StreamObserver<ExecutionServiceInput> {
+
+        return object : StreamObserver<ExecutionServiceInput> {
+            override fun onNext(executionServiceInput: ExecutionServiceInput) {
+                log.info("Received requestId(${executionServiceInput.commonHeader.requestId})  " +
+                        "subRequestId(${executionServiceInput.commonHeader.subRequestId})")
+                responseObserver.onNext(buildResponse(executionServiceInput))
+                responseObserver.onCompleted()
+            }
+
+            override fun onError(error: Throwable) {
+                log.debug("Fail to process message", error)
+                responseObserver.onError(io.grpc.Status.INTERNAL
+                        .withDescription(error.message)
+                        .asException())
+            }
+
+            override fun onCompleted() {
+                log.info("Completed")
+            }
+        }
+    }
+
+    private fun buildResponse(input: ExecutionServiceInput): ExecutionServiceOutput {
+        val status = Status.newBuilder().setCode(200)
+                .setEventType(EventType.EVENT_COMPONENT_EXECUTED)
+                .build()
+        return ExecutionServiceOutput.newBuilder()
+                .setCommonHeader(input.commonHeader)
+                .setActionIdentifiers(input.actionIdentifiers)
+                .setStatus(status)
+                .build()
+
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README
new file mode 100644 (file)
index 0000000..c4e91a2
--- /dev/null
@@ -0,0 +1,5 @@
+
+Generate Certifactes & Keys
+----------------------------
+
+openssl req -x509 -newkey rsa:4096 -keyout my-private-key.pem -out my-public-key-cert.pem -days 3650 -nodes -subj '/CN=localhost'
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-private-key.pem b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-private-key.pem
new file mode 100644 (file)
index 0000000..a7849ae
--- /dev/null
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+y5k17ZEpVCGQySIFFfQux9v0R2Lxzw==
+-----END PRIVATE KEY-----
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-public-key-cert.pem b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/my-public-key-cert.pem
new file mode 100644 (file)
index 0000000..b388885
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEpDCCAowCCQDElilolKhFszANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
+b2NhbGhvc3QwHhcNMTkxMDIyMTczODI0WhcNMjkxMDE5MTczODI0WjAUMRIwEAYD
+VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDE
+D3IZY6mBMXiDT9aW/VxH5JD91BwkS6ya98ZfQnoqmsi4tzDth+cBlA+L8TsfpMqV
+mYcI3ZUz83uHThQh/4jMisqHbHcT777cqkdO2PT7NHFPn+YY6hjkUZnA2ajFJpfK
+eo9mimM6NAc1g7U4XfYLIUX1ZbmHKXkyUjDv4OxnWQkLaL8AuHJozoOBRbr4cdvw
+Nqfy8YMLxe6iRuWzguyzM5DLpP6EqiIVkUDlzQ3reTzLHD84USB5ygIvqAB9/5Mx
+TT2w1/uiwMH4i1WH0c4+xA6VFVIJkZ8EGxJhXo2kNixMOXhXcXb9sTg4NvMU/e0X
+7cRHQ7fhdYEOQjZhAwdMrQFdcOdMRh55RV3bLGSaBPu0LYgM/8ys2n3y9ohDph9B
+cAlIJHsjU3zhkpyKB78dtVA2NGyMyMp0izlDRCRgJWppvpJwHCHy2sKhmlLeJs5d
+Pr65E7qaT8HzEvRxr/6NKRKuseV9DMflwT8edXNYqKY9UeiqY8aOcYPoYCnsdKA3
+ZyYm075I4OcAsFu9sYKMiL0goGNjxkNk2N22cGBMBthGjW+9jwEHC/HjZwVTf7o/
+2HIOfFcKkssHdEhmDWsAddMN2UNbwdWr/Le1qf/mlOBImQtXBJLtyxfSMey7BQus
+dgCYKvhq8Fn6/xPlyVcIrYyOw6XkMklqftLJJzhk7QIDAQABMA0GCSqGSIb3DQEB
+CwUAA4ICAQCGIXVox06XxEHhVTC+XUsPHQppQPI4tibUAijTaM6jgibZeo4zWDQe
+y8LGpvpNVA8KuRBGnjp1bSdOnmymFSnWIf/3ihKjI0NtG8huadcq+KOkbEQAMq7Z
+KrGhRMMgfSdBz/y8IBE3K6O9RlSP2pbjZ3gZnbSL4a9qMXzCYRxsVvqHsuOnT5/F
+gUBDZQD76NzeIv/WU9YpRo0cR7AWZ6b0a8+7CI7nvXUIIsobrfmbomw4ThFBSJes
+EnFUNCLczvItzTkIImofnMSHf1uE0oNHSZfGPo75ZkoIyJqz1QeEtr3DBluq7Yhd
+EwhcG0YZHgySL912dPQ8YeXcSV/c/JH6mf4LBFlDuR85wWcumUnvuHdWWfXT+nrI
+kVsykuLtN8vpwrPX65oNOJlG6q3L6GRX7TXcsSFYR0obpkgXHo8/QEzlNLpDh4wi
+mlMxOUn6PojbuMDAVK8FXBnEXMbwS7fR086UhF7Zfrvcqu2qWKXOuTxQiW3GZxDX
+KhaKv3AL73yocC/uy3Ou7p7VQOcpz3EkzBY4Ac+1S4OAi+HdL/x9XD15sXalP2nz
+eGqwc+jzII4lp66pwsgFVdBsSe1gPHgdL8h9SirlqHkeHZAp1TeT/ZFBb5VndX0j
+XppSbJQNC/OSjlxlduPvaHWOQO0gsZ+iufs0fZfP5B2GZxGT0Ho0Ew==
+-----END CERTIFICATE-----
index 37a0712..a77122f 100755 (executable)
@@ -48,6 +48,7 @@
         <json.unit.version>2.8.0</json.unit.version>
         <xmlunit.version>2.6.3</xmlunit.version>
 
+        <netty-ssl>2.0.26.Final</netty-ssl>
         <sshd.version>2.2.0</sshd.version>
         <jsch.version>0.1.55</jsch.version>
         <jython.version>2.7.1</jython.version>
                 <artifactId>protobuf-java-util</artifactId>
                 <version>${protobuff.java.utils.version}</version>
             </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-tcnative-boringssl-static</artifactId>
+                <version>${netty-ssl}</version>
+            </dependency>
 
             <!-- Adaptors -->
             <dependency>
             <groupId>com.google.protobuf</groupId>
             <artifactId>protobuf-java-util</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-tcnative-boringssl-static</artifactId>
+        </dependency>
     </dependencies>
 
     <repositories>