INT-3749: Get rid of IECA logic

JIRA: https://jira.spring.io/browse/INT-3749

Since `IntegrationEvaluationContextAware` isn't so "context-free" resource like `BeanFactory`
 and `ApplicationContext`, but just a specific bean in the context, we can't follow with `BeanPostProcessor` logic - bad architecture by level of responsibility.
 Therefore we should follow with standard Dependency Injection mechanism to retrieve `evaluationContext` for the particular component.

 Since we can't rely on the `@Autowired` because SI can be used from the raw XML configuration,
 we use utility method instead. The pattern to get the proper `integrationEvaluationContext` is:
 ```
 @Override
 protected void onInit() throws Exception {
 		super.onInit();
 		this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
 }
 ```
This commit is contained in:
Artem Bilan
2015-06-23 20:42:34 -04:00
committed by Gary Russell
parent fe98cbc4e0
commit 3392d4e1ab
26 changed files with 272 additions and 253 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jpa.core;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
@@ -28,7 +28,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.expression.IntegrationEvaluationContextAware;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.jpa.support.JpaParameter;
import org.springframework.integration.jpa.support.PersistMode;
import org.springframework.integration.jpa.support.parametersource.BeanPropertyParameterSourceFactory;
@@ -65,7 +65,7 @@ import org.springframework.util.Assert;
* @since 2.2
*
*/
public class JpaExecutor implements InitializingBean, BeanFactoryAware, IntegrationEvaluationContextAware {
public class JpaExecutor implements InitializingBean, BeanFactoryAware {
private final JpaOperations jpaOperations;
@@ -205,6 +205,8 @@ public class JpaExecutor implements InitializingBean, BeanFactoryAware, Integrat
else if (this.flush) {
this.flushSize = 1;
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
}
/**
@@ -617,14 +619,4 @@ public class JpaExecutor implements InitializingBean, BeanFactoryAware, Integrat
this.setMaxResultsExpression(new LiteralExpression("" + maxNumberOfResults));
}
/**
* Sets the evaluation context for evaluating the expression to get the from record of the
* result set retrieved by the retrieving gateway.
* @param evaluationContext The evaluation context.
*/
@Override
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
this.evaluationContext = evaluationContext;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 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
@@ -10,6 +10,7 @@
* 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.core;
import static org.mockito.Mockito.mock;
@@ -17,17 +18,11 @@ import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.jpa.support.JpaParameter;
import org.springframework.integration.jpa.support.parametersource.ExpressionEvaluatingParameterSourceFactory;
import org.springframework.integration.jpa.test.entity.StudentDomain;
@@ -38,13 +33,16 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
*
* @author Gunnar Hillert
* @author Amol Nayak
* @author Gary Russell
* @author Artem Bilan
* @since 2.2
*
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -53,7 +51,8 @@ public class JpaExecutorTests {
@Autowired
protected EntityManager entityManager;
private final StandardEvaluationContext ctx = new StandardEvaluationContext();
@Autowired
private BeanFactory beanFactory;
/**
* In this test, the {@link JpaExecutor}'s poll method will be called without
@@ -69,11 +68,12 @@ public class JpaExecutorTests {
jpaExecutor.afterPropertiesSet();
try {
jpaExecutor.poll();
} catch (IllegalStateException e) {
}
catch (IllegalStateException e) {
Assert.assertEquals("Exception Message does not match.",
"For the polling operation, one of "
+ "the following properties must be specified: "
+ "query, namedQuery or entityClass.", e.getMessage());
+ "the following properties must be specified: "
+ "query, namedQuery or entityClass.", e.getMessage());
return;
}
@@ -81,16 +81,15 @@ public class JpaExecutorTests {
}
/**
*/
@Test
public void testInstatiateJpaExecutorWithNullJpaOperations() {
public void testInstantiateJpaExecutorWithNullJpaOperations() {
JpaOperations jpaOperations = null;
try {
new JpaExecutor(jpaOperations);
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e) {
Assert.assertEquals("jpaOperations must not be null.", e.getMessage());
}
@@ -104,16 +103,18 @@ public class JpaExecutorTests {
try {
executor.setNamedQuery("NamedQuery");
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e) {
Assert.assertEquals("You can define only one of the "
+ "properties 'jpaQuery', 'nativeQuery', 'namedQuery'", e.getMessage());
+ "properties 'jpaQuery', 'nativeQuery', 'namedQuery'", e.getMessage());
}
Assert.assertNull(TestUtils.getPropertyValue(executor, "namedQuery"));
try {
executor.setNativeQuery("select * from Student");
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e) {
Assert.assertEquals("You can define only one of the "
+ "properties 'jpaQuery', 'nativeQuery', 'namedQuery'", e.getMessage());
}
@@ -125,7 +126,8 @@ public class JpaExecutorTests {
try {
executor.setJpaQuery("select s from Student s");
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e) {
Assert.assertEquals("You can define only one of the "
+ "properties 'jpaQuery', 'nativeQuery', 'namedQuery'", e.getMessage());
}
@@ -138,7 +140,7 @@ public class JpaExecutorTests {
public void selectWithMessageAsParameterSource() {
String query = "select s from Student s where s.firstName = :firstName";
Message<Map<String, String>> message =
MessageBuilder.withPayload(Collections.singletonMap("firstName", "First One")).build();
MessageBuilder.withPayload(Collections.singletonMap("firstName", "First One")).build();
JpaExecutor executor = getJpaExecutorForMessageAsParamSource(query);
StudentDomain student = (StudentDomain) executor.poll(message);
Assert.assertNotNull(student);
@@ -149,7 +151,7 @@ public class JpaExecutorTests {
public void selectWithPayloadAsParameterSource() {
String query = "select s from Student s where s.firstName = :firstName";
Message<String> message =
MessageBuilder.withPayload("First One").build();
MessageBuilder.withPayload("First One").build();
JpaExecutor executor = getJpaExecutorForPayloadAsParamSource(query);
StudentDomain student = (StudentDomain) executor.poll(message);
Assert.assertNotNull(student);
@@ -160,7 +162,7 @@ public class JpaExecutorTests {
public void updateWithMessageAsParameterSource() {
String query = "update Student s set s.firstName = :firstName where s.lastName = 'Last One'";
Message<Map<String, String>> message =
MessageBuilder.withPayload(Collections.singletonMap("firstName", "First One")).build();
MessageBuilder.withPayload(Collections.singletonMap("firstName", "First One")).build();
JpaExecutor executor = getJpaExecutorForMessageAsParamSource(query);
Integer rowsAffected = (Integer) executor.executeOutboundJpaOperation(message);
Assert.assertTrue(1 == rowsAffected);
@@ -171,16 +173,12 @@ public class JpaExecutorTests {
public void updateWithPayloadAsParameterSource() {
String query = "update Student s set s.firstName = :firstName where s.lastName = 'Last One'";
Message<String> message =
MessageBuilder.withPayload("First One").build();
MessageBuilder.withPayload("First One").build();
JpaExecutor executor = getJpaExecutorForPayloadAsParamSource(query);
Integer rowsAffected = (Integer) executor.executeOutboundJpaOperation(message);
Assert.assertTrue(1 == rowsAffected);
}
/**
* @param query
* @return
*/
private JpaExecutor getJpaExecutorForMessageAsParamSource(String query) {
JpaExecutor executor = new JpaExecutor(entityManager);
ExpressionEvaluatingParameterSourceFactory factory =
@@ -195,10 +193,6 @@ public class JpaExecutorTests {
return executor;
}
/**
* @param query
* @return
*/
private JpaExecutor getJpaExecutorForPayloadAsParamSource(String query) {
JpaExecutor executor = new JpaExecutor(entityManager);
ExpressionEvaluatingParameterSourceFactory factory =
@@ -218,10 +212,10 @@ public class JpaExecutorTests {
final JpaExecutor jpaExecutor = new JpaExecutor(entityManager);
jpaExecutor.setJpaQuery("select s from Student s");
jpaExecutor.setFirstResultExpression(new LiteralExpression("2"));
jpaExecutor.setIntegrationEvaluationContext(ctx);
jpaExecutor.setBeanFactory(this.beanFactory);
jpaExecutor.afterPropertiesSet();
List<?> results = (List<?>)jpaExecutor.poll(MessageBuilder.withPayload("").build());
List<?> results = (List<?>) jpaExecutor.poll(MessageBuilder.withPayload("").build());
Assert.assertNotNull(results);
Assert.assertEquals(1, results.size());
}
@@ -231,9 +225,10 @@ public class JpaExecutorTests {
final JpaExecutor jpaExecutor = new JpaExecutor(entityManager);
jpaExecutor.setNativeQuery("select * from Student s");
jpaExecutor.setFirstResultExpression(new LiteralExpression("2"));
jpaExecutor.setIntegrationEvaluationContext(ctx);
jpaExecutor.setBeanFactory(this.beanFactory);
jpaExecutor.afterPropertiesSet();
List<?> results = (List<?>)jpaExecutor.poll(MessageBuilder.withPayload("").build());
List<?> results = (List<?>) jpaExecutor.poll(MessageBuilder.withPayload("").build());
Assert.assertNotNull(results);
Assert.assertEquals(1, results.size());
}
@@ -243,9 +238,10 @@ public class JpaExecutorTests {
final JpaExecutor jpaExecutor = new JpaExecutor(entityManager);
jpaExecutor.setNamedQuery("selectAllStudents");
jpaExecutor.setFirstResultExpression(new LiteralExpression("2"));
jpaExecutor.setIntegrationEvaluationContext(ctx);
jpaExecutor.setBeanFactory(this.beanFactory);
jpaExecutor.afterPropertiesSet();
List<?> results = (List<?>)jpaExecutor.poll(MessageBuilder.withPayload("").build());
List<?> results = (List<?>) jpaExecutor.poll(MessageBuilder.withPayload("").build());
Assert.assertNotNull(results);
Assert.assertEquals(1, results.size());
}
@@ -255,9 +251,10 @@ public class JpaExecutorTests {
final JpaExecutor jpaExecutor = new JpaExecutor(entityManager);
jpaExecutor.setEntityClass(StudentDomain.class);
jpaExecutor.setFirstResultExpression(new LiteralExpression("2"));
jpaExecutor.setIntegrationEvaluationContext(ctx);
jpaExecutor.setBeanFactory(this.beanFactory);
jpaExecutor.afterPropertiesSet();
List<?> results = (List<?>)jpaExecutor.poll(MessageBuilder.withPayload("").build());
List<?> results = (List<?>) jpaExecutor.poll(MessageBuilder.withPayload("").build());
Assert.assertNotNull(results);
Assert.assertEquals(1, results.size());
}
@@ -267,7 +264,8 @@ public class JpaExecutorTests {
final JpaExecutor jpaExecutor = new JpaExecutor(mock(EntityManager.class));
try {
jpaExecutor.setMaxResultsExpression(null);
} catch (Exception e) {
}
catch (Exception e) {
Assert.assertEquals("maxResultsExpression cannot be null", e.getMessage());
return;
}