/*
* 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.jpa.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.handler.ReplyRequiredException;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.jpa.core.JpaExecutor;
import org.springframework.integration.jpa.core.JpaOperations;
import org.springframework.integration.jpa.outbound.JpaOutboundGateway;
import org.springframework.integration.jpa.support.OutboundGatewayType;
import org.springframework.integration.jpa.support.PersistMode;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
/**
* @author Gunnar Hillert
* @author Amol Nayak
* @author Gary Russell
* @author Artem Bilan
* @since 2.2
*
*/
public class JpaOutboundGatewayParserTests extends AbstractRequestHandlerAdvice {
private ConfigurableApplicationContext context;
private EventDrivenConsumer consumer;
@Test
public void testRetrievingJpaOutboundGatewayParser() throws Exception {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "retrievingJpaOutboundGateway");
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(this.consumer, "inputChannel", AbstractMessageChannel.class);
assertEquals("in", inputChannel.getComponentName());
final JpaOutboundGateway jpaOutboundGateway = TestUtils.getPropertyValue(this.consumer, "handler", JpaOutboundGateway.class);
final OutboundGatewayType gatewayType = TestUtils.getPropertyValue(jpaOutboundGateway, "gatewayType", OutboundGatewayType.class);
assertEquals(OutboundGatewayType.RETRIEVING, gatewayType);
long sendTimeout = TestUtils.getPropertyValue(jpaOutboundGateway, "messagingTemplate.sendTimeout", Long.class);
assertEquals(100, sendTimeout);
assertFalse(TestUtils.getPropertyValue(jpaOutboundGateway, "requiresReply", Boolean.class));
final JpaExecutor jpaExecutor = TestUtils.getPropertyValue(this.consumer, "handler.jpaExecutor", JpaExecutor.class);
assertNotNull(jpaExecutor);
final Class<?> entityClass = TestUtils.getPropertyValue(jpaExecutor, "entityClass", Class.class);
assertEquals("org.springframework.integration.jpa.test.entity.StudentDomain", entityClass.getName());
final JpaOperations jpaOperations = TestUtils.getPropertyValue(jpaExecutor, "jpaOperations", JpaOperations.class);
assertNotNull(jpaOperations);
assertTrue(TestUtils.getPropertyValue(jpaExecutor, "expectSingleResult", Boolean.class));
final LiteralExpression maxResultsExpression =
TestUtils.getPropertyValue(jpaExecutor, "maxResultsExpression", LiteralExpression.class);
assertNotNull(maxResultsExpression);
assertEquals("55", TestUtils.getPropertyValue(maxResultsExpression, "literalValue"));
assertTrue(TestUtils.getPropertyValue(jpaExecutor, "deleteAfterPoll", Boolean.class));
assertTrue(TestUtils.getPropertyValue(jpaExecutor, "flush", Boolean.class));
}
@Test
public void testRetrievingJpaOutboundGatewayParserWithFirstResult() throws Exception {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "retrievingJpaOutboundGatewayWithFirstResult");
final JpaOutboundGateway jpaOutboundGateway = TestUtils.getPropertyValue(this.consumer, "handler", JpaOutboundGateway.class);
Expression firstResultExpression =
TestUtils.getPropertyValue(jpaOutboundGateway, "jpaExecutor.firstResultExpression", Expression.class);
assertNotNull(firstResultExpression);
assertEquals(LiteralExpression.class, firstResultExpression.getClass());
assertEquals("1", TestUtils.getPropertyValue(firstResultExpression, "literalValue", String.class));
}
@Test
public void testRetrievingJpaOutboundGatewayParserWithFirstResultExpression() throws Exception {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "retrievingJpaOutboundGatewayWithFirstResultExpression");
final JpaOutboundGateway jpaOutboundGateway = TestUtils.getPropertyValue(this.consumer, "handler", JpaOutboundGateway.class);
Expression firstResultExpression =
TestUtils.getPropertyValue(jpaOutboundGateway, "jpaExecutor.firstResultExpression", Expression.class);
assertNotNull(firstResultExpression);
assertEquals(SpelExpression.class, firstResultExpression.getClass());
assertEquals("header['firstResult']", TestUtils.getPropertyValue(firstResultExpression, "expression", String.class));
}
@Test
public void testRetrievingJpaOutboundGatewayParserWithMaxResultExpression() throws Exception {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "retrievingJpaOutboundGatewayWithMaxResultExpression");
final JpaOutboundGateway jpaOutboundGateway = TestUtils.getPropertyValue(this.consumer, "handler", JpaOutboundGateway.class);
Expression maxNumberOfResultExpression =
TestUtils.getPropertyValue(jpaOutboundGateway, "jpaExecutor.maxResultsExpression", Expression.class);
assertNotNull(maxNumberOfResultExpression);
assertEquals(SpelExpression.class, maxNumberOfResultExpression.getClass());
assertEquals("header['maxResults']", TestUtils.getPropertyValue(maxNumberOfResultExpression, "expression", String.class));
}
@Test
public void testUpdatingJpaOutboundGatewayParser() throws Exception {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "updatingJpaOutboundGateway");
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(this.consumer, "inputChannel", AbstractMessageChannel.class);
assertEquals("in", inputChannel.getComponentName());
final JpaOutboundGateway jpaOutboundGateway = TestUtils.getPropertyValue(this.consumer, "handler", JpaOutboundGateway.class);
final OutboundGatewayType gatewayType = TestUtils.getPropertyValue(jpaOutboundGateway, "gatewayType", OutboundGatewayType.class);
assertEquals(OutboundGatewayType.UPDATING, gatewayType);
long sendTimeout = TestUtils.getPropertyValue(jpaOutboundGateway, "messagingTemplate.sendTimeout", Long.class);
assertEquals(100, sendTimeout);
assertFalse(TestUtils.getPropertyValue(jpaOutboundGateway, "requiresReply", Boolean.class));
final JpaExecutor jpaExecutor = TestUtils.getPropertyValue(this.consumer, "handler.jpaExecutor", JpaExecutor.class);
assertNotNull(jpaExecutor);
final Class<?> entityClass = TestUtils.getPropertyValue(jpaExecutor, "entityClass", Class.class);
assertEquals("org.springframework.integration.jpa.test.entity.StudentDomain", entityClass.getName());
final JpaOperations jpaOperations = TestUtils.getPropertyValue(jpaExecutor, "jpaOperations", JpaOperations.class);
assertNotNull(jpaOperations);
final Boolean usePayloadAsParameterSource = TestUtils.getPropertyValue(jpaExecutor, "usePayloadAsParameterSource", Boolean.class);
assertTrue(usePayloadAsParameterSource);
final Integer order = TestUtils.getPropertyValue(jpaOutboundGateway, "order", Integer.class);
assertEquals(Integer.valueOf(2), order);
final PersistMode persistMode = TestUtils.getPropertyValue(jpaExecutor, "persistMode", PersistMode.class);
assertEquals(PersistMode.PERSIST, persistMode);
assertEquals(Integer.valueOf(100), TestUtils.getPropertyValue(jpaExecutor, "flushSize", Integer.class));
assertTrue(TestUtils.getPropertyValue(jpaExecutor, "clearOnFlush", Boolean.class));
}
@Test
public void advised() throws Throwable {
setUp("JpaOutboundGatewayParserTests.xml", getClass(), "advised");
EventDrivenConsumer jpaOutboundGatewayEndpoint = context.getBean("advised", EventDrivenConsumer.class);
MessageHandler jpaOutboundGateway = TestUtils.getPropertyValue(jpaOutboundGatewayEndpoint, "handler", MessageHandler.class);
FooAdvice advice = context.getBean("jpaFooAdvice", FooAdvice.class);
assertTrue(AopUtils.isAopProxy(jpaOutboundGateway));
try {
jpaOutboundGateway.handleMessage(new GenericMessage<String>("foo"));
fail("expected ReplyRequiredException");
}
catch (MessagingException e) {
assertTrue(e instanceof ReplyRequiredException);
}
Mockito.verify(advice).doInvoke(Mockito.any(ExecutionCallback.class), Mockito.any(Object.class), Mockito.any(Message.class));
}
@Test
public void testJpaExecutorBeanIdNaming() throws Exception {
this.context = new ClassPathXmlApplicationContext("JpaOutboundGatewayParserTests.xml", getClass());
assertNotNull(context.getBean("retrievingJpaOutboundGateway.jpaExecutor", JpaExecutor.class));
assertNotNull(context.getBean("updatingJpaOutboundGateway.jpaExecutor", JpaExecutor.class));
}
@Test
public void withBothFirstResultAndFirstResultExpressionPresent() {
try {
this.context = new ClassPathXmlApplicationContext("JpaInvalidOutboundGatewayParserTests.xml", getClass());
}
catch (BeanDefinitionStoreException e) {
assertTrue(e.getMessage().startsWith("Configuration problem: Only one of 'first-result' or 'first-result-expression' is allowed"));
return;
}
fail("BeanDefinitionStoreException expected.");
}
@After
public void tearDown() {
if (context != null) {
context.close();
}
}
public void setUp(String name, Class<?> cls, String gatewayId) {
context = new ClassPathXmlApplicationContext(name, cls);
consumer = this.context.getBean(gatewayId, EventDrivenConsumer.class);
}
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
// Workaround for access to protected AbstractRequestHandlerAdvice.ExecutionCallback
return null;
}
public static class FooAdvice extends AbstractRequestHandlerAdvice {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
return null;
}
}
}