diff options
author | Oleg Mitsura <oleg.mitsura@amdocs.com> | 2019-05-17 11:56:30 -0400 |
---|---|---|
committer | Oleg Mitsura <oleg.mitsura@amdocs.com> | 2019-09-08 17:15:14 -0400 |
commit | c4dce93368dd9ac437668506b9e53967fb55079a (patch) | |
tree | 62ade76e05e62627a343d4c6daeb5cae7ac89dd6 /ms | |
parent | ff853257afc3ba42059fad2453f51674a61248d2 (diff) |
HTTP headers feature for BP REST endpoints def'ns
Issue-ID: CCSDK-1341
Change-Id: I2da6a19ddea137c0fb868a413f77a45c1def3877
Signed-off-by: Oleg Mitsura <oleg.mitsura@amdocs.com>
Diffstat (limited to 'ms')
8 files changed, 491 insertions, 203 deletions
diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt index 75a9409fd..68672f227 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt @@ -1,6 +1,7 @@ /* * Copyright © 2017-2018 AT&T Intellectual Property. * Modifications Copyright © 2019 Huawei. + * Modifications Copyright © 2019 Bell Canada. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +21,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.rest open class RestClientProperties { lateinit var type: String lateinit var url: String + var additionalHeaders: Map<String, String>? = null } open class SSLRestClientProperties : RestClientProperties() { @@ -63,4 +65,4 @@ open class PolicyManagerRestClientProperties : RestClientProperties() { lateinit var env: String lateinit var clientAuth: String lateinit var authorisation: String -}
\ 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/BasicAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt index 3190cd1c6..bb6937d7c 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt @@ -18,6 +18,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.rest.service import org.apache.http.message.BasicHeader import org.onap.ccsdk.cds.blueprintsprocessor.rest.BasicAuthRestClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.rest.utils.WebClientUtils +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.springframework.http.HttpHeaders import org.springframework.http.MediaType import java.nio.charset.Charset @@ -25,42 +29,43 @@ import java.util.* class BasicAuthRestClientService(private val restClientProperties: BasicAuthRestClientProperties) : - BlueprintWebClientService { + BlueprintWebClientService { override fun defaultHeaders(): Map<String, String> { val encodedCredentials = setBasicAuth(restClientProperties.username, - restClientProperties.password) + restClientProperties.password) return mapOf( - HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, - HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE, - HttpHeaders.AUTHORIZATION to "Basic $encodedCredentials") + HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.AUTHORIZATION to "Basic $encodedCredentials") } override fun host(uri: String): String { 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() + //inject additionalHeaders + customHeaders.putAll(verifyAdditionalHeaders(restClientProperties)) + if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) { val encodedCredentials = setBasicAuth( - restClientProperties.username, - restClientProperties.password) + restClientProperties.username, + restClientProperties.password) customHeaders[HttpHeaders.AUTHORIZATION] = - "Basic $encodedCredentials" + "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())) + credentialsString.toByteArray(Charset.defaultCharset())) } - -}
\ 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/BluePrintRestLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt index 4f6865764..8d4f0ca63 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt @@ -38,7 +38,7 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: BluePrintProperties) { open fun blueprintWebClientService(jsonNode: JsonNode): - BlueprintWebClientService { + BlueprintWebClientService { val restClientProperties = restClientProperties(jsonNode) return blueprintWebClientService(restClientProperties) } @@ -51,7 +51,7 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: fun restClientProperties(prefix: String): RestClientProperties { val type = bluePrintProperties.propertyBeanType( - "$prefix.type", String::class.java) + "$prefix.type", String::class.java) return when (type) { RestLibConstants.TYPE_BASIC_AUTH -> { basicAuthRestClientProperties(prefix) @@ -76,7 +76,7 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: } else -> { throw BluePrintProcessorException("Rest adaptor($type) is" + - " not supported") + " not supported") } } } @@ -86,43 +86,35 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: 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)!! + 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)!! + JacksonUtils.readValue(jsonNode, SSLBasicAuthRestClientProperties::class.java)!! } RestLibConstants.TYPE_SSL_TOKEN_AUTH -> { - JacksonUtils.readValue(jsonNode, - SSLTokenAuthRestClientProperties::class.java)!! + JacksonUtils.readValue(jsonNode, SSLTokenAuthRestClientProperties::class.java)!! } RestLibConstants.TYPE_SSL_NO_AUTH -> { - JacksonUtils.readValue( - jsonNode, SSLRestClientProperties::class.java)!! + 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 -> { @@ -138,66 +130,65 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: return DME2ProxyRestClientService(restClientProperties) } else -> { - throw BluePrintProcessorException("couldn't get rest " + - "service for") + throw BluePrintProcessorException("couldn't get rest service for type:${restClientProperties.type} uri: ${restClientProperties.url}") } } } private fun tokenRestClientProperties(prefix: String): - TokenAuthRestClientProperties { + TokenAuthRestClientProperties { return bluePrintProperties.propertyBeanType( - prefix, TokenAuthRestClientProperties::class.java) + prefix, TokenAuthRestClientProperties::class.java) } private fun basicAuthRestClientProperties(prefix: String): - BasicAuthRestClientProperties { + BasicAuthRestClientProperties { return bluePrintProperties.propertyBeanType( - prefix, BasicAuthRestClientProperties::class.java) + prefix, BasicAuthRestClientProperties::class.java) } private fun sslBasicAuthRestClientProperties(prefix: String): - SSLRestClientProperties { + SSLRestClientProperties { val sslProps: SSLBasicAuthRestClientProperties = - bluePrintProperties.propertyBeanType( - prefix, SSLBasicAuthRestClientProperties::class.java) - val basicProps : BasicAuthRestClientProperties = - bluePrintProperties.propertyBeanType( - prefix, BasicAuthRestClientProperties::class.java) + 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 { + SSLRestClientProperties { val sslProps: SSLTokenAuthRestClientProperties = - bluePrintProperties.propertyBeanType(prefix, - SSLTokenAuthRestClientProperties::class.java) - val basicProps : TokenAuthRestClientProperties = - bluePrintProperties.propertyBeanType(prefix, - TokenAuthRestClientProperties::class.java) + bluePrintProperties.propertyBeanType(prefix, + SSLTokenAuthRestClientProperties::class.java) + val basicProps: TokenAuthRestClientProperties = + bluePrintProperties.propertyBeanType(prefix, + TokenAuthRestClientProperties::class.java) sslProps.tokenAuth = basicProps return sslProps } private fun sslNoAuthRestClientProperties(prefix: String): - SSLRestClientProperties { + SSLRestClientProperties { return bluePrintProperties.propertyBeanType( - prefix, SSLRestClientProperties::class.java) + prefix, SSLRestClientProperties::class.java) } private fun dme2ProxyClientProperties(prefix: String): - DME2RestClientProperties { + DME2RestClientProperties { return bluePrintProperties.propertyBeanType( - prefix, DME2RestClientProperties::class.java) + prefix, DME2RestClientProperties::class.java) } private fun policyManagerRestClientProperties(prefix: String): - PolicyManagerRestClientProperties { + PolicyManagerRestClientProperties { return bluePrintProperties.propertyBeanType( - prefix, PolicyManagerRestClientProperties::class.java) + prefix, PolicyManagerRestClientProperties::class.java) } } diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BlueprintWebClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BlueprintWebClientService.kt index 1acd07b7b..26c808874 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BlueprintWebClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BlueprintWebClientService.kt @@ -28,11 +28,14 @@ import org.apache.http.entity.StringEntity import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients import org.apache.http.message.BasicHeader +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestLibConstants import org.onap.ccsdk.cds.blueprintsprocessor.rest.utils.WebClientUtils import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintRetryException import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintIOUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.springframework.http.HttpHeaders import org.springframework.http.HttpMethod import java.io.IOException import java.io.InputStream @@ -46,9 +49,9 @@ interface BlueprintWebClientService { fun httpClient(): CloseableHttpClient { return HttpClients.custom() - .addInterceptorFirst(WebClientUtils.logRequest()) - .addInterceptorLast(WebClientUtils.logResponse()) - .build() + .addInterceptorFirst(WebClientUtils.logRequest()) + .addInterceptorLast(WebClientUtils.logResponse()) + .build() } /** High performance non blocking Retry function, If execution block [block] throws BluePrintRetryException @@ -82,10 +85,12 @@ interface BlueprintWebClientService { HttpMethod.POST -> post(path, request, convertedHeaders, String::class.java) HttpMethod.PUT -> put(path, request, convertedHeaders, String::class.java) HttpMethod.PATCH -> patch(path, request, convertedHeaders, String::class.java) - else -> throw BluePrintProcessorException("Unsupported methodType($methodType)") + else -> throw BluePrintProcessorException( + "Unsupported methodType($methodType) attempted on path($path)") } } + //TODO: convert to multi-map fun convertToBasicHeaders(headers: Map<String, String>): Array<BasicHeader> { return headers.map { BasicHeader(it.key, it.value) }.toTypedArray() } @@ -135,8 +140,8 @@ interface BlueprintWebClientService { @Throws(IOException::class, ClientProtocolException::class) private fun <T> performCallAndExtractTypedWebClientResponse( - httpUriRequest: HttpUriRequest, responseType: Class<T>): - WebClientResponse<T> { + httpUriRequest: HttpUriRequest, responseType: Class<T>): + WebClientResponse<T> { val httpResponse = httpClient().execute(httpUriRequest) val statusCode = httpResponse.statusLine.statusCode httpResponse.entity.content.use { @@ -154,7 +159,7 @@ interface BlueprintWebClientService { } suspend fun <T> getNB(path: String, additionalHeaders: Array<BasicHeader>?, responseType: Class<T>): - WebClientResponse<T> = withContext(Dispatchers.IO) { + WebClientResponse<T> = withContext(Dispatchers.IO) { get(path, additionalHeaders!!, responseType) } @@ -191,27 +196,27 @@ interface BlueprintWebClientService { } suspend fun <T> deleteNB(path: String, additionalHeaders: Array<BasicHeader>?): - WebClientResponse<String> { + WebClientResponse<String> { return deleteNB(path, additionalHeaders, String::class.java) } suspend fun <T> deleteNB(path: String, additionalHeaders: Array<BasicHeader>?, responseType: Class<T>): - WebClientResponse<T> = withContext(Dispatchers.IO) { + WebClientResponse<T> = withContext(Dispatchers.IO) { delete(path, additionalHeaders!!, responseType) } suspend fun <T> patchNB(path: String, request: Any, additionalHeaders: Array<BasicHeader>?, responseType: Class<T>): - WebClientResponse<T> = withContext(Dispatchers.IO) { + WebClientResponse<T> = withContext(Dispatchers.IO) { patch(path, request, additionalHeaders!!, responseType) } suspend fun exchangeNB(methodType: String, path: String, request: Any): WebClientResponse<String> { return exchangeNB(methodType, path, request, hashMapOf(), - String::class.java) + String::class.java) } suspend fun exchangeNB(methodType: String, path: String, request: Any, additionalHeaders: Map<String, String>?): - WebClientResponse<String> { + WebClientResponse<String> { return exchangeNB(methodType, path, request, additionalHeaders, String::class.java) } @@ -249,7 +254,7 @@ interface BlueprintWebClientService { } private fun basicHeaders(headers: Map<String, String>?): - Array<BasicHeader> { + Array<BasicHeader> { val basicHeaders = mutableListOf<BasicHeader>() defaultHeaders().forEach { (name, value) -> basicHeaders.add(BasicHeader(name, value)) @@ -263,11 +268,29 @@ interface BlueprintWebClientService { // Non Blocking Rest Implementation suspend fun httpClientNB(): CloseableHttpClient { return HttpClients.custom() - .addInterceptorFirst(WebClientUtils.logRequest()) - .addInterceptorLast(WebClientUtils.logResponse()) - .build() + .addInterceptorFirst(WebClientUtils.logRequest()) + .addInterceptorLast(WebClientUtils.logResponse()) + .build() } //TODO maybe there could be cases where we care about return headers? data class WebClientResponse<T>(val status: Int, val body: T) + + fun verifyAdditionalHeaders(restClientProperties: RestClientProperties): Map<String, String> { + val customHeaders: MutableMap<String, String> = mutableMapOf() + //Extract additionalHeaders from the requestProperties and + //throw an error if HttpHeaders.AUTHORIZATION key (headers are case-insensitive) + restClientProperties.additionalHeaders?.let { + if (it.keys.map { k -> k.toLowerCase().trim() }.contains(HttpHeaders.AUTHORIZATION.toLowerCase())) { + val errMsg = "Error in definition of endpoint ${restClientProperties.url}." + + " User-supplied \"additionalHeaders\" cannot contain AUTHORIZATION header with" + + " auth-type \"${RestLibConstants.TYPE_BASIC_AUTH}\"" + WebClientUtils.log.error(errMsg) + throw BluePrintProcessorException(errMsg) + } else { + customHeaders.putAll(it) + } + } + return customHeaders + } } 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 index 30dd49018..2acf776ca 100644 --- 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 @@ -33,25 +33,31 @@ import java.io.FileInputStream import java.security.KeyStore import java.security.cert.X509Certificate -class SSLRestClientService(private val restClientProperties: - SSLRestClientProperties) : - BlueprintWebClientService { +class SSLRestClientService(private val restClientProperties: SSLRestClientProperties) : + BlueprintWebClientService { var auth: BlueprintWebClientService? = null init { - auth = getAuthService() + auth = getAuthService() } - private fun getAuthService() : BlueprintWebClientService? { - - return when(restClientProperties) { + private fun getAuthService(): BlueprintWebClientService? { + //type,url and additional headers don't get carried over to TokenAuthRestClientProperties from SSLTokenAuthRestClientProperties + //set them in auth obj to be consistent. TODO: refactor + return when (restClientProperties) { is SSLBasicAuthRestClientProperties -> { - val basic = restClientProperties.basicAuth!! - BasicAuthRestClientService(basic) + val basicAuthProps = restClientProperties.basicAuth!! + basicAuthProps.additionalHeaders = restClientProperties.additionalHeaders + basicAuthProps.url = restClientProperties.url + basicAuthProps.type = restClientProperties.type + BasicAuthRestClientService(basicAuthProps) } is SSLTokenAuthRestClientProperties -> { - val token = restClientProperties.tokenAuth!! + val token = restClientProperties.tokenAuth!! + token.additionalHeaders = restClientProperties.additionalHeaders + token.url = restClientProperties.url + token.type = restClientProperties.type TokenAuthRestClientService(token) } else -> { @@ -61,19 +67,16 @@ class SSLRestClientService(private val restClientProperties: } } - 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) + 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 } @@ -85,8 +88,9 @@ class SSLRestClientService(private val restClientProperties: val sslTrust = restClientProperties.sslTrust val sslTrustPwd = restClientProperties.sslTrustPassword - val acceptingTrustStrategy = { chain: Array<X509Certificate>, - authType: String -> true } + val acceptingTrustStrategy = { _: Array<X509Certificate>, _: String -> + true + } val sslContext = SSLContextBuilder.create() if (sslKey != null && sslKeyPwd != null) { @@ -98,13 +102,12 @@ class SSLRestClientService(private val restClientProperties: } sslContext.loadTrustMaterial(File(sslTrust), sslTrustPwd.toCharArray(), - acceptingTrustStrategy) + acceptingTrustStrategy) val csf = SSLConnectionSocketFactory(sslContext.build()) return HttpClients.custom() - .addInterceptorFirst(WebClientUtils.logRequest()) - .addInterceptorLast(WebClientUtils.logResponse()) - .setSSLSocketFactory(csf).build() - + .addInterceptorFirst(WebClientUtils.logRequest()) + .addInterceptorLast(WebClientUtils.logResponse()) + .setSSLSocketFactory(csf).build() } // Non Blocking Rest Implementation @@ -113,13 +116,15 @@ class SSLRestClientService(private val restClientProperties: } 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) + val mergedDefaultAndSuppliedHeaders = defaultHeaders().plus(headers) + //During the initialization, getAuthService() sets the auth variable. + //If it's not null, then we have an authentication mechanism. + //If null - indicates no-auth used if (auth != null) { - return auth!!.convertToBasicHeaders(head2) + return auth!!.convertToBasicHeaders(mergedDefaultAndSuppliedHeaders) } - return super.convertToBasicHeaders(head2) + //inject additionalHeaders + return super.convertToBasicHeaders(mergedDefaultAndSuppliedHeaders + .plus(verifyAdditionalHeaders(restClientProperties))) } - -}
\ 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/TokenAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt index 82446994c..73b534143 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt @@ -23,20 +23,20 @@ import org.springframework.http.MediaType class TokenAuthRestClientService(private val restClientProperties: TokenAuthRestClientProperties) : - BlueprintWebClientService { + 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!!) + 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> { - + Array<BasicHeader> { val customHeaders: MutableMap<String, String> = headers.toMutableMap() + //inject additionalHeaders + customHeaders.putAll(verifyAdditionalHeaders(restClientProperties)) if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) { customHeaders[HttpHeaders.AUTHORIZATION] = restClientProperties.token!! } diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyServiceTest.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyServiceTest.kt index 37a797f78..b617dab90 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyServiceTest.kt @@ -2,6 +2,7 @@ * Copyright © 2017-2018 AT&T Intellectual Property. * Modifications Copyright © 2018 IBM. * Modifications Copyright © 2019 Huawei. + * Modifications Copyright © 2019 Bell Canada. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,11 +29,15 @@ 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.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType 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.assertFailsWith import kotlin.test.assertNotNull @RunWith(SpringRunner::class) @@ -63,26 +68,25 @@ import kotlin.test.assertNotNull "blueprintsprocessor.restclient.ssl.sslKeyPassword=changeit" ]) class BluePrintRestLibPropertyServiceTest { - @Autowired lateinit var bluePrintRestLibPropertyService: BluePrintRestLibPropertyService @Test fun testRestClientProperties() { val properties = bluePrintRestLibPropertyService.restClientProperties( - "blueprintsprocessor.restclient.sample") + "blueprintsprocessor.restclient.sample") assertNotNull(properties, "failed to create property bean") assertNotNull(properties.url, "failed to get url property in" + - " property bean") + " property bean") } @Test fun testSSLBasicProperties() { val properties = bluePrintRestLibPropertyService.restClientProperties( - "blueprintsprocessor.restclient.sslbasic") + "blueprintsprocessor.restclient.sslbasic") assertNotNull(properties, "failed to create property bean") val p: SSLBasicAuthRestClientProperties = - properties as SSLBasicAuthRestClientProperties + properties as SSLBasicAuthRestClientProperties assertEquals(p.basicAuth!!.username, "admin") assertEquals(p.basicAuth!!.password, "cds") @@ -94,11 +98,11 @@ class BluePrintRestLibPropertyServiceTest { @Test fun testSSLTokenProperties() { val properties = bluePrintRestLibPropertyService.restClientProperties( - "blueprintsprocessor.restclient.ssltoken") + "blueprintsprocessor.restclient.ssltoken") assertNotNull(properties, "failed to create property bean") val p: SSLTokenAuthRestClientProperties = - properties as SSLTokenAuthRestClientProperties + properties as SSLTokenAuthRestClientProperties assertEquals(p.tokenAuth!!.token!!, "72178473kjshdkjgvbsdkjv903274908") assertEquals(p.sslTrust, "src/test/resources/keystore.p12") @@ -109,11 +113,11 @@ class BluePrintRestLibPropertyServiceTest { @Test fun testSSLNoAuthProperties() { val properties = bluePrintRestLibPropertyService.restClientProperties( - "blueprintsprocessor.restclient.ssl") + "blueprintsprocessor.restclient.ssl") assertNotNull(properties, "failed to create property bean") val p: SSLRestClientProperties = - properties as SSLRestClientProperties + properties as SSLRestClientProperties assertEquals(p.sslTrust, "src/test/resources/keystore.p12") assertEquals(p.sslTrustPassword, "changeit") @@ -125,113 +129,370 @@ class BluePrintRestLibPropertyServiceTest { @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 actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField()) val properties = bluePrintRestLibPropertyService.restClientProperties( - actualObj) + actualObj) assertNotNull(properties, "failed to create property bean") - val p: SSLBasicAuthRestClientProperties = - properties as SSLBasicAuthRestClientProperties + 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") + assertEquals("admin", p.basicAuth!!.username) + assertEquals("cds", p.basicAuth!!.password) + assertEquals("src/test/resources/keystore.p12", p.sslTrust) + assertEquals("changeit", p.sslTrustPassword) + assertEquals("PKCS12", p.keyStoreInstance) + assertEquals("ssl-basic-auth", p.type) + assertEquals("https://localhost:8443", p.url) } @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) + val actualObj: JsonNode = defaultMapper.readTree(sslTokenAuthEndpointWithHeadersField()) + val properties = + bluePrintRestLibPropertyService.restClientProperties(actualObj) assertNotNull(properties, "failed to create property bean") - val p: SSLTokenAuthRestClientProperties = - properties as SSLTokenAuthRestClientProperties + 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") + assertEquals("72178473kjshdkjgvbsdkjv903274908", p.tokenAuth!!.token!!) + assertEquals("src/test/resources/keystore.p12", p.sslTrust) + assertEquals("changeit", p.sslTrustPassword) + assertEquals("PKCS12", p.keyStoreInstance) + assertEquals("ssl-token-auth", p.type) + assertEquals("https://localhost:8443", p.url) } @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 actualObj: JsonNode = defaultMapper.readTree(sslNoAuthEndpointWithHeadersField()) val properties = bluePrintRestLibPropertyService.restClientProperties( - actualObj) + actualObj) assertNotNull(properties, "failed to create property bean") val p: SSLRestClientProperties = - properties as 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") + assertEquals("src/test/resources/keystore.p12", p.sslTrust) + assertEquals("changeit", p.sslTrustPassword) + assertEquals("PKCS12", p.keyStoreInstance) + assertEquals("src/test/resources/keystore.p12", p.sslKey) + assertEquals("changeit", p.sslKeyPassword) + assertEquals("ssl-no-auth", p.type) + assertEquals("https://localhost:8443", p.url) } @Test fun testBlueprintWebClientService() { val blueprintWebClientService = bluePrintRestLibPropertyService - .blueprintWebClientService("sample") - assertNotNull(blueprintWebClientService, "failed to create blu" + - "eprintWebClientService") + .blueprintWebClientService("sample") + assertNotNull(blueprintWebClientService, + "failed to create blueprintWebClientService") } @Test fun testBlueprintWebClientServiceWithJsonNode() { - 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 actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField()) val blueprintWebClientService = bluePrintRestLibPropertyService - .blueprintWebClientService(actualObj) - assertNotNull(blueprintWebClientService, "failed to create blu" + - "eprintWebClientService") + .blueprintWebClientService(actualObj) + assertNotNull(blueprintWebClientService, "failed to create blueprintWebClientService") + } + + //pass the result of $typeEndpointWithHeadersField() output with and without headers to compare. + private fun validateHeadersDidNotChangeWithEmptyAdditionalHeaders(noHeaders: String, withHeaders: String) { + val parsedObj: JsonNode = defaultMapper.readTree(noHeaders) + val bpWebClientService = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj) + val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf()) + + val parsedObjWithHeaders: JsonNode = defaultMapper.readTree(withHeaders) + val bpWebClientServiceWithHeaders = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObjWithHeaders) + val extractedHeadersWithAdditionalHeaders = bpWebClientServiceWithHeaders.convertToBasicHeaders(mapOf()) + //Array<BasicHeader<>> -> Map<String,String> + val headersMap = extractedHeaders.map { it.name to it.value }.toMap() + val additionalHeadersMap = extractedHeadersWithAdditionalHeaders.map { it.name to it.value }.toMap() + assertEquals(headersMap, additionalHeadersMap) + } + + @Test + fun `BasicAuth WebClientService with empty additionalHeaders does not modify headers`() { + val endPointJson = basicAuthEndpointWithHeadersField() + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(emptyAdditionalHeaders) + validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson) + } + + private fun acceptsOneAdditionalHeadersTest(endPointWithHeadersJson: String) { + val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson) + val bpWebClientService = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj) + val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf()) + assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count()) + } + + @Test + fun `BasicAuth WebClientService accepts one additionalHeaders`() { + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(oneAdditionalParameter) + acceptsOneAdditionalHeadersTest(endPointWithHeadersJson) + } + + private fun acceptsMultipleAdditionalHeaders(endPointWithHeadersJson: String) { + val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson) + val bpWebClientService = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj) + val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf()) + assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count()) + assertEquals(1, extractedHeaders.filter { it.name == "key2" }.count()) + assertEquals(1, extractedHeaders.filter { it.name == "key3" }.count()) + } + + @Test + fun `BasicAuth WebClientService accepts multiple additionalHeaders`() { + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(threeAdditionalHeaders) + acceptsMultipleAdditionalHeaders(endPointWithHeadersJson) + } + + private fun additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson: String) { + val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson) + val bpWebClientService = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj) + val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf()) + assertEquals(MediaType.APPLICATION_XML.toString(), + extractedHeaders.filter { it.name == HttpHeaders.CONTENT_TYPE }[0].value!!) + } + + @Test + fun `BasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() { + //default content type is application/json + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(contentTypeAdditionalHeader) + additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson) + } + + //called from within "assertFailsWith(exceptionClass = BluePrintProcessorException::class) {" + private fun attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson: String) { + val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson) + val bpWebClientService = + bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj) + bpWebClientService.convertToBasicHeaders(mapOf()) + } + + @Test + fun `BasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() { + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuth) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + //spec says headers are case insensitive... + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + } + + @Test + fun `TokenAuth WebClientService with empty additionalHeaders does not modify headers`() { + val endPointJson = sslTokenAuthEndpointWithHeadersField() + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(emptyAdditionalHeaders) + validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson) + } + + @Test + fun `TokenAuth WebClientService accepts one additionalHeaders`() { + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(oneAdditionalParameter) + acceptsOneAdditionalHeadersTest(endPointWithHeadersJson) + } + + @Test + fun `TokenAuth WebClientService accepts multiple additionalHeaders`() { + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(threeAdditionalHeaders) + acceptsMultipleAdditionalHeaders(endPointWithHeadersJson) + } + + @Test + fun `TokenAuth WebClientService additionalHeaders can overwrite default Content-Type`() { + //default content type is application/json + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(contentTypeAdditionalHeader) + additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson) + } + + @Test + fun `TokenAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() { + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuth) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + //spec says headers are case insensitive... + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + } + + //TESTS FOR SSL BASIC AUTH headers + @Test + fun `SSLBasicAuth WebClientService with empty additionalHeaders does not modify headers`() { + val endPointJson = sslBasicAuthEndpointWithHeadersField() + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(emptyAdditionalHeaders) + validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson) + } + + @Test + fun `SSLBasicAuth WebClientService accepts one additionalHeaders`() { + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(oneAdditionalParameter) + acceptsOneAdditionalHeadersTest(endPointWithHeadersJson) + } + + @Test + fun `SSLBasicAuth WebClientService accepts multiple additionalHeaders`() { + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(threeAdditionalHeaders) + acceptsMultipleAdditionalHeaders(endPointWithHeadersJson) + } + + @Test + fun `SSLBasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() { + //default content type is application/json + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(contentTypeAdditionalHeader) + additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson) + } + + @Test + fun `SSLBasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() { + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuth) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + //spec says headers are case insensitive... + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + } + + //SSL-NO-AUTH headers tests + @Test + fun `SSLNoAuth WebClientService with empty additionalHeaders does not modify headers`() { + val endPointJson = sslNoAuthEndpointWithHeadersField() + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(emptyAdditionalHeaders) + validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson) + } + + @Test + fun `SSLNoAuth WebClientService accepts one additionalHeaders`() { + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(oneAdditionalParameter) + acceptsOneAdditionalHeadersTest(endPointWithHeadersJson) + } + + @Test + fun `SSLNoAuth WebClientService accepts multiple additionalHeaders`() { + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(threeAdditionalHeaders) + acceptsMultipleAdditionalHeaders(endPointWithHeadersJson) + } + + @Test + fun `SSLNoAuth WebClientService additionalHeaders can overwrite default Content-Type`() { + //default content type is application/json + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(contentTypeAdditionalHeader) + additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson) + } + + @Test + fun `SSLNoAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() { + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuth) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + //spec says headers are case insensitive... + assertFailsWith(exceptionClass = BluePrintProcessorException::class) { + val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased) + attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson) + } + } + + companion object BluePrintRestLibPropertyServiceTest { + val defaultMapper = ObjectMapper() + val expectedTokenAuthDefaultHeaders = mapOf<String, String>( + "Content-Type" to "application/json", + "Accept" to "application/json", + "Authorization" to "72178473kjshdkjgvbsdkjv903274908") + + val endPointWithHeadersJsonWithBasicAuthHeader = basicAuthEndpointWithHeadersField(""", + "additionalHeaders" : { + "authorization": "Basic aGF2ZTphbmljZWRheQo=" + }""".trimIndent()) + + private fun sslTokenAuthEndpointWithHeadersField(headers: String = ""): String = + """{ + "type" : "ssl-token-auth", + "url" : "https://localhost:8443", + "keyStoreInstance" : "PKCS12", + "sslTrust" : "src/test/resources/keystore.p12", + "sslTrustPassword" : "changeit", + "tokenAuth" : { + "token" : "72178473kjshdkjgvbsdkjv903274908" + }$headers + } + """.trimIndent() + + private fun sslBasicAuthEndpointWithHeadersField(headers: String = ""): String = + """{ + "type" : "ssl-basic-auth", + "url" : "https://localhost:8443", + "keyStoreInstance" : "PKCS12", + "sslTrust" : "src/test/resources/keystore.p12", + "sslTrustPassword" : "changeit", + "basicAuth" : { + "username" : "admin", + "password" : "cds" + }$headers + }""".trimIndent() + + private fun sslNoAuthEndpointWithHeadersField(headers: String = ""): String = """{ + "type" : "ssl-no-auth", + "url" : "https://localhost:8443", + "keyStoreInstance" : "PKCS12", + "sslTrust" : "src/test/resources/keystore.p12", + "sslTrustPassword" : "changeit", + "sslKey" : "src/test/resources/keystore.p12", + "sslKeyPassword" : "changeit"$headers + }""".trimIndent() + + //Don't forget to supply "," as the first char to make valid JSON + private fun basicAuthEndpointWithHeadersField(headers: String = ""): String = + """{ + "type": "basic-auth", + "url": "http://127.0.0.1:8000", + "username": "user", + "password": "pass"$headers + }""".trimIndent() + + private val emptyAdditionalHeaders = """, + "additionalHeaders" : { + }""".trimIndent() + + private val oneAdditionalParameter = """, + "additionalHeaders" : { + "key1": "value1" + }""".trimIndent() + + private val threeAdditionalHeaders = """, + "additionalHeaders" : { + "key1": "value1", + "key2": "value2", + "key3": "value3" + }""".trimIndent() + + private val contentTypeAdditionalHeader = """, + "additionalHeaders" : { + "${HttpHeaders.CONTENT_TYPE}": "${MediaType.APPLICATION_XML}" + }""".trimIndent() + + private val additionalHeadersWithAuth = """, + "additionalHeaders" : { + "Authorization": "Basic aGF2ZTphbmljZWRheQo=" + }""".trimIndent() + + private val additionalHeadersWithAuthLowercased = """, + "additionalHeaders" : { + "authorization": "Basic aGF2ZTphbmljZWRheQo=" + }""".trimIndent() } } diff --git a/ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/validation/utils/PropertyAssignmentValidationUtils.kt b/ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/validation/utils/PropertyAssignmentValidationUtils.kt index 2ef70164a..d49348152 100644 --- a/ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/validation/utils/PropertyAssignmentValidationUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/validation/utils/PropertyAssignmentValidationUtils.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2019 Bell Canada. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +52,7 @@ open class PropertyAssignmentValidationUtils(private val bluePrintContext: BlueP properties: MutableMap<String, JsonNode>) { properties.forEach { propertyName, propertyAssignment -> val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName] - ?: throw BluePrintException("failed to get definition for the property ($propertyName)") + ?: throw BluePrintException("validatePropertyAssignments failed to get definition for the property ($propertyName)") validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment) @@ -91,7 +92,7 @@ open class PropertyAssignmentValidationUtils(private val bluePrintContext: BlueP } check(isValid) { - throw BluePrintException("property($propertyName) defined of type($propertyType) is not comptable with the value ($propertyAssignment)") + throw BluePrintException("property($propertyName) defined of type($propertyType) is not compatible with the value ($propertyAssignment)") } } |