GH-3938: Fix HTTP XML configuration for ambiguity (#3939)

* GH-3938: Fix HTTP XML configuration for ambiguity

Fixes https://github.com/spring-projects/spring-integration/issues/3938

The `encoding-mode` is a property of the `RestTemplate`.
Therefore, it cannot be set on the component configuration together with
an externally injected `rest-template`

Even if `HttpRequestExecutingMessageHandler` has an assertion for such
an ambiguity, the XML parser just ignores this `encoding-mode`
when it encounters the `rest-template`

* Fix `HttpAdapterParsingUtils.verifyNoRestTemplateAttributes()` to check for not allowed
attributes with a `encoding-mode` as well
* Remove a `default` from the `encoding-mode` to not cause an ambiguity in the parser
* Fix some typos in the `spring-integration-http.xsd`
* Rework `OutboundResponseTypeTests` to JUnit 5

**Cherry-pick to `5.5.x`**

* * Fix error handling for `encoding-mode` in the `HttpAdapterParsingUtils`
* Cover `encoding-mode` and `rest-template` ambiguity with a test against failing XML configuration

* * Improve error message for ambiguous attributes in the `HttpAdapterParsingUtils`
This commit is contained in:
Artem Bilan
2022-11-07 15:47:19 -05:00
committed by GitHub
parent 0d8e286572
commit 053c86ab05
5 changed files with 89 additions and 71 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,9 +36,10 @@ import org.springframework.util.xml.DomUtils;
* @author Gary Russell
* @author Artem Bilan
* @author Shiliang Li
*
* @since 2.0.2
*/
abstract class HttpAdapterParsingUtils {
final class HttpAdapterParsingUtils {
static final String[] SYNC_REST_TEMPLATE_REFERENCE_ATTRIBUTES = {
"request-factory", "error-handler", "message-converters"
@@ -48,14 +49,22 @@ abstract class HttpAdapterParsingUtils {
for (String attributeName : SYNC_REST_TEMPLATE_REFERENCE_ATTRIBUTES) {
if (element.hasAttribute(attributeName)) {
parserContext.getReaderContext().error("When providing a 'rest-template' reference, the '"
+ attributeName + "' attribute is not allowed.",
+ attributeName + "' attribute is not allowed, " +
"it must be set on the provided template instead",
parserContext.extractSource(element));
}
}
if (element.hasAttribute("encoding-mode")) {
parserContext.getReaderContext().error("When providing a 'rest-template' reference, " +
"the 'encoding-mode' must be set on the 'RestTemplate.uriTemplateHandler' property.",
parserContext.extractSource(element));
}
}
static void configureUriVariableExpressions(BeanDefinitionBuilder builder, ParserContext parserContext,
Element element) {
String uriVariablesExpression = element.getAttribute("uri-variables-expression");
List<Element> uriVariableElements = DomUtils.getChildElementsByTagName(element, "uri-variable");
@@ -73,7 +82,7 @@ abstract class HttpAdapterParsingUtils {
}
if (hasUriVariableExpressions) {
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<String, Object>();
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<>();
for (Element uriVariableElement : uriVariableElements) {
String name = uriVariableElement.getAttribute("name");
String expression = uriVariableElement.getAttribute("expression");
@@ -146,8 +155,8 @@ abstract class HttpAdapterParsingUtils {
if (hasExpectedResponseType && hasExpectedResponseTypeExpression) {
parserContext.getReaderContext()
.error("The 'expected-response-type' and 'expected-response-type-expression' are mutually exclusive. " +
"You can only have one or the other", element);
.error("The 'expected-response-type' and 'expected-response-type-expression' " +
"are mutually exclusive. You can only have one or the other", element);
}
RootBeanDefinition expressionDef = null;
@@ -164,4 +173,7 @@ abstract class HttpAdapterParsingUtils {
}
}
private HttpAdapterParsingUtils() {
}
}

View File

@@ -73,8 +73,7 @@
By default 'status-code-expression' is null, meaning that the default '200 OK' response status
will be returned.
The 'http:inbound-gateway' resolves the 'status code' from the 'http_statusCode' header of the
reply
Message.
reply Message.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -412,7 +411,7 @@
<xsd:annotation>
<xsd:documentation>
Specify whether the outbound message's payload should be extracted
when preparing the request body. Otherwise the Message instance itself
when preparing the request body. Otherwise, the Message instance itself
will be serialized.
The default value is 'true'.
</xsd:documentation>
@@ -484,7 +483,7 @@
<xsd:annotation>
<xsd:documentation>
Specifies whether the outbound message's payload should be extracted
when preparing the request body. Otherwise the Message instance itself
when preparing the request body. Otherwise, the Message instance itself
will be serialized.
The default value is 'true'.
</xsd:documentation>
@@ -493,8 +492,8 @@
<xsd:attribute name="transfer-cookies" type="xsd:string" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
When set to "true", if a response contains a 'Set-Cookie' header, it will be mapped to a 'Cookie' header. This enables simple
cookie handling where subsequent HTTP interactions in the same message flow can use a cookie
When set to "true", if a response contains a 'Set-Cookie' header, it will be mapped to a 'Cookie' header.
This enables simple cookie handling where subsequent HTTP interactions in the same message flow can use a cookie
supplied by the server. Default is "false".
]]></xsd:documentation>
</xsd:annotation>
@@ -602,7 +601,8 @@
<xsd:complexType name="headerType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Expression to be evaluated against the ServletRequest(makes BODY and Headers available) as well as URI Variables (e.g., foo/bar/{id}).
Expression to be evaluated against the ServletRequest(makes BODY and Headers available)
as well as URI Variables (e.g., foo/bar/{id}).
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" use="required">
@@ -759,7 +759,7 @@
<xsd:attribute name="allow-credentials" default="true">
<xsd:annotation>
<xsd:documentation>
Set to "true" if the the browser should include any cookies associated to the domain
Set to "true" if the browser should include any cookies associated to the domain
of the request being annotated, or "false" if it should not. Empty string "" means undefined.
If true, the pre-flight response will include the header
'Access-Control-Allow-Credentials=true'. Default value is "true".
@@ -826,7 +826,7 @@
<xsd:annotation>
<xsd:documentation>
Provide a reference to a list of HttpMessageConverter instances. If specified,
these converters will replace all of the default converters that would normally
these converters will replace all default converters that would normally
be present on the underlying RestTemplate.
</xsd:documentation>
</xsd:annotation>
@@ -852,10 +852,11 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="encoding-mode" default="TEMPLATE_AND_VALUES">
<xsd:attribute name="encoding-mode">
<xsd:annotation>
<xsd:documentation>
Set the encoding mode during URI building.
Defaults to 'TEMPLATE_AND_VALUES'
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -948,7 +949,7 @@
<xsd:attribute name="uri-variables-expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the SpEL expression to be evaluate as a Map for URI variable placeholders within 'url'.
Specifies the SpEL expression to be evaluated as a Map for URI variable placeholders within 'url'.
This attribute is mutually exclusive with 'uri-variable' sub-elements.
]]></xsd:documentation>
</xsd:annotation>