/*
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.mapping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.springframework.integration.mapping.AbstractHeaderMapper.CompositeHeaderMatcher;
import org.springframework.integration.mapping.AbstractHeaderMapper.ContentBasedHeaderMatcher;
import org.springframework.integration.mapping.AbstractHeaderMapper.HeaderMatcher;
import org.springframework.integration.mapping.AbstractHeaderMapper.PatternBasedHeaderMatcher;
import org.springframework.integration.mapping.AbstractHeaderMapper.PrefixBasedMatcher;
import org.springframework.integration.mapping.AbstractHeaderMapper.SinglePatternBasedHeaderMatcher;
import org.springframework.messaging.MessageHeaders;
import org.springframework.util.StringUtils;
/**
* @author Stephane Nicoll
* @since 4.1
*/
public class HeaderMapperTests {
private final GenericTestHeaderMapper mapper = new GenericTestHeaderMapper();
@Test
public void toHeadersFromRequest() {
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = this.mapper.toHeadersFromRequest(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertEquals("request-123", attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertFalse(attributes.containsKey(GenericTestHeaders.REPLY_ONLY));
assertEquals("Wrong number of mapped header(s)", 2, attributes.size());
}
@Test
public void toHeadersFromRequestWithStar() {
this.mapper.setRequestHeaderNames("*");
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = this.mapper.toHeadersFromRequest(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertEquals("request-123", attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("bar", attributes.get("foo"));
assertEquals("Wrong number of mapped header(s)", 4, attributes.size());
}
@Test
public void toHeadersFromRequestWithCustomPatterns() {
this.mapper.setRequestHeaderNames("foo*", "generic_reply*");
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = this.mapper.toHeadersFromRequest(properties);
assertEquals(null, attributes.get(GenericTestHeaders.APP_ID));
assertEquals(null, attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("bar", attributes.get("foo"));
assertEquals("Wrong number of mapped header(s)", 2, attributes.size());
}
@Test
public void toHeadersFromRequestWithStandardRequestPattern() {
this.mapper.setRequestHeaderNames("foo*", GenericTestHeaderMapper.STANDARD_REQUEST_HEADER_NAME_PATTERN);
GenericTestProperties properties = createSimpleGenericTestProperties();
properties.setUserDefinedHeader("foo2", "bar");
properties.setUserDefinedHeader("something-else", "bar");
Map<String, Object> attributes = this.mapper.toHeadersFromRequest(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertEquals("request-123", attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertFalse(attributes.containsKey(GenericTestHeaders.REPLY_ONLY));
assertEquals("bar", attributes.get("foo"));
assertEquals("bar", attributes.get("foo2"));
assertEquals("Wrong number of mapped header(s)", 4, attributes.size());
}
@Test
public void toHeadersFromRequestWithOnlyStandardHeaders() {
this.mapper.setRequestHeaderNames(GenericTestHeaderMapper.STANDARD_REQUEST_HEADER_NAME_PATTERN);
GenericTestProperties properties = createSimpleGenericTestProperties();
properties.setUserDefinedHeader("foo2", "bar");
properties.setUserDefinedHeader("something-else", "bar");
Map<String, Object> attributes = this.mapper.toHeadersFromRequest(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertEquals("request-123", attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertFalse(attributes.containsKey(GenericTestHeaders.REPLY_ONLY));
assertEquals("Wrong number of mapped header(s)", 2, attributes.size());
}
@Test
public void toHeadersFromReply() {
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = this.mapper.toHeadersFromReply(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertFalse(attributes.containsKey(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("Wrong number of mapped header(s)", 2, attributes.size());
}
@Test
public void toHeadersFromReplyWithStar() {
this.mapper.setReplyHeaderNames("*");
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = this.mapper.toHeadersFromReply(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertEquals("request-123", attributes.get(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("bar", attributes.get("foo"));
assertEquals("Wrong number of mapped header(s)", 4, attributes.size());
}
@Test
public void toHeadersFromReplyWithStandardReplyPattern() {
this.mapper.setReplyHeaderNames("foo*", GenericTestHeaderMapper.STANDARD_REPLY_HEADER_NAME_PATTERN);
GenericTestProperties properties = createSimpleGenericTestProperties();
properties.setUserDefinedHeader("foo2", "bar");
properties.setUserDefinedHeader("something-else", "bar");
Map<String, Object> attributes = this.mapper.toHeadersFromReply(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertFalse(attributes.containsKey(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("bar", attributes.get("foo"));
assertEquals("bar", attributes.get("foo2"));
assertEquals("Wrong number of mapped header(s)", 4, attributes.size());
}
@Test
public void toHeadersFromReplyWithOnlyStandardReplyHeaders() {
this.mapper.setReplyHeaderNames(GenericTestHeaderMapper.STANDARD_REPLY_HEADER_NAME_PATTERN);
GenericTestProperties properties = createSimpleGenericTestProperties();
properties.setUserDefinedHeader("foo2", "bar");
properties.setUserDefinedHeader("something-else", "bar");
Map<String, Object> attributes = this.mapper.toHeadersFromReply(properties);
assertEquals("appId", attributes.get(GenericTestHeaders.APP_ID));
assertFalse(attributes.containsKey(GenericTestHeaders.REQUEST_ONLY));
assertEquals("reply-123", attributes.get(GenericTestHeaders.REPLY_ONLY));
assertEquals("Wrong number of mapped header(s)", 2, attributes.size());
}
@Test
public void customTransientHeaderNames() {
GenericTestHeaderMapper customMapper = new GenericTestHeaderMapper() {
@Override
protected Collection<String> getTransientHeaderNames() {
return Arrays.asList("foo", GenericTestHeaders.APP_ID);
}
};
GenericTestProperties properties = createSimpleGenericTestProperties();
Map<String, Object> attributes = customMapper.toHeadersFromReply(properties);
// foo custom header and app Id not mapped
assertFalse(attributes.containsKey(GenericTestHeaders.APP_ID));
assertFalse(attributes.containsKey("foo"));
assertEquals("Wrong number of mapped header(s)", 1, attributes.size());
}
private GenericTestProperties createSimpleGenericTestProperties() {
GenericTestProperties properties = new GenericTestProperties();
properties.setAppId("appId");
properties.setRequestOnly("request-123");
properties.setReplyOnly("reply-123");
properties.setUserDefinedHeader("foo", "bar");
return properties;
}
@Test
public void fromHeadersToRequest() {
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToRequest(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertEquals("request-456", properties.getRequestOnly());
assertNull(properties.getReplyOnly());
assertEquals(0, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToRequestWithStar() {
this.mapper.setRequestHeaderNames("*");
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToRequest(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertEquals("request-456", properties.getRequestOnly());
assertEquals("reply-456", properties.getReplyOnly());
assertEquals("bar", properties.getUserDefinedHeaders().get("foo"));
assertEquals(1, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToRequestWithStandardRequestPattern() {
this.mapper.setRequestHeaderNames("foo", GenericTestHeaderMapper.STANDARD_REQUEST_HEADER_NAME_PATTERN);
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToRequest(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertEquals("request-456", properties.getRequestOnly());
assertNull(properties.getReplyOnly());
assertEquals("bar", properties.getUserDefinedHeaders().get("foo"));
assertEquals(1, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToRequestWithStandardRequestPatternAndNegatives() {
this.mapper.setRequestHeaderNames("foo", "!foo", "bar", "!baz", "\\!qux", "!fiz*",
GenericTestHeaderMapper.STANDARD_REQUEST_HEADER_NAME_PATTERN);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put(GenericTestHeaders.APP_ID, "myAppId");
headers.put(GenericTestHeaders.REDELIVERED, true);
headers.put(GenericTestHeaders.REQUEST_ONLY, "request-456");
headers.put(GenericTestHeaders.REPLY_ONLY, "reply-456");
headers.put("foo", "foo");
headers.put("bar", "bar");
headers.put("baz", "baz");
headers.put("!qux", "qux");
headers.put("fizbuz", "fizbuz");
MessageHeaders messageHeaders = new MessageHeaders(headers);
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToRequest(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertEquals("request-456", properties.getRequestOnly());
assertNull(properties.getReplyOnly());
assertEquals("bar", properties.getUserDefinedHeaders().get("bar"));
assertEquals("qux", properties.getUserDefinedHeaders().get("!qux"));
assertEquals(2, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToReply() {
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToReply(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertNull(properties.getRequestOnly());
assertEquals("reply-456", properties.getReplyOnly());
assertEquals(0, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToReplyWithStar() {
this.mapper.setReplyHeaderNames("*");
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToReply(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertEquals("request-456", properties.getRequestOnly());
assertEquals("reply-456", properties.getReplyOnly());
assertEquals("bar", properties.getUserDefinedHeaders().get("foo"));
assertEquals(1, properties.getUserDefinedHeaders().size());
}
@Test
public void fromHeadersToReplyWithStandardReplyPattern() {
this.mapper.setReplyHeaderNames("foo", GenericTestHeaderMapper.STANDARD_REPLY_HEADER_NAME_PATTERN);
MessageHeaders messageHeaders = createSimpleMessageHeaders();
GenericTestProperties properties = new GenericTestProperties();
this.mapper.fromHeadersToReply(messageHeaders, properties);
assertEquals("myAppId", properties.getAppId());
assertNull(properties.getTransactionSize());
assertEquals(true, properties.getRedelivered());
assertNull(properties.getRequestOnly());
assertEquals("reply-456", properties.getReplyOnly());
assertEquals("bar", properties.getUserDefinedHeaders().get("foo"));
assertEquals(1, properties.getUserDefinedHeaders().size());
}
public MessageHeaders createSimpleMessageHeaders() {
Map<String, Object> headers = new HashMap<String, Object>();
headers.put(GenericTestHeaders.APP_ID, "myAppId");
headers.put(GenericTestHeaders.REDELIVERED, true);
headers.put(GenericTestHeaders.REQUEST_ONLY, "request-456");
headers.put(GenericTestHeaders.REPLY_ONLY, "reply-456");
headers.put("foo", "bar");
return new MessageHeaders(headers);
}
@Test
public void prefixHeaderPatternMatching() {
@SuppressWarnings("deprecation")
PatternBasedHeaderMatcher strategy =
new PatternBasedHeaderMatcher(Collections.singleton("fOo*"));
assertMapping(strategy, "foo", true);
assertMapping(strategy, "foo123", true);
assertMapping(strategy, "FoO", true);
assertMapping(strategy, "123foo", false);
assertMapping(strategy, "_foo", false);
}
@Test
public void suffixHeaderPatternMatching() {
@SuppressWarnings("deprecation")
PatternBasedHeaderMatcher strategy =
new PatternBasedHeaderMatcher(Collections.singleton("*fOo"));
assertMapping(strategy, "foo", true);
assertMapping(strategy, "123foo", true);
assertMapping(strategy, "FoO", true);
assertMapping(strategy, "foo123", false);
assertMapping(strategy, "foo_", false);
}
@Test
public void prefixSingleHeaderPatternMatching() {
SinglePatternBasedHeaderMatcher strategy =
new SinglePatternBasedHeaderMatcher("Foo*");
assertMapping(strategy, "foo", true);
assertMapping(strategy, "foo123", true);
assertMapping(strategy, "FoO", true);
assertMapping(strategy, "123foo", false);
assertMapping(strategy, "_foo", false);
}
@Test
public void suffixSingleHeaderPatternMatching() {
SinglePatternBasedHeaderMatcher strategy =
new SinglePatternBasedHeaderMatcher("*fOo");
assertMapping(strategy, "foo", true);
assertMapping(strategy, "123foo", true);
assertMapping(strategy, "FoO", true);
assertMapping(strategy, "foo123", false);
assertMapping(strategy, "foo_", false);
}
@Test
public void contentHeaderMatching() {
ContentBasedHeaderMatcher strategy =
new ContentBasedHeaderMatcher(true, Arrays.asList("foo", "bar"));
assertMapping(strategy, "foo", true);
assertMapping(strategy, "bar", true);
assertMapping(strategy, "FOO", true);
assertMapping(strategy, "somethingElse", false);
}
@Test
public void contentHeaderReverseMatching() {
ContentBasedHeaderMatcher strategy =
new ContentBasedHeaderMatcher(false, Arrays.asList("foo", "bar"));
assertMapping(strategy, "foo", false);
assertMapping(strategy, "bar", false);
assertMapping(strategy, "somethingElse", true);
assertMapping(strategy, "anything", true);
}
@Test
public void prefixHeaderMatching() {
PrefixBasedMatcher strategy = new PrefixBasedMatcher(true, "foo_");
assertMapping(strategy, "foo_", true);
assertMapping(strategy, "foo_ANYTHING", true);
assertMapping(strategy, "something_foo_", false);
assertMapping(strategy, "somethingElse", false);
}
@Test
public void prefixHeaderReverseMatching() {
PrefixBasedMatcher strategy = new PrefixBasedMatcher(false, "foo_");
assertMapping(strategy, "foo_", false);
assertMapping(strategy, "foo_ANYTHING", false);
assertMapping(strategy, "something_foo_", true);
assertMapping(strategy, "somethingElse", true);
}
@Test
public void compositeOneMatch() {
HeaderMatcher strategy = new CompositeHeaderMatcher(
new PrefixBasedMatcher(true, "foo_"),
new PrefixBasedMatcher(true, "bar_"));
assertMapping(strategy, "foo_ANYTHING", true);
assertMapping(strategy, "bar_ANYTHING", true);
assertMapping(strategy, "somethingElse", false);
}
protected void assertMapping(HeaderMatcher strategy, String candidate, boolean match) {
assertEquals("Wrong mapping result for " + candidate + "", match, strategy.matchHeader(candidate));
}
private static abstract class GenericTestHeaders {
public static final String PREFIX = "generic_";
public static final String APP_ID = PREFIX + "appId";
public static final String TRANSACTION_SIZE = PREFIX + "transactionSize";
public static final String REDELIVERED = PREFIX + "redelivered";
public static final String REQUEST_ONLY = PREFIX + "requestOnly";
public static final String REPLY_ONLY = PREFIX + "replyOnly";
}
private static class GenericTestHeaderMapper extends AbstractHeaderMapper<GenericTestProperties> {
GenericTestHeaderMapper() {
super(GenericTestHeaders.PREFIX,
Arrays.asList(GenericTestHeaders.APP_ID, GenericTestHeaders.TRANSACTION_SIZE,
GenericTestHeaders.REDELIVERED, GenericTestHeaders.REQUEST_ONLY),
Arrays.asList(GenericTestHeaders.APP_ID, GenericTestHeaders.TRANSACTION_SIZE,
GenericTestHeaders.REDELIVERED, GenericTestHeaders.REPLY_ONLY));
}
@Override
protected Map<String, Object> extractStandardHeaders(GenericTestProperties source) {
Map<String, Object> result = new HashMap<String, Object>();
if (StringUtils.hasText(source.getAppId())) {
result.put(GenericTestHeaders.APP_ID, source.getAppId());
}
if (source.getTransactionSize() != null) {
result.put(GenericTestHeaders.TRANSACTION_SIZE, source.getTransactionSize());
}
if (source.getRedelivered() != null) {
result.put(GenericTestHeaders.REDELIVERED, source.getRedelivered());
}
if (StringUtils.hasText(source.getRequestOnly())) {
result.put(GenericTestHeaders.REQUEST_ONLY, source.getRequestOnly());
}
if (StringUtils.hasText(source.getReplyOnly())) {
result.put(GenericTestHeaders.REPLY_ONLY, source.getReplyOnly());
}
return result;
}
@Override
protected Map<String, Object> extractUserDefinedHeaders(GenericTestProperties source) {
return source.getUserDefinedHeaders();
}
@Override
protected void populateStandardHeaders(Map<String, Object> headers, GenericTestProperties target) {
String appId = getHeaderIfAvailable(headers, GenericTestHeaders.APP_ID, String.class);
if (StringUtils.hasText(appId)) {
target.setAppId(appId);
}
Integer transactionSize = getHeaderIfAvailable(headers, GenericTestHeaders.TRANSACTION_SIZE, Integer.class);
if (transactionSize != null) {
target.setTransactionSize(transactionSize);
}
Boolean redelivered = getHeaderIfAvailable(headers, GenericTestHeaders.REDELIVERED, Boolean.class);
if (redelivered != null) {
target.setRedelivered(redelivered);
}
String requestOnly = getHeaderIfAvailable(headers, GenericTestHeaders.REQUEST_ONLY, String.class);
if (StringUtils.hasText(requestOnly)) {
target.setRequestOnly(requestOnly);
}
String replyOnly = getHeaderIfAvailable(headers, GenericTestHeaders.REPLY_ONLY, String.class);
if (StringUtils.hasText(replyOnly)) {
target.setReplyOnly(replyOnly);
}
}
@Override
protected void populateUserDefinedHeader(String headerName, Object headerValue, GenericTestProperties target) {
target.setUserDefinedHeader(headerName, headerValue);
}
}
private static class GenericTestProperties {
private String appId;
private Integer transactionSize;
private Boolean redelivered;
private String requestOnly;
private String replyOnly;
private final Map<String, Object> userDefinedHeaders = new HashMap<String, Object>();
GenericTestProperties() {
super();
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public Integer getTransactionSize() {
return transactionSize;
}
public void setTransactionSize(Integer transactionSize) {
this.transactionSize = transactionSize;
}
public Boolean getRedelivered() {
return redelivered;
}
public void setRedelivered(boolean redelivered) {
this.redelivered = redelivered;
}
public String getRequestOnly() {
return requestOnly;
}
public void setRequestOnly(String requestOnly) {
this.requestOnly = requestOnly;
}
public String getReplyOnly() {
return replyOnly;
}
public void setReplyOnly(String replyOnly) {
this.replyOnly = replyOnly;
}
public Map<String, Object> getUserDefinedHeaders() {
return userDefinedHeaders;
}
public void setUserDefinedHeader(String name, Object value) {
this.userDefinedHeaders.put(name, value);
}
}
}