/*
* 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.
* 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.http.outbound;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.expression.ExpressionEvalMap;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
/**
* @author Dave Syer
* @author Mark Fisher
* @author Wallace Wadge
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
public class UriVariableExpressionTests {
@Test
public void testFromMessageWithExpressions() throws Exception {
final AtomicReference<URI> uriHolder = new AtomicReference<URI>();
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://test/{foo}");
SpelExpressionParser parser = new SpelExpressionParser();
handler.setUriVariableExpressions(Collections.singletonMap("foo", parser.parseExpression("payload")));
handler.setRequestFactory(new SimpleClientHttpRequestFactory() {
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
uriHolder.set(uri);
throw new RuntimeException("intentional");
}
});
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
Message<?> message = new GenericMessage<Object>("bar");
try {
handler.handleMessage(message);
fail("Exception expected.");
}
catch (Exception e) {
assertEquals("intentional", e.getCause().getMessage());
}
assertEquals("http://test/bar", uriHolder.get().toString());
}
/** Test for INT-3054: Do not break if there are extra uri variables defined in the http outbound gateway. */
@Test
public void testFromMessageWithSuperfluousExpressionsInt3054() throws Exception {
final AtomicReference<URI> uriHolder = new AtomicReference<URI>();
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://test/{foo}");
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> multipleExpressions = new HashMap<String, Expression>();
multipleExpressions.put("foo", parser.parseExpression("payload"));
multipleExpressions.put("extra-to-be-ignored", parser.parseExpression("headers.extra"));
handler.setUriVariableExpressions(multipleExpressions);
handler.setRequestFactory(new SimpleClientHttpRequestFactory() {
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
uriHolder.set(uri);
throw new RuntimeException("intentional");
}
});
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
try {
handler.handleMessage(new GenericMessage<Object>("bar"));
fail("Exception expected.");
}
catch (Exception e) {
assertEquals("intentional", e.getCause().getMessage());
}
assertEquals("http://test/bar", uriHolder.get().toString());
}
@Test
public void testInt3055UriVariablesExpression() throws Exception {
final AtomicReference<URI> uriHolder = new AtomicReference<URI>();
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://test/{foo}");
handler.setRequestFactory(new SimpleClientHttpRequestFactory() {
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
uriHolder.set(uri);
throw new RuntimeException("intentional");
}
});
AbstractApplicationContext context = TestUtils.createTestApplicationContext();
IntegrationRegistrar registrar = new IntegrationRegistrar();
registrar.setBeanClassLoader(context.getClassLoader());
registrar.registerBeanDefinitions(null, (BeanDefinitionRegistry) context.getBeanFactory());
context.refresh();
handler.setBeanFactory(context);
handler.setUriVariablesExpression(new SpelExpressionParser().parseExpression("headers.uriVariables"));
handler.afterPropertiesSet();
Map<String, String> expressions = new HashMap<String, String>();
expressions.put("foo", "bar");
Map<String, ?> expressionsMap = ExpressionEvalMap.from(expressions).usingSimpleCallback().build();
try {
handler.handleMessage(MessageBuilder.withPayload("test").setHeader("uriVariables", expressionsMap).build());
fail("Exception expected.");
}
catch (Exception e) {
assertEquals("intentional", e.getCause().getMessage());
}
assertEquals("http://test/bar", uriHolder.get().toString());
}
}