From 65789f2e7bcb5e4ca9d88edb9a37d1471ff60652 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 11 Jul 2024 11:03:37 +0200 Subject: [PATCH 1/3] fixed adding body condition and content-type creation --- .../rule/engine/rest/TbHttpClient.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) 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 1db9dd2fc5..1c02d882d0 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 @@ -31,6 +31,7 @@ import org.springframework.web.client.RestClientResponseException; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec; +import org.springframework.web.reactive.function.client.WebClientResponseException; import org.springframework.web.util.UriComponentsBuilder; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; @@ -43,11 +44,13 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import reactor.netty.http.client.HttpClient; +import reactor.netty.resources.ConnectionProvider; import reactor.netty.transport.ProxyProvider; import javax.net.ssl.SSLException; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.Base64; import java.util.List; import java.util.Map; @@ -57,6 +60,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; +import static io.netty.channel.ChannelOption.SO_KEEPALIVE; + @Data @Slf4j public class TbHttpClient { @@ -170,7 +175,7 @@ public class TbHttpClient { BiConsumer onFailure) { try { if (semaphore != null && !semaphore.tryAcquire(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS)) { - ctx.tellFailure(msg, new RuntimeException("Timeout during waiting for reply!")); + onFailure.accept(msg, new RuntimeException("Timeout during waiting for reply!")); return; } @@ -183,10 +188,10 @@ public class TbHttpClient { .uri(uri) .headers(headers -> prepareHeaders(headers, msg)); - if (HttpMethod.POST.equals(method) || HttpMethod.PUT.equals(method) || - HttpMethod.PATCH.equals(method) || HttpMethod.DELETE.equals(method) || + if ((HttpMethod.POST.equals(method) || HttpMethod.PUT.equals(method) || + HttpMethod.PATCH.equals(method) || HttpMethod.DELETE.equals(method)) && !config.isIgnoreRequestBody()) { - request.body(BodyInserters.fromValue(getData(msg, config.isIgnoreRequestBody(), config.isParseToPlainText()))); + request.body(BodyInserters.fromValue(getData(msg, config.isParseToPlainText()))); } request @@ -236,11 +241,9 @@ public class TbHttpClient { return uri; } - private String getData(TbMsg tbMsg, boolean ignoreBody, boolean parseToPlainText) { - if (!ignoreBody && parseToPlainText) { - return JacksonUtil.toPlainText(tbMsg.getData()); - } - return tbMsg.getData(); + private Object getData(TbMsg tbMsg, boolean parseToPlainText) { + String data = tbMsg.getData(); + return parseToPlainText ? JacksonUtil.toPlainText(data) : JacksonUtil.toJsonNode(data); } private TbMsg processResponse(TbContext ctx, TbMsg origMsg, ResponseEntity response) { @@ -283,10 +286,9 @@ public class TbHttpClient { private TbMsg processException(TbMsg origMsg, Throwable e) { TbMsgMetaData metaData = origMsg.getMetaData(); metaData.putValue(ERROR, e.getClass() + ": " + e.getMessage()); - if (e instanceof RestClientResponseException) { - RestClientResponseException restClientResponseException = (RestClientResponseException) e; + if (e instanceof WebClientResponseException restClientResponseException) { metaData.putValue(STATUS, restClientResponseException.getStatusText()); - metaData.putValue(STATUS_CODE, restClientResponseException.getRawStatusCode() + ""); + metaData.putValue(STATUS_CODE, restClientResponseException.getStatusCode().value() + ""); metaData.putValue(ERROR_BODY, restClientResponseException.getResponseBodyAsString()); } return TbMsg.transformMsgMetadata(origMsg, metaData); From 58185d4a4c42bb8bfb363e467eaeb1c82afd1325 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 11 Jul 2024 11:23:03 +0200 Subject: [PATCH 2/3] hotfix Connection reset --- .../main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java | 1 + 1 file changed, 1 insertion(+) 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 1c02d882d0..24304f33b4 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 @@ -137,6 +137,7 @@ public class TbHttpClient { this.webClient = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) + .defaultHeader(HttpHeaders.CONNECTION, "close") //In previous realization this header was present! (Added for hotfix "Connection reset") .build(); } catch (SSLException e) { throw new TbNodeException(e); From 196ec5e59de33834c1d962a71eddd9c494395d07 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 11 Jul 2024 11:33:29 +0200 Subject: [PATCH 3/3] fixed tests --- .../java/org/thingsboard/rule/engine/rest/TbHttpClient.java | 5 ----- .../thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) 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 24304f33b4..26de3ad5e5 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 @@ -27,7 +27,6 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.web.client.RestClientResponseException; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec; @@ -44,13 +43,11 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import reactor.netty.http.client.HttpClient; -import reactor.netty.resources.ConnectionProvider; import reactor.netty.transport.ProxyProvider; import javax.net.ssl.SSLException; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.time.Duration; import java.util.Base64; import java.util.List; import java.util.Map; @@ -60,8 +57,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; -import static io.netty.channel.ChannelOption.SO_KEEPALIVE; - @Data @Slf4j public class TbHttpClient { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java index 98695c1570..fad0ae66da 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java @@ -165,7 +165,7 @@ public class TbRestApiCallNodeTest { try { assertEquals(path, request.getRequestLine().getUri(), "Request path matches"); assertTrue(request.containsHeader("Content-Type"), "Content-Type included"); - assertEquals("text/plain;charset=UTF-8", + assertEquals("application/json", request.getFirstHeader("Content-Type").getValue(), "Content-Type value"); assertTrue(request.containsHeader("Content-Length"), "Content-Length included"); assertEquals("2",