From d9774ccfda1a58256dbab72bd06203be0d012e08 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Wed, 7 Sep 2022 16:44:05 +0300 Subject: [PATCH] http client returns headers as array is there is more than one, put headers to metadata for failure response --- .../rule/engine/rest/TbHttpClient.java | 22 ++++++++++++++++++- .../rule/engine/rest/TbHttpClientTest.java | 22 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 58bb5c7564..b7414c5e0d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -41,6 +41,7 @@ import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.web.client.AsyncRestTemplate; import org.springframework.web.client.RestClientResponseException; import org.springframework.web.util.UriComponentsBuilder; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbRelationTypes; @@ -59,8 +60,11 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.util.Deque; +import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; @Data @Slf4j @@ -244,17 +248,33 @@ public class TbHttpClient { metaData.putValue(STATUS, response.getStatusCode().name()); metaData.putValue(STATUS_CODE, response.getStatusCode().value() + ""); metaData.putValue(STATUS_REASON, response.getStatusCode().getReasonPhrase()); - response.getHeaders().toSingleValueMap().forEach(metaData::putValue); + headersToMetaData(response.getHeaders(), metaData::putValue); String body = response.getBody() == null ? "{}" : response.getBody(); return ctx.transformMsg(origMsg, origMsg.getType(), origMsg.getOriginator(), metaData, body); } + void headersToMetaData(Map> headers, BiConsumer consumer) { + if (headers == null) { + return; + } + headers.forEach((key, values) -> { + if (values != null && !values.isEmpty()) { + if (values.size() == 1) { + consumer.accept(key, values.get(0)); + } else { + consumer.accept(key, JacksonUtil.toString(values)); + } + } + }); + } + private TbMsg processFailureResponse(TbContext ctx, TbMsg origMsg, ResponseEntity response) { TbMsgMetaData metaData = origMsg.getMetaData(); metaData.putValue(STATUS, response.getStatusCode().name()); metaData.putValue(STATUS_CODE, response.getStatusCode().value() + ""); metaData.putValue(STATUS_REASON, response.getStatusCode().getReasonPhrase()); metaData.putValue(ERROR_BODY, response.getBody()); + headersToMetaData(response.getHeaders(), metaData::putValue); return ctx.transformMsg(origMsg, origMsg.getType(), origMsg.getOriginator(), metaData, origMsg.getData()); } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java index f7a1d83ac9..28918538e2 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java @@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.rest; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import org.assertj.core.api.Assertions; import org.awaitility.Awaitility; import org.junit.After; import org.junit.Assert; @@ -26,6 +27,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockserver.integration.ClientAndServer; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.AsyncRestTemplate; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.server.common.data.id.DeviceId; @@ -34,6 +36,8 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import java.net.URI; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -200,5 +204,23 @@ public class TbHttpClientTest { ); } + @Test + public void testHeadersToMetaData() { + Map> headers = new LinkedMultiValueMap<>(); + headers.put("Content-Type", List.of("binary")); + headers.put("Set-Cookie", List.of("sap-context=sap-client=075; path=/", "sap-token=sap-client=075; path=/")); + + TbMsgMetaData metaData = new TbMsgMetaData(); + + willCallRealMethod().given(client).headersToMetaData(any(), any()); + + client.headersToMetaData(headers, metaData::putValue); + + Map data = metaData.getData(); + + Assertions.assertThat(data).hasSize(2); + Assertions.assertThat(data.get("Content-Type")).isEqualTo("binary"); + Assertions.assertThat(data.get("Set-Cookie")).isEqualTo("[\"sap-context=sap-client=075; path=/\",\"sap-token=sap-client=075; path=/\"]"); + } } \ No newline at end of file