From a091ede73456cdbba02b0a4cc573cc7898543d0a Mon Sep 17 00:00:00 2001 From: ottero Date: Sun, 17 Mar 2019 19:38:32 +0000 Subject: Adding custom headers capability to REST client For YANG PATCH requests to ODL to work, they need to have a Content- type header of application/yang.patch+json and should not have Accept as application/json Current REST client inserts a default header to the requests with this content: Content-Type: application/json Accept: application/json The solution was to add the possibility of sending custom headers alon- gside the other parameters. Change-Id: I2cf0cd2ef7b87f4f5a246d427dffafe266cb33f7 Issue-ID: CCSDK-926 Signed-off-by: ottero --- .../rest/service/BasicAuthRestClientService.kt | 26 +++++++--- .../rest/service/BlueprintWebClientService.kt | 60 +++++++++++++++------- .../rest/service/DME2ProxyRestClientService.kt | 3 +- .../rest/service/SSLBasicAuthRestClientService.kt | 10 ++-- .../rest/service/TokenAuthRestClientService.kt | 23 ++++++--- .../rest/utils/WebClientUtils.kt | 2 +- .../rest/service/RestClientServiceTest.kt | 14 +++++ 7 files changed, 97 insertions(+), 41 deletions(-) (limited to 'ms/blueprintsprocessor/modules/commons') diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt index 0502f67c0..98a4fd58f 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BasicAuthRestClientService.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2019 AT&T, Bell Canada + * Copyright © 2017-2019 AT&T, Bell Canada, Nordix Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * 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. + * + * SPDX-License-Identifier: Apache-2.0 */ package org.onap.ccsdk.apps.blueprintsprocessor.rest.service @@ -26,21 +28,31 @@ import java.util.* class BasicAuthRestClientService(private val restClientProperties: BasicAuthRestClientProperties) : BlueprintWebClientService { - override fun headers(): Array { + override fun defaultHeaders(): Map { val encodedCredentials = setBasicAuth(restClientProperties.username, restClientProperties.password) - val params = arrayListOf() - params.add(BasicHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)) - params.add(BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)) - params.add(BasicHeader(HttpHeaders.AUTHORIZATION, "Basic $encodedCredentials")) - return params.toTypedArray() + return mapOf( + 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): Array { + val customHeaders: MutableMap = headers.toMutableMap() + if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) { + 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())) } + + } \ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BlueprintWebClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BlueprintWebClientService.kt index 9c2caad70..0629909ec 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BlueprintWebClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/BlueprintWebClientService.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2019 AT&T, Bell Canada + * Copyright © 2017-2019 AT&T, Bell Canada, Nordix Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,15 +12,14 @@ * 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. + * + * SPDX-License-Identifier: Apache-2.0 */ package org.onap.ccsdk.apps.blueprintsprocessor.rest.service import org.apache.commons.io.IOUtils -import org.apache.http.client.methods.HttpDelete -import org.apache.http.client.methods.HttpGet -import org.apache.http.client.methods.HttpPost -import org.apache.http.client.methods.HttpPut +import org.apache.http.client.methods.* import org.apache.http.entity.StringEntity import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients @@ -32,7 +31,7 @@ import java.nio.charset.Charset interface BlueprintWebClientService { - fun headers(): Array + fun defaultHeaders(): Map fun host(uri: String): String @@ -44,48 +43,73 @@ interface BlueprintWebClientService { } 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 { + val convertedHeaders: Array = convertToBasicHeaders(headers) return when (HttpMethod.resolve(methodType)) { - HttpMethod.DELETE -> delete(path) - HttpMethod.GET -> get(path) - HttpMethod.POST -> post(path, request) - HttpMethod.PUT -> put(path, request) + 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)") } } - fun delete(path: String): String { + fun convertToBasicHeaders(headers: Map): Array { + val convertedHeaders = Array(headers.size){ BasicHeader("","") } + var currentElement = 0 + for ((name, value) in headers) { + convertedHeaders[currentElement++] = BasicHeader(name, value) + } + return convertedHeaders + } + + fun delete(path: String, headers: Array): String { val httpDelete = HttpDelete(host(path)) - httpDelete.setHeaders(headers()) + httpDelete.setHeaders(headers) httpClient().execute(httpDelete).entity.content.use { return IOUtils.toString(it, Charset.defaultCharset()) } } - fun get(path: String): String { + fun get(path: String, headers: Array): String { val httpGet = HttpGet(host(path)) - httpGet.setHeaders(headers()) + httpGet.setHeaders(headers) httpClient().execute(httpGet).entity.content.use { return IOUtils.toString(it, Charset.defaultCharset()) } } - fun post(path: String, request: String): String { + fun post(path: String, request: String, headers: Array): String { val httpPost = HttpPost(host(path)) val entity = StringEntity(request) httpPost.entity = entity - httpPost.setHeaders(headers()) + httpPost.setHeaders(headers) httpClient().execute(httpPost).entity.content.use { return IOUtils.toString(it, Charset.defaultCharset()) } } - fun put(path: String, request: String): String { + fun put(path: String, request: String, headers: Array): String { val httpPut = HttpPut(host(path)) val entity = StringEntity(request) httpPut.entity = entity - httpPut.setHeaders(headers()) + httpPut.setHeaders(headers) httpClient().execute(httpPut).entity.content.use { return IOUtils.toString(it, Charset.defaultCharset()) } } + + fun patch(path: String, request: String, headers: Array): String { + val httpPatch = HttpPatch(host(path)) + val entity = StringEntity(request) + httpPatch.entity = entity + httpPatch.setHeaders(headers) + httpClient().execute(httpPatch).entity.content.use { + return IOUtils.toString(it, Charset.defaultCharset()) + } + } } \ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt index 2b2578a37..94e146d8b 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt @@ -16,11 +16,10 @@ package org.onap.ccsdk.apps.blueprintsprocessor.rest.service -import org.apache.http.message.BasicHeader import org.onap.ccsdk.apps.blueprintsprocessor.rest.RestClientProperties class DME2ProxyRestClientService(restClientProperties: RestClientProperties) : BlueprintWebClientService { - override fun headers(): Array { + override fun defaultHeaders(): Map { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt index dc2993d98..2bfacf417 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/SSLBasicAuthRestClientService.kt @@ -19,7 +19,6 @@ package org.onap.ccsdk.apps.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.apps.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties import org.onap.ccsdk.apps.blueprintsprocessor.rest.utils.WebClientUtils @@ -33,11 +32,10 @@ import java.security.cert.X509Certificate class SSLBasicAuthRestClientService(private val restClientProperties: SSLBasicAuthRestClientProperties) : BlueprintWebClientService { - override fun headers(): Array { - val params = arrayListOf() - params.add(BasicHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)) - params.add(BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)) - return params.toTypedArray() + override fun defaultHeaders(): Map { + return mapOf( + HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE) } override fun host(uri: String): String { diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt index 6e90957d1..d5dec3ae5 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/TokenAuthRestClientService.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Bell Canada + * Copyright © 2019 Bell Canada, Nordix Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * 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. + * + * SPDX-License-Identifier: Apache-2.0 */ package org.onap.ccsdk.apps.blueprintsprocessor.rest.service @@ -24,12 +26,19 @@ import org.springframework.http.MediaType class TokenAuthRestClientService(private val restClientProperties: TokenAuthRestClientProperties) : BlueprintWebClientService { - override fun headers(): Array { - val params = arrayListOf() - params.add(BasicHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)) - params.add(BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)) - params.add(BasicHeader(HttpHeaders.AUTHORIZATION, restClientProperties.token)) - return params.toTypedArray() + override fun defaultHeaders(): Map { + 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): Array { + val customHeaders: MutableMap = headers.toMutableMap() + if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) { + customHeaders[HttpHeaders.AUTHORIZATION] = restClientProperties.token!! + } + return super.convertToBasicHeaders(customHeaders) } override fun host(uri: String): String { diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/utils/WebClientUtils.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/utils/WebClientUtils.kt index d6167a87b..b9a014e35 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/utils/WebClientUtils.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/utils/WebClientUtils.kt @@ -30,6 +30,6 @@ class WebClientUtils { HttpRequestInterceptor { request, _ -> log.info("Rest request method(${request?.requestLine?.method}), url(${request?.requestLine?.uri})") } fun logResponse(): HttpResponseInterceptor = - HttpResponseInterceptor { response, _ -> log.info("Response status(${response.statusLine.statusCode})") } + HttpResponseInterceptor { response, _ -> log.info("Response status(${response.statusLine.statusCode} - ${response.statusLine.reasonPhrase})") } } } \ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/RestClientServiceTest.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/RestClientServiceTest.kt index 4fa82df22..0390550cc 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/RestClientServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/rest/service/RestClientServiceTest.kt @@ -1,5 +1,6 @@ /* * Copyright © 2017-2018 AT&T Intellectual Property. + * Copyright (C) 2019 Nordix Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +13,8 @@ * 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. + * + * SPDX-License-Identifier: Apache-2.0 */ package org.onap.ccsdk.apps.blueprintsprocessor.rest.service @@ -29,9 +32,11 @@ 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.GetMapping +import org.springframework.web.bind.annotation.PatchMapping 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) @@ -58,6 +63,13 @@ class RestClientServiceTest { 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") + } + } @RestController @@ -65,5 +77,7 @@ class RestClientServiceTest { open class SampleController { @GetMapping("/name") fun getName(): String = "Sample Controller" + @PatchMapping("/name") + fun patchName(): String = "Patch request successful" } -- cgit 1.2.3-korg