INT-4284: Exception to overwrite id or timestamp
JIRA: https://jira.spring.io/browse/INT-4284 To inform end-user that he/she can't override `id` and `timestamp` headers throw a `BeanInitializationException` from the `gateway`, `header-enricher`, `enricher` and `header-filter` configuration when `id` and `timestamp` are explicitly provided
This commit is contained in:
committed by
Gary Russell
parent
99224f54c0
commit
4a47a7ce45
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.springframework.integration.gateway;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
@@ -35,6 +38,7 @@ import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -43,6 +47,8 @@ import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.GatewayHeader;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
@@ -50,7 +56,9 @@ import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -83,6 +91,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
startResponder(requestChannel);
|
||||
GenericConversionService cs = new DefaultConversionService();
|
||||
Converter<String, byte[]> stringToByteConverter = new Converter<String, byte[]>() {
|
||||
|
||||
@Override
|
||||
public byte[] convert(String source) {
|
||||
return source.getBytes();
|
||||
@@ -312,6 +321,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
DirectChannel channel = new DirectChannel();
|
||||
EventDrivenConsumer consumer = new EventDrivenConsumer(channel, new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) {
|
||||
Method method = ReflectionUtils.findMethod(
|
||||
@@ -358,6 +368,57 @@ public class GatewayProxyFactoryBeanTests {
|
||||
assertThat(bar, equalTo("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdHeaderOverrideHeaderExpression() {
|
||||
GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean();
|
||||
gpfb.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
GatewayMethodMetadata meta = new GatewayMethodMetadata();
|
||||
meta.setHeaderExpressions(Collections.singletonMap(MessageHeaders.ID, new LiteralExpression("bar")));
|
||||
gpfb.setGlobalMethodMetadata(meta);
|
||||
|
||||
try {
|
||||
gpfb.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdHeaderOverrideGatewayHeaderAnnotation() {
|
||||
GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean();
|
||||
gpfb.setBeanFactory(mock(BeanFactory.class));
|
||||
gpfb.setServiceInterface(HeadersOverwriteService.class);
|
||||
|
||||
try {
|
||||
gpfb.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeStampHeaderOverrideParamHeaderAnnotation() {
|
||||
GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean();
|
||||
gpfb.setBeanFactory(mock(BeanFactory.class));
|
||||
gpfb.setServiceInterface(HeadersParamService.class);
|
||||
|
||||
try {
|
||||
gpfb.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testHistory() throws Exception {
|
||||
// GenericApplicationContext context = new GenericApplicationContext();
|
||||
@@ -413,6 +474,18 @@ public class GatewayProxyFactoryBeanTests {
|
||||
}
|
||||
|
||||
|
||||
interface HeadersOverwriteService {
|
||||
|
||||
@Gateway(headers = @GatewayHeader(name = MessageHeaders.ID, value = "id"))
|
||||
Message<?> echo(String s);
|
||||
}
|
||||
|
||||
interface HeadersParamService {
|
||||
|
||||
Message<?> echo(String s, @Header(MessageHeaders.TIMESTAMP) String foo);
|
||||
}
|
||||
|
||||
|
||||
interface TestExceptionThrowingInterface {
|
||||
|
||||
String throwCheckedException(String s) throws TestException;
|
||||
@@ -421,6 +494,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class TestException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -16,20 +16,30 @@
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.transformer.HeaderEnricher;
|
||||
import org.springframework.integration.transformer.support.StaticHeaderValueMessageProcessor;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MethodInvokingHeaderEnricherTests {
|
||||
@@ -89,6 +99,21 @@ public class MethodInvokingHeaderEnricherTests {
|
||||
assertEquals("ABC", result.getHeaders().get("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overwriteId() {
|
||||
HeaderEnricher enricher =
|
||||
new HeaderEnricher(Collections.singletonMap(MessageHeaders.ID,
|
||||
new StaticHeaderValueMessageProcessor<>("foo")));
|
||||
|
||||
try {
|
||||
enricher.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("HeaderEnricher cannot override 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.transformer;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalToIgnoringCase;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
@@ -27,6 +28,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -34,6 +36,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
@@ -47,9 +50,11 @@ import org.springframework.integration.endpoint.PollingConsumer;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.handler.ReplyRequiredException;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.transformer.support.StaticHeaderValueMessageProcessor;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
@@ -87,7 +92,7 @@ public class ContentEnricherTests {
|
||||
public void replyChannelReplyTimingOut() throws Exception {
|
||||
|
||||
final long requestTimeout = 500L;
|
||||
final long replyTimeout = 700L;
|
||||
final long replyTimeout = 100L;
|
||||
|
||||
final DirectChannel replyChannel = new DirectChannel();
|
||||
final QueueChannel requestChannel = new QueueChannel(1);
|
||||
@@ -521,6 +526,40 @@ public class ContentEnricherTests {
|
||||
assertEquals("failed target", result.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwriteTimestamp() {
|
||||
ContentEnricher contentEnricher = new ContentEnricher();
|
||||
contentEnricher.setHeaderExpressions(
|
||||
Collections.singletonMap(MessageHeaders.TIMESTAMP, new StaticHeaderValueMessageProcessor<>("foo")));
|
||||
|
||||
contentEnricher.setBeanFactory(mock(BeanFactory.class));
|
||||
try {
|
||||
contentEnricher.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("ContentEnricher cannot override 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwriteIdNullResult() {
|
||||
ContentEnricher contentEnricher = new ContentEnricher();
|
||||
contentEnricher.setNullResultHeaderExpressions(
|
||||
Collections.singletonMap(MessageHeaders.ID, new StaticHeaderValueMessageProcessor<>("foo")));
|
||||
|
||||
contentEnricher.setBeanFactory(mock(BeanFactory.class));
|
||||
try {
|
||||
contentEnricher.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("ContentEnricher cannot override 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final class Source {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -16,24 +16,35 @@
|
||||
|
||||
package org.springframework.integration.transformer;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.integration.test.matcher.HeaderMatcher.hasHeaderKey;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class HeaderFilterTests {
|
||||
@@ -76,4 +87,60 @@ public class HeaderFilterTests {
|
||||
assertEquals(correlationId, new IntegrationMessageHeaderAccessor(result).getCorrelationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdHeaderRemoval() {
|
||||
HeaderFilter filter = new HeaderFilter("foo", MessageHeaders.ID);
|
||||
try {
|
||||
filter.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("HeaderFilter cannot remove 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimestampHeaderRemoval() {
|
||||
HeaderFilter filter = new HeaderFilter(MessageHeaders.TIMESTAMP);
|
||||
try {
|
||||
filter.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("HeaderFilter cannot remove 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdPatternRemoval() {
|
||||
HeaderFilter filter = new HeaderFilter("*", MessageHeaders.ID);
|
||||
filter.setPatternMatch(true);
|
||||
try {
|
||||
filter.afterPropertiesSet();
|
||||
fail("BeanInitializationException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("HeaderFilter cannot remove 'id' and 'timestamp' read-only headers."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatternRemoval() {
|
||||
HeaderFilter filter = new HeaderFilter("time*");
|
||||
filter.setPatternMatch(true);
|
||||
|
||||
filter.afterPropertiesSet();
|
||||
Message<String> message = MessageBuilder.withPayload("test")
|
||||
.setHeader("time", new Date())
|
||||
.build();
|
||||
|
||||
Message<?> result = filter.transform(message);
|
||||
|
||||
assertThat(result, hasHeaderKey(MessageHeaders.TIMESTAMP));
|
||||
assertThat(result, not(hasHeaderKey("time")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user