From fe521ab3fc62a2dc66bda6710885b8160daf21c1 Mon Sep 17 00:00:00 2001 From: "Muthuramalingam, Brinda Santh" Date: Tue, 26 Mar 2019 16:21:06 -0400 Subject: [PATCH] Improve Rest Service API Change-Id: I4addb046f5e20f36f0c5d810bc547b02a70d4c17 Issue-ID: CCSDK-1137 Signed-off-by: Muthuramalingam, Brinda Santh --- .../rest/service/BlueprintWebClientService.kt | 139 ++++++++++++++++++++- .../core/utils/JacksonUtils.kt | 10 +- 2 files changed, 145 insertions(+), 4 deletions(-) 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 94a575397..1c1d510fc 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 @@ -1,5 +1,6 @@ /* * Copyright © 2017-2019 AT&T, Bell Canada, Nordix Foundation + * Modifications Copyright © 2018-2019 IBM. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +17,9 @@ package org.onap.ccsdk.cds.blueprintsprocessor.rest.service +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.entity.StringEntity @@ -24,6 +28,7 @@ import org.apache.http.impl.client.HttpClients import org.apache.http.message.BasicHeader 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.nio.charset.Charset @@ -35,9 +40,9 @@ interface BlueprintWebClientService { fun httpClient(): CloseableHttpClient { return HttpClients.custom() - .addInterceptorFirst(WebClientUtils.logRequest()) - .addInterceptorLast(WebClientUtils.logResponse()) - .build() + .addInterceptorFirst(WebClientUtils.logRequest()) + .addInterceptorLast(WebClientUtils.logResponse()) + .build() } fun exchangeResource(methodType: String, path: String, request: String): String { @@ -105,4 +110,132 @@ interface BlueprintWebClientService { return IOUtils.toString(it, Charset.defaultCharset()) } } + + // 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 { + return getNB(path, additionalHeaders, String::class.java) + } + + suspend fun getNB(path: String, additionalHeaders: Map?, + responseType: Class): T = withContext(Dispatchers.IO) { + val httpGet = HttpGet(host(path)) + httpGet.setHeaders(basicHeaders(additionalHeaders)) + httpClientNB().execute(httpGet).entity.content.use { + JacksonUtils.readValue(it, responseType)!! + } + } + + suspend fun postNB(path: String, request: Any): String { + return postNB(path, request, null, String::class.java) + } + + suspend fun postNB(path: String, request: Any, additionalHeaders: Map?): String { + return postNB(path, request, additionalHeaders, String::class.java) + } + + suspend fun postNB(path: String, request: Any, additionalHeaders: Map?, + responseType: Class): 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)!! + } + } + + suspend fun putNB(path: String, request: Any): String { + return putNB(path, request, null, String::class.java) + } + + suspend fun putNB(path: String, request: Any, additionalHeaders: Map?): String { + return putNB(path, request, additionalHeaders, String::class.java) + } + + suspend fun putNB(path: String, request: Any, additionalHeaders: Map?, + responseType: Class): 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)!! + } + } + + suspend fun deleteNB(path: String): String { + return deleteNB(path, null, String::class.java) + } + + suspend fun deleteNB(path: String, additionalHeaders: Map?): String { + return deleteNB(path, additionalHeaders, String::class.java) + } + + suspend fun deleteNB(path: String, additionalHeaders: Map?, responseType: Class): T = + withContext(Dispatchers.IO) { + val httpDelete = HttpDelete(host(path)) + httpDelete.setHeaders(basicHeaders(additionalHeaders)) + httpClient().execute(httpDelete).entity.content.use { + JacksonUtils.readValue(it, responseType)!! + } + } + + suspend fun patchNB(path: String, request: Any, additionalHeaders: Map?, + responseType: Class): 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)!! + } + } + + 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 { + return exchangeNB(methodType, path, request, additionalHeaders, String::class.java) + } + + suspend fun exchangeNB(methodType: String, path: String, request: Any, additionalHeaders: Map?, + responseType: Class): T { + return when (HttpMethod.resolve(methodType)) { + HttpMethod.GET -> getNB(path, 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)") + } + } + + private fun strRequest(request: Any): String { + return when (request) { + is String -> request.toString() + is JsonNode -> request.toString() + else -> JacksonUtils.getJson(request) + } + } + + private fun basicHeaders(headers: Map?): Array { + val basicHeaders = mutableListOf() + defaultHeaders().forEach { name, value -> + basicHeaders.add(BasicHeader(name, value)) + } + headers?.forEach { name, value -> + basicHeaders.add(BasicHeader(name, value)) + } + return basicHeaders.toTypedArray() + } } \ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt index 7ac79e2f1..7b5f181da 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt @@ -1,6 +1,6 @@ /* * Copyright © 2017-2018 AT&T Intellectual Property. - * Modifications Copyright © 2018 IBM. + * Modifications Copyright © 2018-2019 IBM. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import kotlinx.coroutines.withContext import org.apache.commons.io.IOUtils import org.onap.ccsdk.cds.controllerblueprints.core.* import java.io.File +import java.io.InputStream import java.nio.charset.Charset /** @@ -42,10 +43,17 @@ class JacksonUtils { inline fun readValue(content: String): T = objectMapper.readValue(content, T::class.java) + inline fun readValue(stream: InputStream): T = + objectMapper.readValue(stream, T::class.java) + fun readValue(content: String, valueType: Class): T? { return objectMapper.readValue(content, valueType) } + fun readValue(stream: InputStream, valueType: Class): T? { + return objectMapper.readValue(stream, valueType) + } + fun readValue(node: JsonNode, valueType: Class): T? { return objectMapper.treeToValue(node, valueType) } -- 2.16.6