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 0d5a78810b..e9476157aa 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 @@ -217,7 +217,7 @@ public class TbHttpClient { String endpointUrl = TbNodeUtils.processPattern(config.getRestEndpointUrlPattern(), msg); List processedQueryParams; - if (config.isUseNewEncoding()) { + if (config.getQueryParams() != null) { processedQueryParams = config.getQueryParams().stream() .map(param -> { var processedParamName = TbNodeUtils.processPattern(param.name(), msg); @@ -312,9 +312,9 @@ public class TbHttpClient { queryParams.forEach(param -> builder.addParameter(param.name(), param.value())); return builder.build(); } catch (URISyntaxException e) { - throw new IllegalArgumentException(""" - Invalid request URL: '%s'. The URL must be valid and properly encoded. - If URL contains special characters (e.g., spaces), they must be percent-encoded (e.g., '/my file/' should be '/my%%20file/').""".formatted(endpointUrl), e); + throw new IllegalArgumentException( + "Invalid request URL: '" + endpointUrl + "'. The URL must be valid and properly encoded. " + + "If URL contains special characters (e.g., spaces), they must be percent-encoded (e.g., '/my device/' should be '/my%20device/').", e); } } @@ -327,10 +327,10 @@ public class TbHttpClient { * Pre-encoding the URL (e.g., {@code email=user%2Btag@test.com}) doesn't help * because {@code .encode()} will double-encode it to {@code email=user%252Btag@test.com}. *

- * Use {@link #buildEncodedUriNew} with a separate query params map, + * Use {@link #buildEncodedUriNew} with a separate query params list, * where values are encoded exactly once: {@code +} → {@code %2B}, {@code @} → {@code %40}. */ - @Deprecated(since = "4.2.1.2", forRemoval = true) // fixme: remove in major 5.0 + @Deprecated(since = "4.2.1.2", forRemoval = true) private URI buildEncodedUriLegacy(String endpointUrl) { return UriComponentsBuilder.fromUriString(endpointUrl).build().encode().toUri(); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeConfiguration.java index cd12eb5211..d319d15157 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeConfiguration.java @@ -15,10 +15,8 @@ */ package org.thingsboard.rule.engine.rest; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.validation.Valid; -import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotNull; import lombok.Data; import org.springframework.http.HttpHeaders; @@ -37,7 +35,6 @@ public class TbRestApiCallNodeConfiguration implements NodeConfiguration queryParams; private Map headers; private boolean useSimpleClientHttpFactory; @@ -55,31 +52,12 @@ public class TbRestApiCallNodeConfiguration implements NodeConfiguration new TbRestApiCallNode().init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)))) - .isInstanceOf(TbNodeException.class) - .hasRootCauseInstanceOf(DataValidationException.class) - .hasRootCauseMessage("'" + ruleNode.getName() + "' node configuration is invalid: query parameters must be null if old encoding is used") - .matches(e -> ((TbNodeException) e).isUnrecoverable()); - } - - @Test - public void shouldNotAllowNullQueryParamsIfNewEncodingIsUsed() { - // GIVEN - var config = new TbRestApiCallNodeConfiguration().defaultConfiguration(); - config.setUseNewEncoding(true); - config.setQueryParams(null); + var queryParams = new ArrayList(); + queryParams.add(new QueryParam("key", "value")); + queryParams.add(null); + config.setQueryParams(queryParams); // WHEN-THEN assertThatThrownBy(() -> new TbRestApiCallNode().init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)))) .isInstanceOf(TbNodeException.class) - .hasRootCauseInstanceOf(DataValidationException.class) - .hasRootCauseMessage("'" + ruleNode.getName() + "' node configuration is invalid: query parameters must be non-null if new encoding is used") - .matches(e -> ((TbNodeException) e).isUnrecoverable()); + .matches(e -> ((TbNodeException) e).isUnrecoverable()) + .rootCause() + .isInstanceOf(DataValidationException.class) + .hasMessageContaining("must not be null"); } @Test @@ -187,7 +174,6 @@ public class TbRestApiCallNodeTest extends AbstractRuleNodeUpgradeTest { var defaultConfig = new TbRestApiCallNodeConfiguration().defaultConfiguration(); // THEN - assertTrue(defaultConfig.isUseNewEncoding()); assertEquals(Collections.emptyList(), defaultConfig.getQueryParams()); } @@ -224,7 +210,6 @@ public class TbRestApiCallNodeTest extends AbstractRuleNodeUpgradeTest { var config = JacksonUtil.fromString(configJson, TbRestApiCallNodeConfiguration.class); // THEN - assertFalse(config.isUseNewEncoding()); assertNull(config.getQueryParams()); }