Updating Rest code for AAI resolution 65/83965/2
authorjanani b <janani.b@huawei.com>
Tue, 2 Apr 2019 12:23:56 +0000 (17:53 +0530)
committerjanani b <janani.b@huawei.com>
Tue, 2 Apr 2019 15:51:58 +0000 (21:21 +0530)
This commit includes,
i) Updated the SSL based rest connection for different auth support
ii) Checked the co-routines based rest connection

Issue-ID: CCSDK-692

Change-Id: Ic2fe5e5292c9190670d2a573598d78e94f59efb0
Signed-off-by: janani b <janani.b@huawei.com>
12 files changed:
ms/blueprintsprocessor/modules/commons/rest-lib/pom.xml
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BlueprintWebClientService.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt [deleted file]
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLRestClientService.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyServiceTest.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/test/resources/keystore.p12 [new file with mode: 0644]

index 054f238..6809e79 100644 (file)
@@ -2,6 +2,7 @@
 <!--
   ~  Copyright © 2017-2018 AT&T Intellectual Property.
   ~  Modifications Copyright © 2018 IBM.
+  ~  Modifications Copyright © 2019 Huawei.
   ~
   ~  Licensed under the Apache License, Version 2.0 (the "License");
   ~  you may not use this file except in compliance with the License.
             <artifactId>httpclient</artifactId>
             <version>${apache.httpcomponents.client.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
index 05143f3..fa4ff23 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  * Modifications Copyright © 2019 IBM.
+ * Modifications Copyright © 2019 Huawei.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,6 +34,8 @@ class RestLibConstants {
         const val TYPE_TOKEN_AUTH = "token-auth"
         const val TYPE_BASIC_AUTH = "basic-auth"
         const val TYPE_SSL_BASIC_AUTH = "ssl-basic-auth"
+        const val TYPE_SSL_TOKEN_AUTH = "ssl-token-auth"
+        const val TYPE_SSL_NO_AUTH = "ssl-no-auth"
         const val TYPE_DME2_PROXY = "dme2-proxy"
         const val TYPE_POLICY_MANAGER = "policy-manager"
     }
index 4e6e62e..70ec950 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 Huawei.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +22,22 @@ open class RestClientProperties {
     lateinit var url: String
 }
 
+open class SSLRestClientProperties : RestClientProperties() {
+    lateinit var keyStoreInstance: String // JKS, PKCS12
+    lateinit var sslTrust: String
+    lateinit var sslTrustPassword: String
+    var sslKey: String? = null
+    var sslKeyPassword: String? = null
+}
+
+open class SSLBasicAuthRestClientProperties : SSLRestClientProperties() {
+    var basicAuth: BasicAuthRestClientProperties? = null
+}
+
+open class SSLTokenAuthRestClientProperties : SSLRestClientProperties() {
+    var tokenAuth: TokenAuthRestClientProperties? = null
+}
+
 open class BasicAuthRestClientProperties : RestClientProperties() {
     lateinit var password: String
     lateinit var username: String
@@ -30,14 +47,6 @@ open class TokenAuthRestClientProperties : RestClientProperties() {
     var token: String? = null
 }
 
-open class SSLBasicAuthRestClientProperties : RestClientProperties() {
-    lateinit var keyStoreInstance: String // JKS, PKCS12
-    lateinit var sslTrust: String
-    lateinit var sslTrustPassword: String
-    lateinit var sslKey: String
-    lateinit var sslKeyPassword: String
-}
-
 open class DME2RestClientProperties : RestClientProperties() {
     lateinit var service: String
     lateinit var subContext: String
index 67dbd0d..3190cd1 100644 (file)
@@ -23,11 +23,14 @@ import org.springframework.http.MediaType
 import java.nio.charset.Charset
 import java.util.*
 
-class BasicAuthRestClientService(private val restClientProperties: BasicAuthRestClientProperties) :
-    BlueprintWebClientService {
+class BasicAuthRestClientService(private val restClientProperties:
+                                 BasicAuthRestClientProperties) :
+        BlueprintWebClientService {
 
     override fun defaultHeaders(): Map<String, String> {
-        val encodedCredentials = setBasicAuth(restClientProperties.username, restClientProperties.password)
+
+        val encodedCredentials = setBasicAuth(restClientProperties.username,
+                restClientProperties.password)
         return mapOf(
                 HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE,
                 HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE,
@@ -38,18 +41,25 @@ class BasicAuthRestClientService(private val restClientProperties: BasicAuthRest
         return restClientProperties.url + uri
     }
 
-    override fun convertToBasicHeaders(headers: Map<String, String>): Array<BasicHeader> {
+    override fun convertToBasicHeaders(headers: Map<String, String>):
+            Array<BasicHeader> {
+
         val customHeaders: MutableMap<String, String> = headers.toMutableMap()
         if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
-            val encodedCredentials = setBasicAuth(restClientProperties.username, restClientProperties.password)
-            customHeaders[HttpHeaders.AUTHORIZATION] = "Basic $encodedCredentials"
+            val encodedCredentials = setBasicAuth(
+                    restClientProperties.username,
+                    restClientProperties.password)
+            customHeaders[HttpHeaders.AUTHORIZATION] =
+                    "Basic $encodedCredentials"
         }
         return super.convertToBasicHeaders(customHeaders)
     }
 
     private fun setBasicAuth(username: String, password: String): String {
+
         val credentialsString = "$username:$password"
-        return Base64.getEncoder().encodeToString(credentialsString.toByteArray(Charset.defaultCharset()))
+        return Base64.getEncoder().encodeToString(
+                credentialsString.toByteArray(Charset.defaultCharset()))
     }
 
 
index dc97446..a6bbc39 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2019 AT&T, Bell Canada
  * Modifications Copyright © 2019 IBM.
+ * Modifications Copyright © 2019 Huawei.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,15 +26,19 @@ import org.onap.ccsdk.cds.blueprintsprocessor.rest.PolicyManagerRestClientProper
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestLibConstants
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLTokenAuthRestClientProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.TokenAuthRestClientProperties
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.stereotype.Service
 
 @Service(RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY)
-open class BluePrintRestLibPropertyService(private var bluePrintProperties: BluePrintProperties) {
+open class BluePrintRestLibPropertyService(private var bluePrintProperties:
+                                           BluePrintProperties) {
 
-    fun blueprintWebClientService(jsonNode: JsonNode): BlueprintWebClientService {
+    fun blueprintWebClientService(jsonNode: JsonNode):
+            BlueprintWebClientService {
         val restClientProperties = restClientProperties(jsonNode)
         return blueprintWebClientService(restClientProperties)
     }
@@ -45,7 +50,8 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: Blue
     }
 
     fun restClientProperties(prefix: String): RestClientProperties {
-        val type = bluePrintProperties.propertyBeanType("$prefix.type", String::class.java)
+        val type = bluePrintProperties.propertyBeanType(
+                "$prefix.type", String::class.java)
         return when (type) {
             RestLibConstants.TYPE_BASIC_AUTH -> {
                 basicAuthRestClientProperties(prefix)
@@ -53,6 +59,12 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: Blue
             RestLibConstants.TYPE_SSL_BASIC_AUTH -> {
                 sslBasicAuthRestClientProperties(prefix)
             }
+            RestLibConstants.TYPE_SSL_TOKEN_AUTH -> {
+                sslTokenAuthRestClientProperties(prefix)
+            }
+            RestLibConstants.TYPE_SSL_NO_AUTH -> {
+                sslNoAuthRestClientProperties(prefix)
+            }
             RestLibConstants.TYPE_DME2_PROXY -> {
                 dme2ProxyClientProperties(prefix)
             }
@@ -60,69 +72,123 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: Blue
                 policyManagerRestClientProperties(prefix)
             }
             else -> {
-                throw BluePrintProcessorException("Rest adaptor($type) is not supported")
+                throw BluePrintProcessorException("Rest adaptor($type) is" +
+                        " not supported")
             }
         }
     }
 
-    private fun restClientProperties(jsonNode: JsonNode): RestClientProperties {
+    fun restClientProperties(jsonNode: JsonNode): RestClientProperties {
+
         val type = jsonNode.get("type").textValue()
         return when (type) {
             RestLibConstants.TYPE_TOKEN_AUTH -> {
-                JacksonUtils.readValue(jsonNode, TokenAuthRestClientProperties::class.java)!!
+                JacksonUtils.readValue(jsonNode,
+                        TokenAuthRestClientProperties::class.java)!!
             }
             RestLibConstants.TYPE_BASIC_AUTH -> {
-                JacksonUtils.readValue(jsonNode, BasicAuthRestClientProperties::class.java)!!
-            }
-            RestLibConstants.TYPE_SSL_BASIC_AUTH -> {
-                JacksonUtils.readValue(jsonNode, SSLBasicAuthRestClientProperties::class.java)!!
+                JacksonUtils.readValue(jsonNode,
+                        BasicAuthRestClientProperties::class.java)!!
             }
             RestLibConstants.TYPE_DME2_PROXY -> {
-                JacksonUtils.readValue(jsonNode, DME2RestClientProperties::class.java)!!
+                JacksonUtils.readValue(jsonNode,
+                        DME2RestClientProperties::class.java)!!
             }
             RestLibConstants.TYPE_POLICY_MANAGER -> {
-                JacksonUtils.readValue(jsonNode, PolicyManagerRestClientProperties::class.java)!!
+                JacksonUtils.readValue(jsonNode,
+                        PolicyManagerRestClientProperties::class.java)!!
+            }
+            RestLibConstants.TYPE_SSL_BASIC_AUTH -> {
+                JacksonUtils.readValue(jsonNode,
+                        SSLBasicAuthRestClientProperties::class.java)!!
+            }
+            RestLibConstants.TYPE_SSL_TOKEN_AUTH -> {
+                JacksonUtils.readValue(jsonNode,
+                        SSLTokenAuthRestClientProperties::class.java)!!
+            }
+            RestLibConstants.TYPE_SSL_NO_AUTH -> {
+                JacksonUtils.readValue(
+                        jsonNode, SSLRestClientProperties::class.java)!!
             }
             else -> {
-                throw BluePrintProcessorException("Rest adaptor($type) is not supported")
+                throw BluePrintProcessorException("Rest adaptor($type) is" +
+                        " not supported")
             }
         }
     }
+    
+    private fun blueprintWebClientService(
+            restClientProperties: RestClientProperties):
+            BlueprintWebClientService {
 
-    private fun blueprintWebClientService(restClientProperties: RestClientProperties): BlueprintWebClientService {
         when (restClientProperties) {
+            is SSLRestClientProperties -> {
+                return SSLRestClientService(restClientProperties)
+            }
             is TokenAuthRestClientProperties -> {
                 return TokenAuthRestClientService(restClientProperties)
             }
             is BasicAuthRestClientProperties -> {
                 return BasicAuthRestClientService(restClientProperties)
             }
-            is SSLBasicAuthRestClientProperties -> {
-                return SSLBasicAuthRestClientService(restClientProperties)
-            }
             is DME2RestClientProperties -> {
                 return DME2ProxyRestClientService(restClientProperties)
             }
             else -> {
-                throw BluePrintProcessorException("couldn't get rest service for")
+                throw BluePrintProcessorException("couldn't get rest " +
+                        "service for")
             }
         }
     }
 
-    private fun basicAuthRestClientProperties(prefix: String): BasicAuthRestClientProperties {
-        return bluePrintProperties.propertyBeanType(prefix, BasicAuthRestClientProperties::class.java)
+    private fun basicAuthRestClientProperties(prefix: String):
+            BasicAuthRestClientProperties {
+        return bluePrintProperties.propertyBeanType(
+                prefix, BasicAuthRestClientProperties::class.java)
+    }
+
+    private fun sslBasicAuthRestClientProperties(prefix: String):
+            SSLRestClientProperties {
+
+        val sslProps: SSLBasicAuthRestClientProperties =
+                bluePrintProperties.propertyBeanType(
+                        prefix, SSLBasicAuthRestClientProperties::class.java)
+        val basicProps : BasicAuthRestClientProperties =
+                bluePrintProperties.propertyBeanType(
+                        prefix, BasicAuthRestClientProperties::class.java)
+        sslProps.basicAuth = basicProps
+        return sslProps
+    }
+
+    private fun sslTokenAuthRestClientProperties(prefix: String):
+            SSLRestClientProperties {
+
+        val sslProps: SSLTokenAuthRestClientProperties =
+                bluePrintProperties.propertyBeanType(prefix,
+                        SSLTokenAuthRestClientProperties::class.java)
+        val basicProps : TokenAuthRestClientProperties =
+                bluePrintProperties.propertyBeanType(prefix,
+                        TokenAuthRestClientProperties::class.java)
+        sslProps.tokenAuth = basicProps
+        return sslProps
     }
 
-    private fun sslBasicAuthRestClientProperties(prefix: String): SSLBasicAuthRestClientProperties {
-        return bluePrintProperties.propertyBeanType(prefix, SSLBasicAuthRestClientProperties::class.java)
+    private fun sslNoAuthRestClientProperties(prefix: String):
+            SSLRestClientProperties {
+        return bluePrintProperties.propertyBeanType(
+                prefix, SSLRestClientProperties::class.java)
     }
 
-    private fun dme2ProxyClientProperties(prefix: String): DME2RestClientProperties {
-        return bluePrintProperties.propertyBeanType(prefix, DME2RestClientProperties::class.java)
+    private fun dme2ProxyClientProperties(prefix: String):
+            DME2RestClientProperties {
+        return bluePrintProperties.propertyBeanType(
+                prefix, DME2RestClientProperties::class.java)
     }
 
-    private fun policyManagerRestClientProperties(prefix: String): PolicyManagerRestClientProperties {
-        return bluePrintProperties.propertyBeanType(prefix, PolicyManagerRestClientProperties::class.java)
+    private fun policyManagerRestClientProperties(prefix: String):
+            PolicyManagerRestClientProperties {
+        return bluePrintProperties.propertyBeanType(
+                prefix, PolicyManagerRestClientProperties::class.java)
     }
 }
 
index 1c1d510..d6d02b3 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2019 AT&T, Bell Canada, Nordix Foundation
  * Modifications Copyright © 2018-2019 IBM.
+ * Modifications Copyright © 2019 Huawei.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +22,11 @@ import com.fasterxml.jackson.databind.JsonNode
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 import org.apache.commons.io.IOUtils
-import org.apache.http.client.methods.*
+import org.apache.http.client.methods.HttpDelete
+import org.apache.http.client.methods.HttpGet
+import org.apache.http.client.methods.HttpPatch
+import org.apache.http.client.methods.HttpPost
+import org.apache.http.client.methods.HttpPut
 import org.apache.http.entity.StringEntity
 import org.apache.http.impl.client.CloseableHttpClient
 import org.apache.http.impl.client.HttpClients
@@ -30,6 +35,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.rest.utils.WebClientUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.http.HttpMethod
+import java.io.InputStream
 import java.nio.charset.Charset
 
 interface BlueprintWebClientService {
@@ -45,19 +51,24 @@ interface BlueprintWebClientService {
                 .build()
     }
 
-    fun exchangeResource(methodType: String, path: String, request: String): String {
-        return this.exchangeResource(methodType, path, request, defaultHeaders())
+    fun exchangeResource(methodType: String, path: String, request: String):
+            String {
+        return this.exchangeResource(methodType, path, request,
+                defaultHeaders())
     }
 
-    fun exchangeResource(methodType: String, path: String, request: String, headers: Map<String, String>): String {
-        val convertedHeaders: Array<BasicHeader> = convertToBasicHeaders(headers)
+    fun exchangeResource(methodType: String, path: String, request: String,
+                         headers: Map<String, String>): String {
+        val convertedHeaders: Array<BasicHeader> = convertToBasicHeaders(
+                headers)
         return when (HttpMethod.resolve(methodType)) {
             HttpMethod.DELETE -> delete(path, convertedHeaders)
             HttpMethod.GET -> get(path, convertedHeaders)
             HttpMethod.POST -> post(path, request, convertedHeaders)
             HttpMethod.PUT -> put(path, request, convertedHeaders)
             HttpMethod.PATCH -> patch(path, request, convertedHeaders)
-            else -> throw BluePrintProcessorException("Unsupported methodType($methodType)")
+            else -> throw BluePrintProcessorException("Unsupported met" +
+                    "hodType($methodType)")
         }
     }
 
@@ -81,7 +92,8 @@ interface BlueprintWebClientService {
         }
     }
 
-    fun post(path: String, request: String, headers: Array<BasicHeader>): String {
+    fun post(path: String, request: String, headers: Array<BasicHeader>):
+            String {
         val httpPost = HttpPost(host(path))
         val entity = StringEntity(request)
         httpPost.entity = entity
@@ -91,7 +103,8 @@ interface BlueprintWebClientService {
         }
     }
 
-    fun put(path: String, request: String, headers: Array<BasicHeader>): String {
+    fun put(path: String, request: String, headers: Array<BasicHeader>):
+            String {
         val httpPut = HttpPut(host(path))
         val entity = StringEntity(request)
         httpPut.entity = entity
@@ -101,7 +114,8 @@ interface BlueprintWebClientService {
         }
     }
 
-    fun patch(path: String, request: String, headers: Array<BasicHeader>): String {
+    fun patch(path: String, request: String, headers: Array<BasicHeader>):
+            String {
         val httpPatch = HttpPatch(host(path))
         val entity = StringEntity(request)
         httpPatch.entity = entity
@@ -111,28 +125,23 @@ interface BlueprintWebClientService {
         }
     }
 
-    // Non Blocking Rest Implementation
-    suspend fun httpClientNB(): CloseableHttpClient {
-        return HttpClients.custom()
-                .addInterceptorFirst(WebClientUtils.logRequest())
-                .addInterceptorLast(WebClientUtils.logResponse())
-                .build()
-    }
 
     suspend fun getNB(path: String): String {
         return getNB(path, null, String::class.java)
     }
 
-    suspend fun getNB(path: String, additionalHeaders: Map<String, String>?): String {
+    suspend fun getNB(path: String, additionalHeaders: Map<String, String>?):
+            String {
         return getNB(path, additionalHeaders, String::class.java)
     }
 
     suspend fun <T> getNB(path: String, additionalHeaders: Map<String, String>?,
-                          responseType: Class<T>): T = withContext(Dispatchers.IO) {
+                          responseType: Class<T>): T =
+            withContext(Dispatchers.IO) {
         val httpGet = HttpGet(host(path))
         httpGet.setHeaders(basicHeaders(additionalHeaders))
         httpClientNB().execute(httpGet).entity.content.use {
-            JacksonUtils.readValue(it, responseType)!!
+            getResponse(it, responseType)
         }
     }
 
@@ -140,18 +149,20 @@ interface BlueprintWebClientService {
         return postNB(path, request, null, String::class.java)
     }
 
-    suspend fun postNB(path: String, request: Any, additionalHeaders: Map<String, String>?): String {
+    suspend fun postNB(path: String, request: Any,
+                       additionalHeaders: Map<String, String>?): String {
         return postNB(path, request, additionalHeaders, String::class.java)
     }
 
-    suspend fun <T> postNB(path: String, request: Any, additionalHeaders: Map<String, String>?,
+    suspend fun <T> postNB(path: String, request: Any,
+                           additionalHeaders: Map<String, String>?,
                            responseType: Class<T>): T =
             withContext(Dispatchers.IO) {
                 val httpPost = HttpPost(host(path))
                 httpPost.entity = StringEntity(strRequest(request))
                 httpPost.setHeaders(basicHeaders(additionalHeaders))
                 httpClientNB().execute(httpPost).entity.content.use {
-                    JacksonUtils.readValue(it, responseType)!!
+                    getResponse(it, responseType)
                 }
             }
 
@@ -159,17 +170,20 @@ interface BlueprintWebClientService {
         return putNB(path, request, null, String::class.java)
     }
 
-    suspend fun putNB(path: String, request: Any, additionalHeaders: Map<String, String>?): String {
+    suspend fun putNB(path: String, request: Any,
+                      additionalHeaders: Map<String, String>?): String {
         return putNB(path, request, additionalHeaders, String::class.java)
     }
 
-    suspend fun <T> putNB(path: String, request: Any, additionalHeaders: Map<String, String>?,
-                          responseType: Class<T>): T = withContext(Dispatchers.IO) {
+    suspend fun <T> putNB(path: String, request: Any,
+                          additionalHeaders: Map<String, String>?,
+                          responseType: Class<T>): T =
+            withContext(Dispatchers.IO) {
         val httpPut = HttpPut(host(path))
         httpPut.entity = StringEntity(strRequest(request))
         httpPut.setHeaders(basicHeaders(additionalHeaders))
         httpClientNB().execute(httpPut).entity.content.use {
-            JacksonUtils.readValue(it, responseType)!!
+            getResponse(it, responseType)
         }
     }
 
@@ -177,46 +191,61 @@ interface BlueprintWebClientService {
         return deleteNB(path, null, String::class.java)
     }
 
-    suspend fun <T> deleteNB(path: String, additionalHeaders: Map<String, String>?): String {
+    suspend fun <T> deleteNB(path: String,
+                             additionalHeaders: Map<String, String>?): String {
         return deleteNB(path, additionalHeaders, String::class.java)
     }
 
-    suspend fun <T> deleteNB(path: String, additionalHeaders: Map<String, String>?, responseType: Class<T>): T =
+    suspend fun <T> deleteNB(path: String,
+                             additionalHeaders: Map<String, String>?,
+                             responseType: Class<T>): T =
             withContext(Dispatchers.IO) {
-                val httpDelete = HttpDelete(host(path))
-                httpDelete.setHeaders(basicHeaders(additionalHeaders))
-                httpClient().execute(httpDelete).entity.content.use {
-                    JacksonUtils.readValue(it, responseType)!!
-                }
-            }
+        val httpDelete = HttpDelete(host(path))
+        httpDelete.setHeaders(basicHeaders(additionalHeaders))
+        httpClient().execute(httpDelete).entity.content.use {
+            getResponse(it, responseType)
+        }
+    }
 
-    suspend fun <T> patchNB(path: String, request: Any, additionalHeaders: Map<String, String>?,
-                            responseType: Class<T>): T = withContext(Dispatchers.IO) {
+    suspend fun <T> patchNB(path: String, request: Any,
+                            additionalHeaders: Map<String, String>?,
+                            responseType: Class<T>): T =
+            withContext(Dispatchers.IO) {
         val httpPatch = HttpPatch(host(path))
         httpPatch.entity = StringEntity(strRequest(request))
         httpPatch.setHeaders(basicHeaders(additionalHeaders))
         httpClient().execute(httpPatch).entity.content.use {
-            JacksonUtils.readValue(it, responseType)!!
+            getResponse(it, responseType)
         }
     }
 
-    suspend fun exchangeNB(methodType: String, path: String, request: Any): String {
-        return exchangeNB(methodType, path, request, hashMapOf(), String::class.java)
+    suspend fun exchangeNB(methodType: String, path: String, request: Any):
+            String {
+        return exchangeNB(methodType, path, request, hashMapOf(),
+                String::class.java)
     }
 
-    suspend fun exchangeNB(methodType: String, path: String, request: Any, additionalHeaders: Map<String, String>?): String {
-        return exchangeNB(methodType, path, request, additionalHeaders, String::class.java)
+    suspend fun exchangeNB(methodType: String, path: String, request: Any,
+                           additionalHeaders: Map<String, String>?): String {
+        return exchangeNB(methodType, path, request, additionalHeaders,
+                String::class.java)
     }
 
-    suspend fun <T> exchangeNB(methodType: String, path: String, request: Any, additionalHeaders: Map<String, String>?,
+    suspend fun <T> exchangeNB(methodType: String, path: String, request: Any,
+                               additionalHeaders: Map<String, String>?,
                                responseType: Class<T>): T {
+
         return when (HttpMethod.resolve(methodType)) {
             HttpMethod.GET -> getNB(path, additionalHeaders, responseType)
-            HttpMethod.POST -> postNB(path, request, additionalHeaders, responseType)
+            HttpMethod.POST -> postNB(path, request, additionalHeaders,
+                    responseType)
             HttpMethod.DELETE -> deleteNB(path, additionalHeaders, responseType)
-            HttpMethod.PUT -> putNB(path, request, additionalHeaders, responseType)
-            HttpMethod.PATCH -> patchNB(path, request, additionalHeaders, responseType)
-            else -> throw BluePrintProcessorException("Unsupported methodType($methodType)")
+            HttpMethod.PUT -> putNB(path, request, additionalHeaders,
+                    responseType)
+            HttpMethod.PATCH -> patchNB(path, request, additionalHeaders,
+                    responseType)
+            else -> throw BluePrintProcessorException("Unsupported method" +
+                    "Type($methodType)")
         }
     }
 
@@ -228,7 +257,17 @@ interface BlueprintWebClientService {
         }
     }
 
-    private fun basicHeaders(headers: Map<String, String>?): Array<BasicHeader> {
+    private fun <T> getResponse(it: InputStream, responseType: Class<T>): T {
+        return if (responseType == String::class.java) {
+            IOUtils.toString(it, Charset.defaultCharset()) as T
+        } else {
+            JacksonUtils.readValue(it, responseType)!!
+        }
+    }
+
+    private fun basicHeaders(headers: Map<String, String>?):
+            Array<BasicHeader> {
+
         val basicHeaders = mutableListOf<BasicHeader>()
         defaultHeaders().forEach { name, value ->
             basicHeaders.add(BasicHeader(name, value))
@@ -238,4 +277,12 @@ interface BlueprintWebClientService {
         }
         return basicHeaders.toTypedArray()
     }
+
+    // Non Blocking Rest Implementation
+    suspend fun httpClientNB(): CloseableHttpClient {
+        return HttpClients.custom()
+                .addInterceptorFirst(WebClientUtils.logRequest())
+                .addInterceptorLast(WebClientUtils.logResponse())
+                .build()
+    }
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt
deleted file mode 100644 (file)
index 3d3b0a5..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright © 2017-2019 AT&T, 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.rest.service
-
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory
-import org.apache.http.impl.client.CloseableHttpClient
-import org.apache.http.impl.client.HttpClients
-import org.apache.http.ssl.SSLContextBuilder
-import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties
-import org.onap.ccsdk.cds.blueprintsprocessor.rest.utils.WebClientUtils
-import org.springframework.http.HttpHeaders
-import org.springframework.http.MediaType
-import java.io.File
-import java.io.FileInputStream
-import java.security.KeyStore
-import java.security.cert.X509Certificate
-
-class SSLBasicAuthRestClientService(private val restClientProperties: SSLBasicAuthRestClientProperties) :
-    BlueprintWebClientService {
-
-    override fun defaultHeaders(): Map<String, String> {
-        return mapOf(
-                HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE,
-                HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE)
-    }
-
-    override fun host(uri: String): String {
-        return restClientProperties.url + uri
-    }
-
-    override fun httpClient(): CloseableHttpClient {
-
-        val keystoreInstance = restClientProperties.keyStoreInstance
-        val sslKey = restClientProperties.sslKey
-        val sslKeyPwd = restClientProperties.sslKeyPassword
-        val sslTrust = restClientProperties.sslTrust
-        val sslTrustPwd = restClientProperties.sslTrustPassword
-
-        val acceptingTrustStrategy = { chain: Array<X509Certificate>, authType: String -> true }
-
-        FileInputStream(sslKey).use { keyInput ->
-            val keyStore = KeyStore.getInstance(keystoreInstance)
-            keyStore.load(keyInput, sslKeyPwd.toCharArray())
-
-            val sslContext =
-                SSLContextBuilder.create()
-                    .loadKeyMaterial(keyStore, sslKeyPwd.toCharArray())
-                    .loadTrustMaterial(File(sslTrust), sslTrustPwd.toCharArray(), acceptingTrustStrategy).build()
-
-            val csf = SSLConnectionSocketFactory(sslContext!!)
-
-            return HttpClients.custom()
-                .addInterceptorFirst(WebClientUtils.logRequest())
-                .addInterceptorLast(WebClientUtils.logResponse())
-                .setSSLSocketFactory(csf).build()
-        }
-    }
-}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/SSLRestClientService.kt
new file mode 100644 (file)
index 0000000..30dd490
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2017-2019 AT&T, Bell Canada
+ * Modifications Copyright © 2019 Huawei.
+ *
+ * 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.rest.service
+
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory
+import org.apache.http.impl.client.CloseableHttpClient
+import org.apache.http.impl.client.HttpClients
+import org.apache.http.message.BasicHeader
+import org.apache.http.ssl.SSLContextBuilder
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLTokenAuthRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.utils.WebClientUtils
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import java.io.File
+import java.io.FileInputStream
+import java.security.KeyStore
+import java.security.cert.X509Certificate
+
+class SSLRestClientService(private val restClientProperties:
+                           SSLRestClientProperties) :
+        BlueprintWebClientService {
+
+    var auth: BlueprintWebClientService? = null
+
+    init {
+         auth = getAuthService()
+    }
+
+    private fun getAuthService() : BlueprintWebClientService? {
+
+        return when(restClientProperties) {
+            is SSLBasicAuthRestClientProperties -> {
+                val basic =  restClientProperties.basicAuth!!
+                BasicAuthRestClientService(basic)
+            }
+            is SSLTokenAuthRestClientProperties -> {
+                val token =  restClientProperties.tokenAuth!!
+                TokenAuthRestClientService(token)
+            }
+            else -> {
+                //Returns null for No auth
+                null
+            }
+        }
+    }
+
+
+    override fun defaultHeaders(): Map<String, String> {
+
+        if (auth != null) {
+            return auth!!.defaultHeaders()
+        }
+        return mapOf(
+                HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE,
+                HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE)
+    }
+
+    override fun host(uri: String): String {
+
+        return restClientProperties.url + uri
+    }
+
+    override fun httpClient(): CloseableHttpClient {
+
+        val keystoreInstance = restClientProperties.keyStoreInstance
+        val sslKey = restClientProperties.sslKey
+        val sslKeyPwd = restClientProperties.sslKeyPassword
+        val sslTrust = restClientProperties.sslTrust
+        val sslTrustPwd = restClientProperties.sslTrustPassword
+
+        val acceptingTrustStrategy = { chain: Array<X509Certificate>,
+                                       authType: String -> true }
+        val sslContext = SSLContextBuilder.create()
+
+        if (sslKey != null && sslKeyPwd != null) {
+            FileInputStream(sslKey).use { keyInput ->
+                val keyStore = KeyStore.getInstance(keystoreInstance)
+                keyStore.load(keyInput, sslKeyPwd.toCharArray())
+                sslContext.loadKeyMaterial(keyStore, sslKeyPwd.toCharArray())
+            }
+        }
+
+        sslContext.loadTrustMaterial(File(sslTrust), sslTrustPwd.toCharArray(),
+                acceptingTrustStrategy)
+        val csf = SSLConnectionSocketFactory(sslContext.build())
+        return HttpClients.custom()
+                .addInterceptorFirst(WebClientUtils.logRequest())
+                .addInterceptorLast(WebClientUtils.logResponse())
+                .setSSLSocketFactory(csf).build()
+
+    }
+
+    // Non Blocking Rest Implementation
+    override suspend fun httpClientNB(): CloseableHttpClient {
+        return httpClient()
+    }
+
+    override fun convertToBasicHeaders(headers: Map<String, String>): Array<BasicHeader> {
+        var head1: Map<String, String> = defaultHeaders()
+        var head2: MutableMap<String, String> = head1.toMutableMap()
+        head2.putAll(headers)
+        if (auth != null) {
+            return auth!!.convertToBasicHeaders(head2)
+        }
+        return super.convertToBasicHeaders(head2)
+    }
+
+}
\ No newline at end of file
index 6f81ee1..8244699 100644 (file)
@@ -21,17 +21,21 @@ import org.onap.ccsdk.cds.blueprintsprocessor.rest.TokenAuthRestClientProperties
 import org.springframework.http.HttpHeaders
 import org.springframework.http.MediaType
 
-class TokenAuthRestClientService(private val restClientProperties: TokenAuthRestClientProperties) :
-    BlueprintWebClientService {
+class TokenAuthRestClientService(private val restClientProperties:
+                                 TokenAuthRestClientProperties) :
+        BlueprintWebClientService {
 
     override fun defaultHeaders(): Map<String, String> {
+
         return mapOf(
                 HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE,
                 HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE,
                 HttpHeaders.AUTHORIZATION to restClientProperties.token!!)
     }
 
-    override fun convertToBasicHeaders(headers: Map<String, String>): Array<BasicHeader> {
+    override fun convertToBasicHeaders(headers: Map<String, String>):
+            Array<BasicHeader> {
+
         val customHeaders: MutableMap<String, String> = headers.toMutableMap()
         if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
             customHeaders[HttpHeaders.AUTHORIZATION] = restClientProperties.token!!
index c577457..280dd0d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  * Modifications Copyright © 2018 IBM.
+ * Modifications Copyright © 2019 Huawei.
  *
  * 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.rest.service
 
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.ObjectMapper
 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.rest.BluePrintRestLibConfiguration
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLTokenAuthRestClientProperties
 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.assertEquals
 import kotlin.test.assertNotNull
 
-
 @RunWith(SpringRunner::class)
 @ContextConfiguration(classes = [BluePrintRestLibConfiguration::class, BlueprintPropertyConfiguration::class, BluePrintProperties::class])
 @TestPropertySource(properties =
 ["blueprintsprocessor.restclient.sample.type=basic-auth",
     "blueprintsprocessor.restclient.sample.url=http://localhost:8080",
-    "blueprintsprocessor.restclient.sample.userId=sampleuser"])
+    "blueprintsprocessor.restclient.sample.userId=sampleuser",
+    "blueprintsprocessor.restclient.sslbasic.type=ssl-basic-auth",
+    "blueprintsprocessor.restclient.sslbasic.url=https://localhost:8443",
+    "blueprintsprocessor.restclient.sslbasic.username=admin",
+    "blueprintsprocessor.restclient.sslbasic.password=cds",
+    "blueprintsprocessor.restclient.sslbasic.keyStoreInstance=PKCS12",
+    "blueprintsprocessor.restclient.sslbasic.sslTrust=src/test/resources/keystore.p12",
+    "blueprintsprocessor.restclient.sslbasic.sslTrustPassword=changeit",
+    "blueprintsprocessor.restclient.ssltoken.type=ssl-token-auth",
+    "blueprintsprocessor.restclient.ssltoken.url=https://localhost:8443",
+    "blueprintsprocessor.restclient.ssltoken.token=72178473kjshdkjgvbsdkjv903274908",
+    "blueprintsprocessor.restclient.ssltoken.keyStoreInstance=PKCS12",
+    "blueprintsprocessor.restclient.ssltoken.sslTrust=src/test/resources/keystore.p12",
+    "blueprintsprocessor.restclient.ssltoken.sslTrustPassword=changeit",
+    "blueprintsprocessor.restclient.ssl.type=ssl-no-auth",
+    "blueprintsprocessor.restclient.ssl.url=https://localhost:8443",
+    "blueprintsprocessor.restclient.ssl.keyStoreInstance=PKCS12",
+    "blueprintsprocessor.restclient.ssl.sslTrust=src/test/resources/keystore.p12",
+    "blueprintsprocessor.restclient.ssl.sslTrustPassword=changeit",
+    "blueprintsprocessor.restclient.ssl.sslKey=src/test/resources/keystore.p12",
+    "blueprintsprocessor.restclient.ssl.sslKeyPassword=changeit"
+])
 
 class BluePrintRestLibPropertyServiceTest {
 
@@ -43,15 +70,148 @@ class BluePrintRestLibPropertyServiceTest {
 
     @Test
     fun testRestClientProperties() {
-        val properties = bluePrintRestLibPropertyService.restClientProperties("blueprintsprocessor.restclient.sample")
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                "blueprintsprocessor.restclient.sample")
+        assertNotNull(properties, "failed to create property bean")
+        assertNotNull(properties.url, "failed to get url property in" +
+                " property bean")
+    }
+
+    @Test
+    fun testSSLBasicProperties() {
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                "blueprintsprocessor.restclient.sslbasic")
+        assertNotNull(properties, "failed to create property bean")
+        val p: SSLBasicAuthRestClientProperties =
+                properties as SSLBasicAuthRestClientProperties
+
+        assertEquals(p.basicAuth!!.username, "admin")
+        assertEquals(p.basicAuth!!.password, "cds")
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+    }
+
+    @Test
+    fun testSSLTokenProperties() {
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                "blueprintsprocessor.restclient.ssltoken")
+        assertNotNull(properties, "failed to create property bean")
+
+        val p: SSLTokenAuthRestClientProperties =
+                properties as SSLTokenAuthRestClientProperties
+
+        assertEquals(p.tokenAuth!!.token!!, "72178473kjshdkjgvbsdkjv903274908")
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+    }
+
+    @Test
+    fun testSSLNoAuthProperties() {
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                "blueprintsprocessor.restclient.ssl")
+        assertNotNull(properties, "failed to create property bean")
+
+        val p: SSLRestClientProperties =
+                properties as SSLRestClientProperties
+
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+        assertEquals(p.sslKey, "src/test/resources/keystore.p12")
+        assertEquals(p.sslKeyPassword, "changeit")
+    }
+
+
+    @Test
+    fun testSSLBasicPropertiesAsJson() {
+        val json: String = "{\n" +
+                "  \"type\" : \"ssl-basic-auth\",\n" +
+                "  \"url\" : \"https://localhost:8443\",\n" +
+                "  \"keyStoreInstance\" : \"PKCS12\",\n" +
+                "  \"sslTrust\" : \"src/test/resources/keystore.p12\",\n" +
+                "  \"sslTrustPassword\" : \"changeit\",\n" +
+                "  \"basicAuth\" : {\n" +
+                "    \"username\" : \"admin\",\n" +
+                "    \"password\" : \"cds\"\n" +
+                "  }\n" +
+                "}"
+        val mapper = ObjectMapper()
+        val actualObj: JsonNode = mapper.readTree(json)
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                actualObj)
+        assertNotNull(properties, "failed to create property bean")
+        val p: SSLBasicAuthRestClientProperties =
+                properties as SSLBasicAuthRestClientProperties
+
+        assertEquals(p.basicAuth!!.username, "admin")
+        assertEquals(p.basicAuth!!.password, "cds")
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+    }
+
+    @Test
+    fun testSSLTokenPropertiesAsJson() {
+        val json: String = "{\n" +
+                "  \"type\" : \"ssl-token-auth\",\n" +
+                "  \"url\" : \"https://localhost:8443\",\n" +
+                "  \"keyStoreInstance\" : \"PKCS12\",\n" +
+                "  \"sslTrust\" : \"src/test/resources/keystore.p12\",\n" +
+                "  \"sslTrustPassword\" : \"changeit\",\n" +
+                "  \"tokenAuth\" : {\n" +
+                "    \"token\" : \"72178473kjshdkjgvbsdkjv903274908\"\n" +
+                "  }\n" +
+                "}"
+        val mapper = ObjectMapper()
+        val actualObj: JsonNode = mapper.readTree(json)
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                actualObj)
         assertNotNull(properties, "failed to create property bean")
-        assertNotNull(properties.url, "failed to get url property in property bean")
+
+        val p: SSLTokenAuthRestClientProperties =
+                properties as SSLTokenAuthRestClientProperties
+
+        assertEquals(p.tokenAuth!!.token!!, "72178473kjshdkjgvbsdkjv903274908")
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+    }
+
+    @Test
+    fun testSSLNoAuthPropertiesAsJson() {
+        val json: String = "{\n" +
+                "  \"type\" : \"ssl-basic-auth\",\n" +
+                "  \"url\" : \"https://localhost:8443\",\n" +
+                "  \"keyStoreInstance\" : \"PKCS12\",\n" +
+                "  \"sslTrust\" : \"src/test/resources/keystore.p12\",\n" +
+                "  \"sslTrustPassword\" : \"changeit\",\n" +
+                "  \"sslKey\" : \"src/test/resources/keystore.p12\",\n" +
+                "  \"sslKeyPassword\" : \"changeit\"\n" +
+                "}"
+        val mapper = ObjectMapper()
+        val actualObj: JsonNode = mapper.readTree(json)
+        val properties = bluePrintRestLibPropertyService.restClientProperties(
+                actualObj)
+        assertNotNull(properties, "failed to create property bean")
+
+        val p: SSLRestClientProperties =
+                properties as SSLRestClientProperties
+
+        assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
+        assertEquals(p.sslTrustPassword, "changeit")
+        assertEquals(p.keyStoreInstance, "PKCS12")
+        assertEquals(p.sslKey, "src/test/resources/keystore.p12")
+        assertEquals(p.sslKeyPassword, "changeit")
     }
 
     @Test
     fun testBlueprintWebClientService() {
-        val blueprintWebClientService = bluePrintRestLibPropertyService.blueprintWebClientService("sample")
-        assertNotNull(blueprintWebClientService, "failed to create blueprintWebClientService")
+        val blueprintWebClientService = bluePrintRestLibPropertyService
+                .blueprintWebClientService("sample")
+        assertNotNull(blueprintWebClientService, "failed to create blu" +
+                "eprintWebClientService")
     }
 
 }
index a02a808..98cdfc0 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  * Copyright (C) 2019 Nordix Foundation
+ * Modifications Copyright © 2019 Huawei.
  *
  * 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.rest.service
 
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.ObjectMapper
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.async
+import kotlinx.coroutines.runBlocking
+import org.apache.catalina.connector.Connector
+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
@@ -25,57 +33,330 @@ import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
 import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
+import org.springframework.boot.web.servlet.server.ServletWebServerFactory
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
 import org.springframework.http.HttpMethod
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
+import org.springframework.security.config.annotation.web.builders.HttpSecurity
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+import org.springframework.security.crypto.password.PasswordEncoder
+import org.springframework.stereotype.Component
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
 import org.springframework.test.context.junit4.SpringRunner
+import org.springframework.web.bind.annotation.DeleteMapping
 import org.springframework.web.bind.annotation.GetMapping
 import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.PutMapping
+import org.springframework.web.bind.annotation.RequestHeader
 import org.springframework.web.bind.annotation.RequestMapping
 import org.springframework.web.bind.annotation.RestController
-import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
 @RunWith(SpringRunner::class)
 @EnableAutoConfiguration(exclude = [DataSourceAutoConfiguration::class])
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-@ContextConfiguration(classes = [BluePrintRestLibConfiguration::class, BlueprintPropertyConfiguration::class,
-    SampleController::class, BluePrintProperties::class, BluePrintProperties::class])
+@ContextConfiguration(classes = [BluePrintRestLibConfiguration::class,
+    BlueprintPropertyConfiguration::class,
+    SampleController::class, BluePrintProperties::class,
+    BluePrintProperties::class])
 @TestPropertySource(properties =
-["blueprintsprocessor.restclient.sample.type=basic-auth",
+[
+    "server.port=8443",
+    "server.ssl.enabled=true",
+    "server.ssl.key-store=classpath:keystore.p12",
+    "server.ssl.key-store-password=changeit",
+    "server.ssl.keyStoreType=PKCS12",
+    "server.ssl.keyAlias=tomcat",
+    "blueprintsprocessor.restclient.sample.type=basic-auth",
     "blueprintsprocessor.restclient.sample.url=http://127.0.0.1:8080",
-    "blueprintsprocessor.restclient.sample.username=sampleuser",
-    "blueprintsprocessor.restclient.sample.password=sampletoken"])
+    "blueprintsprocessor.restclient.sample.username=admin",
+    "blueprintsprocessor.restclient.sample.password=jans",
+    "blueprintsprocessor.restclient.test.type=ssl-basic-auth",
+    "blueprintsprocessor.restclient.test.url=https://localhost:8443",
+    "blueprintsprocessor.restclient.test.username=admin",
+    "blueprintsprocessor.restclient.test.password=jans",
+    "blueprintsprocessor.restclient.test.keyStoreInstance=PKCS12",
+    "blueprintsprocessor.restclient.test.sslTrust=src/test/resources/keystore.p12",
+    "blueprintsprocessor.restclient.test.sslTrustPassword=changeit"
+])
 class RestClientServiceTest {
 
     @Autowired
     lateinit var bluePrintRestLibPropertyService: BluePrintRestLibPropertyService
 
+    @Test
+    fun testPatch() {
+        val restClientService = bluePrintRestLibPropertyService
+                .blueprintWebClientService("sample")
+        val response = restClientService.exchangeResource(
+                HttpMethod.PATCH.name, "/sample/name", "")
+        assertEquals("Patch request successful", response,
+                "failed to get patch response")
+    }
+
     @Test
     fun testBaseAuth() {
-        val restClientService = bluePrintRestLibPropertyService.blueprintWebClientService("sample")
+        val restClientService = bluePrintRestLibPropertyService
+                .blueprintWebClientService("sample")
         val headers = mutableMapOf<String, String>()
         headers["X-Transaction-Id"] = "1234"
-        val response = restClientService.exchangeResource(HttpMethod.GET.name, "/sample/name", "")
+        val response = restClientService.exchangeResource(HttpMethod.GET.name,
+                "/sample/name", "")
         assertNotNull(response, "failed to get response")
     }
 
     @Test
-    fun testPatch() {
-        val restClientService = bluePrintRestLibPropertyService.blueprintWebClientService("sample")
-        val response = restClientService.exchangeResource(HttpMethod.PATCH.name, "/sample/name", "")
-        assertEquals("Patch request successful", response, "failed to get patch response")
+    fun testSimpleBasicAuth() {
+        val json: String = "{\n" +
+                "  \"type\" : \"basic-auth\",\n" +
+                "  \"url\" : \"http://localhost:8080\",\n" +
+                "  \"username\" : \"admin\",\n" +
+                "  \"password\" : \"jans\"\n" +
+                "}"
+        val mapper = ObjectMapper()
+        val actualObj: JsonNode = mapper.readTree(json)
+        val restClientService = bluePrintRestLibPropertyService
+                .blueprintWebClientService(actualObj)
+        lateinit var res:String
+        runBlocking {
+            val get = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.GET.name,
+                        "/sample/basic", "")}
+            get.start()
+            res = get.await()
+        }
+        assertNotNull(res, "failed to get response")
+        assertEquals(res, "Basic request arrived successfully")
     }
 
+    @Test
+    fun testSampleAaiReq() {
+        val restClientService = bluePrintRestLibPropertyService
+                .blueprintWebClientService("test")
+        val headers = mutableMapOf<String, String>()
+        headers["X-TransactionId"] = "9999"
+        headers["X-FromAppId"] = "AAI"
+        val post1 = "{\n" +
+                "  \"customer\": {\n" +
+                "    \"global-customer-id\": \"ONSDEMOBJHKCustomer\",\n" +
+                "    \"subscriber-name\": \"ONSDEMOBJHKCustomer\",\n" +
+                "    \"subscriber-type\": \"CUST\",\n" +
+                "    \"resource-version\": \"1552985011163\"\n" +
+                "  }\n" +
+                "}"
+        lateinit var res1: Customer
+        lateinit var res2: Customer
+        lateinit var res3: String
+        lateinit var res4: String
+        lateinit var res5: String
+        lateinit var res6: String
+        runBlocking {
+            val get1 = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.GET.name,
+                        "/sample/aai/v14/business/customers", "", headers,
+                        Customer::class.java)}
+
+            val get2 = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.GET.name,
+                        "/sample/aai/v14/business/customers", "", headers,
+                        Customer::class.java)}
+
+            val post = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.POST.name,
+                        "/sample/aai/v14/business/customers", post1, headers,
+                        String::class.java)}
+
+            val put = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.PUT.name,
+                        "/sample/aai/v14/business/customers", post1, headers,
+                        String::class.java)}
+
+            val patch = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.PATCH.name,
+                        "/sample/aai/v14/business/customers", post1, headers,
+                        String::class.java)}
+
+            val delete = async(start = CoroutineStart.LAZY) {
+                restClientService.exchangeNB(HttpMethod.DELETE.name,
+                        "/sample/aai/v14/business/customers", "", headers,
+                        String::class.java)}
+
+            get1.start()
+            get2.start()
+            post.start()
+            put.start()
+            patch.start()
+            delete.start()
+            res1 = get1.await()
+            res2 = get2.await()
+            res3 = post.await()
+            res4 = put.await()
+            res5 = patch.await()
+            res6 = delete.await()
+        }
+        assertNotNull(res1, "failed to get response")
+        assertNotNull(res2, "failed to get response")
+        assertEquals(res1.id, "ONSDEMOBJHKCustomer")
+        assertEquals(res1.name, "ONSDEMOBJHKCustomer")
+        assertEquals(res1.type, "CUST")
+        assertEquals(res1.resource, "1552985011163")
+        assertEquals(res2.id, "ONSDEMOBJHKCustomer")
+        assertEquals(res2.name, "ONSDEMOBJHKCustomer")
+        assertEquals(res2.type, "CUST")
+        assertEquals(res2.resource, "1552985011163")
+        assertEquals(res3, "The message is successfully posted")
+        assertEquals(res4, "The put request is success")
+        assertEquals(res5, "The patch request is success")
+        assertEquals(res6, "The message is successfully deleted")
+    }
 }
 
+/**
+ * Sample controller code for testing both http and https requests.
+ */
 @RestController
 @RequestMapping("/sample")
 open class SampleController {
+
     @GetMapping("/name")
     fun getName(): String = "Sample Controller"
+
     @PatchMapping("/name")
     fun patchName(): String = "Patch request successful"
+
+    @GetMapping("/basic")
+    fun getBasic(): String = "Basic request arrived successfully"
+
+
+    @GetMapping("/aai/v14/business/customers")
+    fun getAaiCustomers(
+            @RequestHeader(name = "X-TransactionId", required = true)
+            transId: String,
+            @RequestHeader(name = "X-FromAppId", required = true)
+            appId: String) : String {
+        if (transId != "9999" || appId != "AAI") {
+            return ""
+        }
+        return "{\n" +
+                "  \"id\": \"ONSDEMOBJHKCustomer\",\n" +
+                "  \"name\": \"ONSDEMOBJHKCustomer\",\n" +
+                "  \"type\": \"CUST\",\n" +
+                "  \"resource\": \"1552985011163\"\n" +
+                "}"
+    }
+
+    @PostMapping("/aai/v14/business/customers")
+    fun postAaiCustomers(
+            @RequestHeader(name = "X-TransactionId", required = true)
+            transId: String,
+            @RequestHeader(name = "X-FromAppId", required = true)
+            appId: String) : String {
+        if (transId != "9999" || appId != "AAI") {
+            return ""
+        }
+        return "The message is successfully posted"
+    }
+
+
+    @PutMapping("/aai/v14/business/customers")
+    fun putAaiCustomers(
+            @RequestHeader(name = "X-TransactionId", required = true)
+            transId: String,
+            @RequestHeader(name = "X-FromAppId", required = true)
+            appId: String) : String {
+        if (transId != "9999" || appId != "AAI") {
+            return ""
+        }
+        return "The put request is success"
+    }
+
+    @PatchMapping("/aai/v14/business/customers")
+    fun patchAaiCustomers(
+            @RequestHeader(name = "X-TransactionId", required = true)
+            transId: String,
+            @RequestHeader(name = "X-FromAppId", required = true)
+            appId: String) : String {
+        if (transId != "9999" || appId != "AAI") {
+            return ""
+        }
+        return "The patch request is success"
+    }
+
+    @DeleteMapping("/aai/v14/business/customers")
+    fun deleteAaiCustomers(
+            @RequestHeader(name = "X-TransactionId", required = true)
+            transId: String,
+            @RequestHeader(name = "X-FromAppId", required = true)
+            appId: String) : String {
+        if (transId != "9999" || appId != "AAI") {
+            return ""
+        }
+        return "The message is successfully deleted"
+    }
 }
 
+/**
+ * Security configuration required for basic authentication with username and
+ * password for any request in the server.
+ */
+@Configuration
+@EnableWebSecurity
+open class SecurityConfig : WebSecurityConfigurerAdapter() {
+
+    @Throws(Exception::class)
+    override fun configure(http: HttpSecurity) {
+        http
+                .csrf().disable()
+                .authorizeRequests().anyRequest().authenticated()
+                .and()
+                .httpBasic()
+    }
+
+    @Autowired
+    @Throws(Exception::class)
+    open fun configureGlobal(auth: AuthenticationManagerBuilder) {
+        auth.inMemoryAuthentication()
+                .withUser("admin")
+                .password(passwordEncoder().encode("jans"))
+                .roles("USER")
+    }
+
+    @Bean
+    open fun passwordEncoder(): PasswordEncoder {
+        return BCryptPasswordEncoder()
+    }
+}
+
+/**
+ * Http server required for http request to be processed along with the https
+ * server.
+ */
+@Component
+class HttpServer {
+    @Bean
+    fun servletContainer(): ServletWebServerFactory {
+
+        val connector = Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL)
+        connector.setPort(8080)
+
+        val tomcat = TomcatServletWebServerFactory()
+        tomcat.addAdditionalTomcatConnectors(connector)
+        return tomcat
+    }
+}
+
+/**
+ * Data class required for response
+ */
+data class Customer(
+       val id: String,
+       val name: String,
+       val type: String,
+       val resource: String)
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/resources/keystore.p12 b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/resources/keystore.p12
new file mode 100644 (file)
index 0000000..96b0d3a
Binary files /dev/null and b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/resources/keystore.p12 differ