Merge pull request #472 from garyrussell/INT-2271

* INT-2271:
  INT-2271 - Add Dynamic Stored Proc Names (SpEL + Header) * Add support for Stored Procedure/Function Names via Message Header * Add support for Stored Procedure/Function Names via "stored-procedure-expression" parameter * Add support for cacheable *SimpleJdbcCallOperation* instances * Add Guava dependency for Cache Support * Convert white-spaces to tabs (where occurring) * Convert line-delimiters to Linux format (where occurring)
This commit is contained in:
Oleg Zhurakousky
2012-06-01 15:14:04 -04:00
50 changed files with 4023 additions and 2588 deletions

View File

@@ -418,12 +418,15 @@ project('spring-integration-jdbc') {
compile "org.springframework:spring-aop:$springVersion"
compile "org.springframework:spring-jdbc:$springVersion"
compile "org.springframework:spring-tx:$springVersion"
compile "com.google.guava:guava:12.0"
testCompile project(":spring-integration-test")
testCompile "com.h2database:h2:1.3.160"
testCompile "hsqldb:hsqldb:1.8.0.10"
testCompile "org.apache.derby:derby:10.5.3.0_1"
testCompile "org.aspectj:aspectjrt:$aspectjVersion"
testCompile "org.aspectj:aspectjweaver:$aspectjVersion"
testCompile "org.powermock:powermock-module-junit4:1.4.12"
testCompile "org.powermock:powermock-api-mockito:1.4.12"
}
bundlor {
bundleSymbolicName = 'org.springframework.integration.jdbc'
@@ -433,7 +436,9 @@ project('spring-integration-jdbc') {
'org.apache.commons.logging;version="[1.1.1, 2.0.0)"',
'org.aopalliance.*;version="[1.0.0, 2.0.0)"',
'javax.sql.*;version="0"',
'org.w3c.dom.*;version="0"'
'org.w3c.dom.*;version="0"',
'com.google.guava.*;version="[12.0.0,13.0.0)"',
'com.google.common.*;version="[11.0.0, 12.0.0)"'
]
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -24,7 +24,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
/**
* A default implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} to
* reference bean properties in its input.
*
*
* @author Dave Syer
* @since 2.0
*/
@@ -39,7 +39,7 @@ public class BeanPropertySqlParameterSourceFactory implements SqlParameterSource
/**
* If the input is a List or a Map, the output is a map parameter source, and in that case some static parameters
* can be added (default is empty). If the input is not a List or a Map then this value is ignored.
*
*
* @param staticParameters the static parameters to set
*/
public void setStaticParameters(Map<String, Object> staticParameters) {

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -28,7 +28,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
/**
* An implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} that evaluates
* Spring EL expressions. In addition the user can supply static parameters that always take precedence.
*
*
* @author Dave Syer
* @author Oleg Zhurakousky
* @since 2.0
@@ -53,7 +53,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
* Define some static parameter values. These take precedence over those defined as expressions in the
* {@link #setParameterExpressions(Map) parameterExpressions}, so a parameter in the query will be filled from here
* first, and then from the expressions.
*
*
* @param staticParameters the static parameters to set
*/
public void setStaticParameters(Map<String, ?> staticParameters) {
@@ -68,7 +68,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
* context: generally in an outbound setting it is a Message, and in an inbound setting it is a result set row (a
* Map or a domain object if a RowMapper has been provided). The {@link #setStaticParameters(Map) static parameters}
* can be referred to in an expression using the variable <code>#staticParameters</code>, for example:
*
*
* <table border="1" cellspacing="1" cellpadding="1">
* <tr>
* <th><b>Key</b></th>
@@ -91,7 +91,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
* <td>select * from items where name=:key</td>
* </tr>
* </pre>
*
*
* @param parameterExpressions the parameter expressions to set
*/
public void setParameterExpressions(Map<String, String> parameterExpressions) {
@@ -104,7 +104,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
return toReturn;
}
private class ExpressionEvaluatingSqlParameterSource extends AbstractSqlParameterSource {
private final class ExpressionEvaluatingSqlParameterSource extends AbstractSqlParameterSource {
private final Object input;

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -29,7 +29,6 @@ import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.util.LinkedCaseInsensitiveMap;
@@ -38,14 +37,14 @@ import org.springframework.util.LinkedCaseInsensitiveMap;
* A message handler that executes an SQL update. Dynamic query parameters are supported through the
* {@link SqlParameterSourceFactory} abstraction, the default implementation of which wraps the message so that its bean
* properties can be referred to by name in the query string E.g.
*
*
* <pre>
* INSERT INTO FOOS (MESSAGE_ID, PAYLOAD) VALUES (:headers[id], :payload)
* </pre>
*
*
* N.B. do not use quotes to escape the header keys. The default SQL parameter source (from Spring JDBC) can also handle
* headers with dotted names (e.g. <code>business.id</code>)
*
*
* @author Dave Syer
* @since 2.0
*/
@@ -62,8 +61,8 @@ public class JdbcMessageHandler extends AbstractMessageHandler {
/**
* Constructor taking {@link DataSource} from which the DB Connection can be obtained and the select query to
* execute to retrieve new rows.
*
* @param dataSource used to create a {@link SimpleJdbcTemplate}
*
* @param dataSource Must not be null
* @param updateSql query to execute
*/
public JdbcMessageHandler(DataSource dataSource, String updateSql) {
@@ -74,7 +73,7 @@ public class JdbcMessageHandler extends AbstractMessageHandler {
/**
* Constructor taking {@link JdbcOperations} instance to use for query execution and the select query to execute to
* retrieve new rows.
*
*
* @param jdbcOperations instance to use for query execution
* @param updateSql query to execute
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -45,8 +45,8 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
private volatile boolean keysGenerated;
private volatile Integer maxRowsPerPoll;
private volatile Integer maxRowsPerPoll;
public JdbcOutboundGateway(DataSource dataSource, String updateQuery) {
this(new JdbcTemplate(dataSource), updateQuery, null);
}
@@ -73,15 +73,15 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
/**
* The maximum number of rows to pull out of the query results per poll (if
* greater than zero, otherwise all rows will be packed into the outgoing
* message).
*
* message).
*
* The value is ultimately set on the underlying {@link JdbcPollingChannelAdapter}.
* If not specified this value will default to <code>zero</code>.
*
*
* This parameter is only applicable if a selectQuery was provided. Null values
* are not permitted.
*
* @param maxRowsPerPoll Must not be null.
* are not permitted.
*
* @param maxRowsPerPoll Must not be null.
*/
public void setMaxRowsPerPoll(Integer maxRowsPerPoll) {
Assert.notNull(maxRowsPerPoll, "MaxRowsPerPoll must not be null.");
@@ -90,14 +90,14 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
@Override
protected void onInit() {
if (this.maxRowsPerPoll != null) {
Assert.notNull(poller, "If you want to set 'maxRowsPerPoll', then you must provide a 'selectQuery'.");
poller.setMaxRowsPerPoll(this.maxRowsPerPoll);
poller.setMaxRowsPerPoll(this.maxRowsPerPoll);
}
handler.afterPropertiesSet();
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -36,13 +36,12 @@ import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
/**
* A polling channel adapter that creates messages from the payload returned by
* executing a select query. Optionally an update can be executed after the
* select in order to update processed rows.
*
*
* @author Jonas Partner
* @author Dave Syer
* @since 2.0
@@ -68,8 +67,8 @@ public class JdbcPollingChannelAdapter extends IntegrationObjectSupport implemen
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the select query to execute to retrieve new rows.
*
* @param dataSource used to create a {@link SimpleJdbcTemplate}
*
* @param dataSource Must not be null
* @param selectQuery query to execute
*/
public JdbcPollingChannelAdapter(DataSource dataSource, String selectQuery) {
@@ -80,7 +79,7 @@ public class JdbcPollingChannelAdapter extends IntegrationObjectSupport implemen
/**
* Constructor taking {@link JdbcOperations} instance to use for query
* execution and the select query to execute to retrieve new rows.
*
*
* @param jdbcOperations instance to use for query execution
* @param selectQuery query to execute
*/
@@ -107,7 +106,7 @@ public class JdbcPollingChannelAdapter extends IntegrationObjectSupport implemen
/**
* A source of parameters for the select query used for polling.
*
*
* @param sqlQueryParameterSource the sql query parameter source to set
*/
public void setSelectSqlParameterSource(SqlParameterSource sqlQueryParameterSource) {
@@ -118,7 +117,7 @@ public class JdbcPollingChannelAdapter extends IntegrationObjectSupport implemen
* The maximum number of rows to pull out of the query results per poll (if
* greater than zero, otherwise all rows will be packed into the outgoing
* message). Default is zero.
*
*
* @param maxRows the max rows to set
*/
public void setMaxRowsPerPoll(int maxRows) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -21,7 +21,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
/**
* Collaborator for JDBC adapters which allows creation of
* instances of {@link SqlParameterSource} for use in update operations.
*
*
* @author Jonas Partner
* @since 2.0
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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
@@ -15,6 +15,7 @@ package org.springframework.integration.jdbc;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -22,9 +23,17 @@ import java.util.Map.Entry;
import javax.sql.DataSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
@@ -34,53 +43,48 @@ import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.core.simple.SimpleJdbcCallOperations;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedMetric;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.util.Assert;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
import com.google.common.cache.LoadingCache;
/**
* A message handler that executes Stored Procedures for update purposes.
*
* Stored procedure parameter value are by default automatically extracted from
* the Payload if the payload's bean properties match the parameters of the Stored
* Procedure.
*
* This may be sufficient for basic use cases. For more sophisticated options
* consider passing in one or more {@link ProcedureParameter}.
*
* If you need to handle the return parameters of the called stored procedure
* explicitly, please consider using a {@link StoredProcOutboundGateway} instead.
*
* Also, if you need to execute SQL Functions, please also use the
* {@link StoredProcOutboundGateway}. As functions are typically used to look up
* values, only, the Stored Procedure message handler does purposefully not support
* SQL function calls. If you believe there are valid use-cases for that, please file a
* feature request at http://jira.springsource.org.
*
* This class is used by all Stored Procedure (Stored Function) components and
* provides the core functionality to execute those.
*
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcExecutor implements InitializingBean {
@ManagedResource
public class StoredProcExecutor implements BeanFactoryAware, InitializingBean {
/**
* Uses the {@link SimpleJdbcCall} implementation for executing Stored Procedures.
*/
private final SimpleJdbcCall jdbcCallOperations;
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile BeanFactory beanFactory = null;
/**
* Name of the stored procedure or function to be executed.
*/
private volatile String storedProcedureName;
private volatile int jdbcCallOperationsCacheSize = 10;
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* or Function from the JDBC Meta-data. However, if the used database does
* not support meta data lookups or if you like to provide customized
* parameter definitions, this flag can be set to 'true'. It defaults to 'false'.
*/
private volatile boolean ignoreColumnMetaData = false;
/**
* Uses the {@link SimpleJdbcCall} implementation for executing Stored Procedures.
*/
private volatile LoadingCache<String, SimpleJdbcCallOperations> jdbcCallOperationsCache = null;
private volatile Expression storedProcedureNameExpression;
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* or Function from the JDBC Meta-data. However, if the used database does
* not support meta data lookups or if you like to provide customized
* parameter definitions, this flag can be set to 'true'. It defaults to 'false'.
*/
private volatile boolean ignoreColumnMetaData = false;
/**
* If this variable is set to true then all results from a stored procedure call
@@ -90,282 +94,414 @@ public class StoredProcExecutor implements InitializingBean {
*
* Value defaults to <code>true</code>.
*/
private volatile boolean skipUndeclaredResults = true;
private volatile boolean skipUndeclaredResults = true;
/**
* If your database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly. See also {@link SqlOutParameter} and
* {@link SqlInOutParameter}.
*/
private volatile List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>(0);
/**
* If your database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly. See also {@link SqlOutParameter} and
* {@link SqlInOutParameter}.
*/
private volatile List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>(0);
/**
* By default bean properties of the passed in {@link Message} will be used
* as a source for the Stored Procedure's input parameters. By default a
* {@link BeanPropertySqlParameterSourceFactory} will be used.
*
* This may be sufficient for basic use cases. For more sophisticated options
* consider passing in one or more {@link ProcedureParameter}.
*/
private volatile SqlParameterSourceFactory sqlParameterSourceFactory = null;
/**
* By default bean properties of the passed in {@link Message} will be used
* as a source for the Stored Procedure's input parameters. By default a
* {@link BeanPropertySqlParameterSourceFactory} will be used.
*
* This may be sufficient for basic use cases. For more sophisticated options
* consider passing in one or more {@link ProcedureParameter}.
*/
private volatile SqlParameterSourceFactory sqlParameterSourceFactory = null;
/**
* Indicates that whether only the payload of the passed in {@link Message}
* will be used as a source of parameters. The is 'true' by default because as a
* default a {@link BeanPropertySqlParameterSourceFactory} implementation is
* used for the sqlParameterSourceFactory property.
*/
private volatile Boolean usePayloadAsParameterSource = null;
/**
* Indicates that whether only the payload of the passed-in {@link Message}
* shall be used as a source of parameters.
*
* @see #setUsePayloadAsParameterSource(boolean)
*/
private volatile Boolean usePayloadAsParameterSource = null;
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
private volatile List<ProcedureParameter>procedureParameters;
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
private volatile List<ProcedureParameter>procedureParameters;
private volatile boolean isFunction = false;
private volatile boolean returnValueRequired = false;
private volatile Map<String, RowMapper<?>> returningResultSetRowMappers = new HashMap<String, RowMapper<?>>(0);
private volatile boolean isFunction = false;
private volatile boolean returnValueRequired = false;
private volatile Map<String, RowMapper<?>> returningResultSetRowMappers = new HashMap<String, RowMapper<?>>(0);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private final DataSource dataSource;
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the select query to execute the stored procedure.
*
* @param dataSource used to create a {@link SimpleJdbcTemplate}, must not be Null
* @param storedProcedureName Name of the Stored Procedure or function, must not be empty
*/
public StoredProcExecutor(DataSource dataSource, String storedProcedureName) {
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
this.jdbcCallOperations = new SimpleJdbcCall(dataSource);
this.storedProcedureName = storedProcedureName;
}
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
public void afterPropertiesSet() {
if (this.procedureParameters != null ) {
if (this.sqlParameterSourceFactory == null) {
ExpressionEvaluatingSqlParameterSourceFactory expressionSourceFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
expressionSourceFactory.setStaticParameters(ProcedureParameter.convertStaticParameters(procedureParameters));
expressionSourceFactory.setParameterExpressions(ProcedureParameter.convertExpressions(procedureParameters));
this.sqlParameterSourceFactory = expressionSourceFactory;
} else {
if (!(this.sqlParameterSourceFactory instanceof ExpressionEvaluatingSqlParameterSourceFactory)) {
throw new IllegalStateException("You are providing 'ProcedureParameters'. "
+ "Was expecting the the provided sqlParameterSourceFactory "
+ "to be an instance of 'ExpressionEvaluatingSqlParameterSourceFactory', "
+ "however the provided one is of type '" + this.sqlParameterSourceFactory.getClass().getName() + "'");
}
}
if (this.usePayloadAsParameterSource == null) {
this.usePayloadAsParameterSource = false;
}
} else {
if (this.sqlParameterSourceFactory == null) {
this.sqlParameterSourceFactory = new BeanPropertySqlParameterSourceFactory();
}
if (this.usePayloadAsParameterSource == null) {
this.usePayloadAsParameterSource = true;
}
}
if (this.ignoreColumnMetaData) {
this.jdbcCallOperations.withoutProcedureColumnMetaDataAccess();
}
this.jdbcCallOperations.declareParameters(this.sqlParameters.toArray(new SqlParameter[this.sqlParameters.size()]));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (!this.returningResultSetRowMappers.isEmpty()) {
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained.
*
* @param dataSource used to create a {@link SimpleJdbcCall} instance, must not be Null
*/
public StoredProcExecutor(DataSource dataSource) {
for (Entry<String, RowMapper<?>> mapEntry : this.returningResultSetRowMappers.entrySet()) {
jdbcCallOperations.returningResultSet(mapEntry.getKey(), mapEntry.getValue());
}
}
Assert.notNull(dataSource, "dataSource must not be null.");
this.dataSource = dataSource;
if (this.returnValueRequired) {
jdbcCallOperations.withReturnValue();
}
}
if (this.isFunction) {
this.jdbcCallOperations.withFunctionName(this.storedProcedureName);
} else {
this.jdbcCallOperations.withProcedureName(this.storedProcedureName);
}
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
public void afterPropertiesSet() {
this.jdbcCallOperations.getJdbcTemplate().setSkipUndeclaredResults(this.skipUndeclaredResults);
if (this.storedProcedureNameExpression == null) {
throw new IllegalArgumentException("You must either provide a "
+ "Stored Procedure Name or a Stored Procedure Name Expression.");
}
}
if (this.procedureParameters != null ) {
/**
* Execute a Stored Procedure or Function - Use when no {@link Message} is
* available to extract {@link ProcedureParameter} values from it.
*
* @return Map containing the stored procedure results if any.
*/
public Map<String, Object> executeStoredProcedure() {
return executeStoredProcedureInternal(new Object());
}
if (this.sqlParameterSourceFactory == null) {
ExpressionEvaluatingSqlParameterSourceFactory expressionSourceFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
/**
* Execute a Stored Procedure or Function - Use with {@link Message} is
* available to extract {@link ProcedureParameter} values from it.
*
* @return Map containing the stored procedure results if any.
*/
public Map<String, Object> executeStoredProcedure(Message<?> message) {
expressionSourceFactory.setStaticParameters(ProcedureParameter.convertStaticParameters(procedureParameters));
expressionSourceFactory.setParameterExpressions(ProcedureParameter.convertExpressions(procedureParameters));
Assert.notNull(message, "The message parameter must not be null.");
Assert.notNull(usePayloadAsParameterSource, "Property usePayloadAsParameterSource "
+ "was Null. Did you call afterPropertiesSet()?");
this.sqlParameterSourceFactory = expressionSourceFactory;
if (usePayloadAsParameterSource) {
return executeStoredProcedureInternal(message.getPayload());
} else {
return executeStoredProcedureInternal(message);
}
}
else {
}
if (!(this.sqlParameterSourceFactory instanceof ExpressionEvaluatingSqlParameterSourceFactory)) {
throw new IllegalStateException("You are providing 'ProcedureParameters'. "
+ "Was expecting the the provided sqlParameterSourceFactory "
+ "to be an instance of 'ExpressionEvaluatingSqlParameterSourceFactory', "
+ "however the provided one is of type '" + this.sqlParameterSourceFactory.getClass().getName() + "'");
}
/**
* Execute the Stored Procedure using the passed in {@link Message} as a source
* for parameters.
*
* @param message The message is used to extract parameters for the stored procedure.
* @return A map containing the return values from the Stored Procedure call if any.
*/
private Map<String, Object> executeStoredProcedureInternal(Object input) {
}
Assert.notNull(sqlParameterSourceFactory, "Property sqlParameterSourceFactory "
+ "was Null. Did you call afterPropertiesSet()?");
if (this.usePayloadAsParameterSource == null) {
this.usePayloadAsParameterSource = false;
}
SqlParameterSource storedProcedureParameterSource =
sqlParameterSourceFactory.createParameterSource(input);
}
else {
return StoredProcExecutor.executeStoredProcedure(jdbcCallOperations,
storedProcedureParameterSource);
}
if (this.sqlParameterSourceFactory == null) {
this.sqlParameterSourceFactory = new BeanPropertySqlParameterSourceFactory();
}
/**
*/
private static Map<String, Object> executeStoredProcedure(SimpleJdbcCallOperations simpleJdbcCallOperations,
SqlParameterSource storedProcedureParameterSource) {
if (this.usePayloadAsParameterSource == null) {
this.usePayloadAsParameterSource = true;
}
Map<String, Object> resultMap = simpleJdbcCallOperations.execute(storedProcedureParameterSource);
}
return resultMap;
jdbcCallOperationsCache = CacheBuilder.newBuilder()
.maximumSize(jdbcCallOperationsCacheSize)
.recordStats()
.build(new CacheLoader<String, SimpleJdbcCallOperations>() {
@Override
public SimpleJdbcCall load(String storedProcedureName) {
return createSimpleJdbcCall(storedProcedureName);
}
});
}
if (this.storedProcedureNameExpression instanceof LiteralExpression) {
String storedProcedureName = this.storedProcedureNameExpression.getValue(String.class);
final SimpleJdbcCall simpleJdbcCall = createSimpleJdbcCall(storedProcedureName);
this.jdbcCallOperationsCache.put(storedProcedureName, simpleJdbcCall);
}
//~~~~~Setters for Properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this.evaluationContext.addPropertyAccessor(new MapAccessor());
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* from the JDBC Meta-data. However, if the used database does not support
* meta data lookups or if you like to provide customized parameter definitions,
* this flag can be set to 'true'. It defaults to 'false'.
*/
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.ignoreColumnMetaData = ignoreColumnMetaData;
}
if (this.beanFactory != null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(this.beanFactory));
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
}
Assert.notEmpty(procedureParameters, "procedureParameters must not be null or empty.");
private SimpleJdbcCall createSimpleJdbcCall(String storedProcedureName) {
for (ProcedureParameter procedureParameter : procedureParameters) {
Assert.notNull(procedureParameter, "The provided list (procedureParameters) cannot contain null values.");
}
final SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(this.dataSource);
this.procedureParameters = procedureParameters;
if (this.ignoreColumnMetaData) {
simpleJdbcCall.withoutProcedureColumnMetaDataAccess();
}
}
simpleJdbcCall.declareParameters(this.sqlParameters.toArray(new SqlParameter[this.sqlParameters.size()]));
/**
* If you database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly.
*/
public void setSqlParameters(List<SqlParameter> sqlParameters) {
Assert.notEmpty(sqlParameters, "sqlParameters must not be null or empty.");
for (SqlParameter sqlParameter : sqlParameters) {
Assert.notNull(sqlParameter, "The provided list (sqlParameters) cannot contain null values.");
}
if (!this.returningResultSetRowMappers.isEmpty()) {
this.sqlParameters = sqlParameters;
}
for (Entry<String, RowMapper<?>> mapEntry : this.returningResultSetRowMappers.entrySet()) {
simpleJdbcCall.returningResultSet(mapEntry.getKey(), mapEntry.getValue());
}
}
/**
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
* you would like to provide a custom {@link SqlParameterSourceFactory},
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* If not the SqlParameterSourceFactory will be replaced the default
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* @param sqlParameterSourceFactory
*/
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
Assert.notNull(sqlParameterSourceFactory, "sqlParameterSourceFactory must not be null.");
this.sqlParameterSourceFactory = sqlParameterSourceFactory;
}
if (this.returnValueRequired) {
simpleJdbcCall.withReturnValue();
}
/**
* @return the name of the Stored Procedure or Function
* */
public String getStoredProcedureName() {
return this.storedProcedureName;
}
if (this.isFunction) {
simpleJdbcCall.withFunctionName(storedProcedureName);
}
else {
simpleJdbcCall.withProcedureName(storedProcedureName);
}
simpleJdbcCall.getJdbcTemplate().setSkipUndeclaredResults(this.skipUndeclaredResults);
return simpleJdbcCall;
}
/**
* Execute a Stored Procedure or Function - Use when no {@link Message} is
* available to extract {@link ProcedureParameter} values from it.
*
* @return Map containing the stored procedure results if any.
*/
public Map<String, Object> executeStoredProcedure() {
return executeStoredProcedureInternal(new Object(), this.evaluateExpression(null));
}
/**
* Execute a Stored Procedure or Function - Use with {@link Message} is
* available to extract {@link ProcedureParameter} values from it.
*
* @return Map containing the stored procedure results if any.
*/
public Map<String, Object> executeStoredProcedure(Message<?> message) {
Assert.notNull(message, "The message parameter must not be null.");
Assert.notNull(usePayloadAsParameterSource, "Property usePayloadAsParameterSource "
+ "was Null. Did you call afterPropertiesSet()?");
final Object input;
if (usePayloadAsParameterSource) {
input = message.getPayload();
}
else {
input = message;
}
return executeStoredProcedureInternal(input, evaluateExpression(message));
}
private String evaluateExpression(Message<?> message) {
final String storedProcedureNameToUse = this.storedProcedureNameExpression.getValue(this.evaluationContext,
message, String.class);
Assert.hasText(storedProcedureNameToUse, String.format(
"Unable to resolve Stored Procedure/Function name for the provided Expression '%s'.",
this.storedProcedureNameExpression.getExpressionString()));
return storedProcedureNameToUse;
}
/**
* Execute the Stored Procedure using the passed in {@link Message} as a source
* for parameters.
*
* @param message The message is used to extract parameters for the stored procedure.
* @return A map containing the return values from the Stored Procedure call if any.
*/
private Map<String, Object> executeStoredProcedureInternal(Object input, String storedProcedureName) {
Assert.notNull(sqlParameterSourceFactory, "Property sqlParameterSourceFactory "
+ "was Null. Did you call afterPropertiesSet()?");
SimpleJdbcCallOperations localSimpleJdbcCall = this.jdbcCallOperationsCache.getUnchecked(storedProcedureName);
SqlParameterSource storedProcedureParameterSource =
sqlParameterSourceFactory.createParameterSource(input);
return StoredProcExecutor.executeStoredProcedure(localSimpleJdbcCall,
storedProcedureParameterSource);
}
/**
*/
private static Map<String, Object> executeStoredProcedure(SimpleJdbcCallOperations simpleJdbcCallOperations,
SqlParameterSource storedProcedureParameterSource) {
Map<String, Object> resultMap = simpleJdbcCallOperations.execute(storedProcedureParameterSource);
return resultMap;
}
//~~~~~Setters for Properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* from the JDBC Meta-data. However, if the used database does not support
* meta data lookups or if you like to provide customized parameter definitions,
* this flag can be set to 'true'. It defaults to 'false'.
*/
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.ignoreColumnMetaData = ignoreColumnMetaData;
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
Assert.notEmpty(procedureParameters, "procedureParameters must not be null or empty.");
for (ProcedureParameter procedureParameter : procedureParameters) {
Assert.notNull(procedureParameter, "The provided list (procedureParameters) cannot contain null values.");
}
this.procedureParameters = procedureParameters;
}
/**
* If you database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly.
*/
public void setSqlParameters(List<SqlParameter> sqlParameters) {
Assert.notEmpty(sqlParameters, "sqlParameters must not be null or empty.");
for (SqlParameter sqlParameter : sqlParameters) {
Assert.notNull(sqlParameter, "The provided list (sqlParameters) cannot contain null values.");
}
this.sqlParameters = sqlParameters;
}
/**
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
* you would like to provide a custom {@link SqlParameterSourceFactory},
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* If not the SqlParameterSourceFactory will be replaced the default
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* @param sqlParameterSourceFactory
*/
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
Assert.notNull(sqlParameterSourceFactory, "sqlParameterSourceFactory must not be null.");
this.sqlParameterSourceFactory = sqlParameterSourceFactory;
}
/**
* @return the name of the Stored Procedure or Function if set. Null otherwise.
* */
@ManagedAttribute(defaultValue="Null if not Set.")
public String getStoredProcedureName() {
return this.storedProcedureNameExpression instanceof LiteralExpression ?
storedProcedureNameExpression.getValue(String.class) : null;
}
/**
* @return the Stored Procedure Name Expression as a String if set. Null otherwise.
* */
@ManagedAttribute(defaultValue="Null if not Set.")
public String getStoredProcedureNameExpressionAsString() {
return this.storedProcedureNameExpression != null ? this.storedProcedureNameExpression.getExpressionString() : null;
}
/**
* The name of the Stored Procedure or Stored Function to be executed.
* If {@link StoredProcExecutor#isFunction} is set to "true", then this
* property specifies the Stored Function name.
*
* Alternatively you can also specify the Stored Procedure name via
* {@link StoredProcExecutor#setStoredProcedureNameExpression(Expression)}.
*
* E.g., that way you can specify the name of the Stored Procedure or Stored Function
* through {@link MessageHeaders}.
*
* @param storedProcedureName Must not be null and must not be empty
*
* @see StoredProcExecutor#setStoredProcedureNameExpression(Expression)
*/
public void setStoredProcedureName(String storedProcedureName) {
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
this.storedProcedureNameExpression = new LiteralExpression(storedProcedureName);
}
/**
* Using the {@link StoredProcExecutor#storedProcedureNameExpression} the
* {@link Message} can be used as source for the name of the
* Stored Procedure or Stored Function.
*
* If {@link StoredProcExecutor#isFunction} is set to "true", then this
* property specifies the Stored Function name.
*
* By providing a SpEL expression as value for this setter, a subset of the
* original payload, a header value or any other resolvable SpEL expression
* can be used as the basis for the Stored Procedure / Function.
*
* For the Expression evaluation the full message is available as the <b>root object</b>.
*
* For instance the following SpEL expressions (among others) are possible:
*
* <ul>
* <li>payload.foo</li>
* <li>headers.foobar</li>
* <li>new java.util.Date()</li>
* <li>'foo' + 'bar'</li>
* </ul>
*
* Alternatively you can also specify the Stored Procedure name via
* {@link StoredProcExecutor#setStoredProcedureName(String)}
*
* @param storedProcedureNameExpression Must not be null.
*
*/
public void setStoredProcedureNameExpression(Expression storedProcedureNameExpression) {
Assert.notNull(storedProcedureNameExpression, "storedProcedureNameExpression must not be null.");
this.storedProcedureNameExpression = storedProcedureNameExpression;
}
/**
* If set to 'true', the payload of the Message will be used as a source for
* providing parameters. If false the entire Message will be available as a
* source for parameters.
* providing parameters. If false the entire {@link Message} will be available
* as a source for parameters.
*
* If no {@link ProcedureParameter} are passed in, this property will default to
* 'true'. This means that using a default {@link BeanPropertySqlParameterSourceFactory}
* the bean properties of the payload will be used as a source for parameter values for
* the to-be-executed Stored Procedure or Function.
* <code>true</code>. This means that using a default {@link BeanPropertySqlParameterSourceFactory}
* the bean properties of the payload will be used as a source for parameter
* values for the to-be-executed Stored Procedure or Function.
*
* However, if {@link ProcedureParameter} are passed in, then this property
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
* SpEl Expressions to be provided and therefore it is highly beneficial to
* have access to the entire {@link Message}.
* However, if {@link ProcedureParameter}s are passed in, then this property
* will by default evaluate to <code>false</code>. {@link ProcedureParameter}
* allow for SpEl Expressions to be provided and therefore it is highly
* beneficial to have access to the entire {@link Message}.
*
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
*/
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.usePayloadAsParameterSource = usePayloadAsParameterSource;
}
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.usePayloadAsParameterSource = usePayloadAsParameterSource;
}
/**
* Indicates whether a Stored Procedure or a Function is being executed.
* The default value is false.
*
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
*
* @deprecated Please use {@link #setIsFunction(boolean)} instead.
*/
@Deprecated
public void setFunction(boolean isFunction) {
this.isFunction = isFunction;
}
/**
* Indicates whether a Stored Procedure or a Function is being executed.
@@ -373,19 +509,19 @@ public class StoredProcExecutor implements InitializingBean {
*
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
*/
public void setFunction(boolean isFunction) {
this.isFunction = isFunction;
}
public void setIsFunction(boolean isFunction) {
this.isFunction = isFunction;
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*/
public void setReturnValueRequired(boolean returnValueRequired) {
this.returnValueRequired = returnValueRequired;
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*/
public void setReturnValueRequired(boolean returnValueRequired) {
this.returnValueRequired = returnValueRequired;
}
/**
* If this variable is set to <code>true</code> then all results from a stored
@@ -402,26 +538,92 @@ public class StoredProcExecutor implements InitializingBean {
* the value defaults to <code>true</code>.
*
*/
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
this.skipUndeclaredResults = skipUndeclaredResults;
}
/**
* If the Stored Procedure returns ResultSets you may provide a map of
* {@link RowMapper} to convert the {@link ResultSet} to meaningful objects.
*
* @param returningResultSetRowMappers The map may not be null and must not contain null values.
*/
public void setReturningResultSetRowMappers(
Map<String, RowMapper<?>> returningResultSetRowMappers) {
* If the Stored Procedure returns ResultSets you may provide a map of
* {@link RowMapper} to convert the {@link ResultSet} to meaningful objects.
*
* @param returningResultSetRowMappers The map may not be null and must not contain null values.
*/
public void setReturningResultSetRowMappers(Map<String, RowMapper<?>> returningResultSetRowMappers) {
Assert.notNull(returningResultSetRowMappers, "returningResultSetRowMappers must not be null.");
Assert.notNull(returningResultSetRowMappers, "returningResultSetRowMappers must not be null.");
for (RowMapper<?> rowMapper : returningResultSetRowMappers.values()) {
Assert.notNull(rowMapper, "The provided map cannot contain null values.");
}
for (RowMapper<?> rowMapper : returningResultSetRowMappers.values()) {
Assert.notNull(rowMapper, "The provided map cannot contain null values.");
}
this.returningResultSetRowMappers = returningResultSetRowMappers;
}
this.returningResultSetRowMappers = returningResultSetRowMappers;
}
/**
* Allows for the retrieval of metrics ({@link CacheStats}}) for the
* {@link StoredProcExecutor#jdbcCallOperationsCache}, which is used to store
* instances of {@link SimpleJdbcCallOperations}.
*
* @return Cache statistics for {@link StoredProcExecutor#jdbcCallOperationsCache}
*/
public CacheStats getJdbcCallOperationsCacheStatistics() {
return this.jdbcCallOperationsCache.stats();
}
/**
* Allows for the retrieval of metrics ({@link CacheStats}}) for the
* {@link StoredProcExecutor#jdbcCallOperationsCache}.
*
* Provides the properties of {@link CacheStats} as a {@link Map}. This allows
* for exposing the those properties easily via JMX.
*
* @return Map containing metrics of the JdbcCallOperationsCache
*
* @see StoredProcExecutor#getJdbcCallOperationsCacheStatistics()
*/
@ManagedMetric
public Map<String, Object> getJdbcCallOperationsCacheStatisticsAsMap() {
final CacheStats cacheStats = this.getJdbcCallOperationsCacheStatistics();
final Map<String, Object> cacheStatistics = new HashMap<String, Object>(11);
cacheStatistics.put("averageLoadPenalty", cacheStats.averageLoadPenalty());
cacheStatistics.put("evictionCount", cacheStats.evictionCount());
cacheStatistics.put("hitCount", cacheStats.hitCount());
cacheStatistics.put("hitRate", cacheStats.hitRate());
cacheStatistics.put("loadCount", cacheStats.loadCount());
cacheStatistics.put("loadExceptionCount", cacheStats.loadExceptionCount());
cacheStatistics.put("loadExceptionRate", cacheStats.loadExceptionRate());
cacheStatistics.put("loadSuccessCount", cacheStats.loadSuccessCount());
cacheStatistics.put("missCount", cacheStats.missCount());
cacheStatistics.put("missRate", cacheStats.missRate());
cacheStatistics.put("totalLoadTime", cacheStats.totalLoadTime());
return Collections.unmodifiableMap(cacheStatistics);
}
/**
* Defines the maximum number of {@link SimpleJdbcCallOperations}
* ({@link SimpleJdbcCall}) instances to be held by
* {@link StoredProcExecutor#jdbcCallOperationsCache}.
*
* A value of zero will disable the cache. The default is 10.
*
* @see CacheBuilder#maximumSize(long)
* @param jdbcCallOperationsCacheSize Must not be negative.
*/
public void setJdbcCallOperationsCacheSize(int jdbcCallOperationsCacheSize) {
Assert.isTrue(jdbcCallOperationsCacheSize >= 0, "jdbcCallOperationsCacheSize must not be negative.");
this.jdbcCallOperationsCacheSize = jdbcCallOperationsCacheSize;
}
/**
* Allows to set the optional {@link BeanFactory} which is used to add a
* {@link BeanResolver} to the {@link StandardEvaluationContext}. If not set
* this property defaults to null.
*
* @param beanFactory If set must not be null.
*/
public void setBeanFactory(BeanFactory beanFactory) {
Assert.notNull(returningResultSetRowMappers, "returningResultSetRowMappers must not be null.");
this.beanFactory = beanFactory;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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
@@ -26,9 +26,9 @@ import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.core.simple.SimpleJdbcCallOperations;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.util.Assert;
/**
* A message handler that executes Stored Procedures for update purposes.
*
@@ -53,85 +53,135 @@ import org.springframework.util.Assert;
*/
public class StoredProcMessageHandler extends AbstractMessageHandler implements InitializingBean {
final StoredProcExecutor executor;
private final StoredProcExecutor executor;
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the name of the stored procedure or function to
* execute to retrieve new rows.
*
* @param dataSource used to create a {@link SimpleJdbcTemplate}. Must not be null.
* @param storedProcedureName The name of the Stored Procedure or Function. Must not be null.
*/
public StoredProcMessageHandler(DataSource dataSource, String storedProcedureName) {
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the name of the stored procedure or function to
* execute to retrieve new rows.
*
* @param dataSource Must not be null.
* @param storedProcedureName The name of the Stored Procedure or Function. Must not be null.
*
* @deprecated Since 2.2 use the constructor that expects a {@link StoredProcExecutor} instead
*/
@Deprecated
public StoredProcMessageHandler(DataSource dataSource, String storedProcedureName) {
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
this.executor = new StoredProcExecutor(dataSource);
this.executor.setStoredProcedureName(storedProcedureName);
}
}
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
@Override
protected void onInit() throws Exception {
super.onInit();
this.executor.afterPropertiesSet();
};
/**
*
* Constructor passing in the {@link StoredProcExecutor}.
*
* @param storedProcExecutor Must not be null.
*
*/
public StoredProcMessageHandler(StoredProcExecutor storedProcExecutor) {
/**
* Executes the Stored procedure, delegates to executeStoredProcedure(...).
* Any return values from the Stored procedure are ignored.
*
* Return values are logged at debug level, though.
*/
@Override
protected void handleMessageInternal(Message<?> message) {
Assert.notNull(storedProcExecutor, "storedProcExecutor must not be null.");
this.executor = storedProcExecutor;
Map<String, Object> resultMap = executor.executeStoredProcedure(message);
}
if (logger.isDebugEnabled()) {
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
@Override
protected void onInit() throws Exception {
super.onInit();
};
if (resultMap != null && !resultMap.isEmpty()) {
logger.debug(String.format("The StoredProcMessageHandler ignores return "
+ "values, but the called Stored Procedure '%s' returned the "
+ "following data: '%s'", executor.getStoredProcedureName(), resultMap));
}
/**
* Executes the Stored procedure, delegates to executeStoredProcedure(...).
* Any return values from the Stored procedure are ignored.
*
* Return values are logged at debug level, though.
*/
@Override
protected void handleMessageInternal(Message<?> message) {
}
Map<String, Object> resultMap = executor.executeStoredProcedure(message);
}
if (logger.isDebugEnabled()) {
//~~~~~Setters for Properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (resultMap != null && !resultMap.isEmpty()) {
logger.debug(String.format("The StoredProcMessageHandler ignores return "
+ "values, but the called Stored Procedure returned data: '%s'", executor.getStoredProcedureName(), resultMap));
}
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* from the JDBC Meta-data. However, if the used database does not support
* meta data lookups or if you like to provide customized parameter definitions,
* this flag can be set to <code>true</code>. It defaults to <code>false</code>.
*/
}
}
/**
* The name of the Stored Procedure or Stored Function to be executed.
* If {@link StoredProcExecutor#isFunction} is set to "true", then this
* property specifies the Stored Function name.
*
* Alternatively you can also specify the Stored Procedure name via
* {@link StoredProcExecutor#setStoredProcedureNameExpression(Expression)}.
*
* @param storedProcedureName Must not be null and must not be empty
*
* @see StoredProcExecutor#setStoredProcedureNameExpression(Expression)
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setStoredProcedureName(String)
*/
@Deprecated
public void setStoredProcedureName(String storedProcedureName) {
this.executor.setStoredProcedureName(storedProcedureName);
}
/**
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
* retrieve the parameter information for the to be invoked Stored Procedure
* from the JDBC Meta-data. However, if the used database does not support
* meta data lookups or if you like to provide customized parameter definitions,
* this flag can be set to <code>true</code>. It defaults to <code>false</code>.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setIgnoreColumnMetaData(boolean)
*/
@Deprecated
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setProcedureParameters(List)
*/
@Deprecated
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
this.executor.setProcedureParameters(procedureParameters);
}
/**
* If your database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly.
*/
/**
* If your database system is not fully supported by Spring and thus obtaining
* parameter definitions from the JDBC Meta-data is not possible, you must define
* the {@link SqlParameter} explicitly.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameters(List)
*/
@Deprecated
public void setSqlParameters(List<SqlParameter> sqlParameters) {
this.executor.setSqlParameters(sqlParameters);
}
@@ -140,16 +190,21 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
* you would like to provide a custom {@link SqlParameterSourceFactory},
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* If not the SqlParameterSourceFactory will be replaced by the default
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* @param sqlParameterSourceFactory
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameterSourceFactory(SqlParameterSourceFactory)
*/
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
@Deprecated
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
/**
* If set to 'true', the payload of the Message will be used as a source for
@@ -167,9 +222,14 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
* have access to the entire {@link Message}.
*
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setUsePayloadAsParameterSource(boolean)
*/
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
}
@Deprecated
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -33,8 +33,8 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.core.simple.SimpleJdbcCallOperations;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.util.Assert;
/**
@@ -48,128 +48,193 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
private volatile boolean expectSingleResult = false;
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the name of the stored procedure or function to
* execute to retrieve new rows.
*
* @param dataSource used to create a {@link SimpleJdbcTemplate}
* @param storedProcedureName
*/
public StoredProcOutboundGateway(DataSource dataSource, String storedProcedureName) {
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the name of the stored procedure or function to
* execute to retrieve new rows.
*
* @param dataSource used to create a {@link SimpleJdbcCall} instance
* @param storedProcedureName Must not be null.
*
* @deprecated Since 2.2 use the constructor that expects a {@link StoredProcExecutor} instead
*/
@Deprecated
public StoredProcOutboundGateway(DataSource dataSource, String storedProcedureName) {
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
this.executor = new StoredProcExecutor(dataSource);
this.executor.setStoredProcedureName(storedProcedureName);
}
}
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
@Override
protected void onInit() {
super.onInit();
this.executor.afterPropertiesSet();
};
/**
* Constructor taking {@link StoredProcExecutor}.
*
* @param storedProcExecutor Must not be null.
*
*/
public StoredProcOutboundGateway(StoredProcExecutor storedProcExecutor) {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
Assert.notNull(storedProcExecutor, "storedProcExecutor must not be null.");
this.executor = storedProcExecutor;
Map<String, Object> resultMap = executor.executeStoredProcedure(requestMessage);
}
final Object payload;
/**
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
* when {@link ProcedureParameter} are passed in.
*/
@Override
protected void onInit() {
super.onInit();
};
if (resultMap.isEmpty()) {
payload = null;
} else {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
if (this.expectSingleResult && resultMap.size() == 1) {
payload = resultMap.values().iterator().next();
} else if (this.expectSingleResult && resultMap.size() > 1) {
Map<String, Object> resultMap = executor.executeStoredProcedure(requestMessage);
throw new MessageHandlingException(requestMessage,
"Stored Procedure/Function call returned more than "
+ "1 result object and expectSingleResult was 'true'. ");
final Object payload;
} else {
payload = resultMap;
}
if (resultMap.isEmpty()) {
return null;
}
else {
}
if (this.expectSingleResult && resultMap.size() == 1) {
payload = resultMap.values().iterator().next();
}
else if (this.expectSingleResult && resultMap.size() > 1) {
return MessageBuilder.withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();
throw new MessageHandlingException(requestMessage,
"Stored Procedure/Function call returned more than "
+ "1 result object and expectSingleResult was 'true'. ");
}
}
else {
payload = resultMap;
}
/**
* Explicit declarations are necessary if the database you use is not a
* Spring-supported database. Currently Spring supports metadata lookup of
* stored procedure calls for the following databases:
*
* <ul>
* <li>Apache Derby</li>
* <li>DB2</li>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>Sybase</li>
* <li>PostgreSQL</li>
* </ul>
* , ,
* We also support metadata lookup of stored functions for the following
* databases:
*
* <ul>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>PostgreSQL</li>
* </ul>
*
* See also: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/jdbc.html
*/
public void setSqlParameters(List<SqlParameter> sqlParameters) {
this.executor.setSqlParameters(sqlParameters);
}
}
/**
* Does your stored procedure return one or more result sets? If so, you
* can use the provided method for setting the respective RowMappers.
*/
public void setReturningResultSetRowMappers(
Map<String, RowMapper<?>> returningResultSetRowMappers) {
this.executor.setReturningResultSetRowMappers(returningResultSetRowMappers);
}
return MessageBuilder.withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();
/**
* If true, the JDBC parameter definitions for the stored procedure are not
* automatically derived from the underlying JDBC connection. In that case
* you must pass in {@link SqlParameter} explicitly..
*
* @param ignoreColumnMetaData Defaults to <code>false</code>.
*/
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
}
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*/
public void setReturnValueRequired(boolean returnValueRequired) {
this.executor.setReturnValueRequired(returnValueRequired);
}
/**
* The name of the Stored Procedure or Stored Function to be executed.
* If {@link StoredProcExecutor#isFunction} is set to "true", then this
* property specifies the Stored Function name.
*
* Alternatively you can also specify the Stored Procedure name via
* {@link StoredProcExecutor#setStoredProcedureNameExpression(Expression)}.
*
* @param storedProcedureName Must not be null and must not be empty
*
* @see StoredProcExecutor#setStoredProcedureNameExpression(Expression)
* @see StoredProcExecutor#setStoredProcedureName(String)
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
*/
@Deprecated
public void setStoredProcedureName(String storedProcedureName) {
this.executor.setStoredProcedureName(storedProcedureName);
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
/**
* Explicit declarations are necessary if the database you use is not a
* Spring-supported database. Currently Spring supports metadata lookup of
* stored procedure calls for the following databases:
*
* <ul>
* <li>Apache Derby</li>
* <li>DB2</li>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>Sybase</li>
* <li>PostgreSQL</li>
* </ul>
* , ,
* We also support metadata lookup of stored functions for the following
* databases:
*
* <ul>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>PostgreSQL</li>
* </ul>
*
* See also: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/jdbc.html
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameters(List)
*/
@Deprecated
public void setSqlParameters(List<SqlParameter> sqlParameters) {
this.executor.setSqlParameters(sqlParameters);
}
/**
* Does your stored procedure return one or more result sets? If so, you
* can use the provided method for setting the respective RowMappers.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setReturningResultSetRowMappers(Map)
*/
@Deprecated
public void setReturningResultSetRowMappers(
Map<String, RowMapper<?>> returningResultSetRowMappers) {
this.executor.setReturningResultSetRowMappers(returningResultSetRowMappers);
}
/**
* If true, the JDBC parameter definitions for the stored procedure are not
* automatically derived from the underlying JDBC connection. In that case
* you must pass in {@link SqlParameter} explicitly..
*
* @param ignoreColumnMetaData Defaults to <code>false</code>.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setIgnoreColumnMetaData(boolean)
*/
@Deprecated
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setReturnValueRequired(boolean)
*/
@Deprecated
public void setReturnValueRequired(boolean returnValueRequired) {
this.executor.setReturnValueRequired(returnValueRequired);
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setProcedureParameters(List)
*/
@Deprecated
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
this.executor.setProcedureParameters(procedureParameters);
}
@@ -179,9 +244,14 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
* The default value is false.
*
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setIsFunction(boolean)
*/
@Deprecated
public void setIsFunction(boolean isFunction) {
this.executor.setFunction(isFunction);
this.executor.setIsFunction(isFunction);
}
/**
@@ -212,16 +282,21 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
* you would like to provide a custom {@link SqlParameterSourceFactory},
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* If not the SqlParameterSourceFactory will be replaced by the default
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* @param sqlParameterSourceFactory
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameterSourceFactory(SqlParameterSourceFactory)
*/
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
@Deprecated
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
/**
* If set to 'true', the payload of the Message will be used as a source for
@@ -239,10 +314,15 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
* have access to the entire {@link Message}.
*
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setUsePayloadAsParameterSource(boolean)
*/
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
}
@Deprecated
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
}
/**
* If this variable is set to <code>true</code> then all results from a stored
@@ -257,9 +337,14 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
*
* Only few developers will probably ever like to process update counts, thus
* the value defaults to <code>true</code>.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSkipUndeclaredResults(boolean)
*/
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
@Deprecated
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -46,167 +46,235 @@ import org.springframework.util.Assert;
*/
public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport implements MessageSource<Object> {
private final StoredProcExecutor executor;
private final StoredProcExecutor executor;
private volatile boolean expectSingleResult = false;
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the stored procedure name to execute.
*
* @param dataSource used to create a {@link SimpleJdbcCall}
* @param storedProcedureName Name of the Stored Procedure or Function to execute
*/
public StoredProcPollingChannelAdapter(DataSource dataSource, String storedProcedureName) {
/**
* Constructor taking {@link DataSource} from which the DB Connection can be
* obtained and the stored procedure name to execute.
*
* @param dataSource used to create a {@link SimpleJdbcCall}
* @param storedProcedureName Name of the Stored Procedure or Function to execute
*
* @deprecated Since 2.2 use the constructor that expects a {@link StoredProcExecutor} instead
*/
@Deprecated
public StoredProcPollingChannelAdapter(DataSource dataSource, String storedProcedureName) {
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
Assert.notNull(dataSource, "dataSource must not be null.");
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
this.executor = new StoredProcExecutor(dataSource);
this.executor.setStoredProcedureName(storedProcedureName);
}
@Override
protected void onInit() throws Exception {
super.onInit();
this.executor.afterPropertiesSet();
}
/**
* Executes the query. If a query result set contains one or more rows, the
* Message payload will contain either a List of Maps for each row or, if a
* RowMapper has been provided, the values mapped from those rows. If the
* query returns no rows, this method will return <code>null</code>.
*/
public Message<Object> receive() {
Object payload = poll();
if (payload == null) {
return null;
}
return MessageBuilder.withPayload(payload).build();
}
* Constructor taking {@link StoredProcExecutor}.
*
* @param storedProcExecutor Must not be null.
*
*/
public StoredProcPollingChannelAdapter(StoredProcExecutor storedProcExecutor) {
/**
* Execute the select query and the update query if provided. Returns the
* rows returned by the select query. If a RowMapper has been provided, the
* mapped results are returned.
*/
private Object poll() {
Assert.notNull(storedProcExecutor, "storedProcExecutor must not be null.");
this.executor = storedProcExecutor;
final Object payload;
}
Map<String, ?> resultMap = doPoll();
@Override
protected void onInit() throws Exception {
super.onInit();
}
if (resultMap.isEmpty()) {
payload = null;
} else {
/**
* Executes the query. If a query result set contains one or more rows, the
* Message payload will contain either a List of Maps for each row or, if a
* RowMapper has been provided, the values mapped from those rows. If the
* query returns no rows, this method will return <code>null</code>.
*/
public Message<Object> receive() {
Object payload = poll();
if (payload == null) {
return null;
}
return MessageBuilder.withPayload(payload).build();
}
if (this.expectSingleResult && resultMap.size() == 1) {
payload = resultMap.values().iterator().next();
} else if (this.expectSingleResult && resultMap.size() > 1) {
/**
* Execute the select query and the update query if provided. Returns the
* rows returned by the select query. If a RowMapper has been provided, the
* mapped results are returned.
*/
private Object poll() {
throw new MessagingException(
"Stored Procedure/Function call returned more than "
+ "1 result object and expectSingleResult was 'true'. ");
final Object payload;
} else {
payload = resultMap;
}
Map<String, ?> resultMap = doPoll();
}
if (resultMap.isEmpty()) {
payload = null;
}
else {
return payload;
if (this.expectSingleResult && resultMap.size() == 1) {
payload = resultMap.values().iterator().next();
}
else if (this.expectSingleResult && resultMap.size() > 1) {
}
throw new MessagingException(
"Stored Procedure/Function call returned more than "
+ "1 result object and expectSingleResult was 'true'. ");
protected Map<String, ?> doPoll() {
return this.executor.executeStoredProcedure();
}
}
else {
payload = resultMap;
}
public String getComponentType(){
return "stored-proc:inbound-channel-adapter";
}
}
return payload;
}
protected Map<String, ?> doPoll() {
return this.executor.executeStoredProcedure();
}
public String getComponentType(){
return "stored-proc:inbound-channel-adapter";
}
/**
* The name of the Stored Procedure or Stored Function to be executed.
* If {@link StoredProcExecutor#isFunction} is set to "true", then this
* property specifies the Stored Function name.
*
* Alternatively you can also specify the Stored Procedure name via
* {@link StoredProcExecutor#setStoredProcedureNameExpression(Expression)}.
*
* @param storedProcedureName Must not be null and must not be empty
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setStoredProcedureName(String)
*/
@Deprecated
public void setStoredProcedureName(String storedProcedureName) {
this.executor.setStoredProcedureName(storedProcedureName);
}
/**
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
* you would like to provide a custom {@link SqlParameterSourceFactory},
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* If not the SqlParameterSourceFactory will be replaced by the default
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
*
* @param sqlParameterSourceFactory
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameterSourceFactory(SqlParameterSourceFactory)
*/
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
@Deprecated
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
}
/**
* Explicit declarations are necessary if the database you use is not a
* Spring-supported database. Currently Spring supports metadata lookup of
* stored procedure calls for the following databases:
*
* <ul>
* <li>Apache Derby</li>
* <li>DB2</li>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>Sybase</li>
* <li>PostgreSQL</li>
* </ul>
* , ,
* We also support metadata lookup of stored functions for the following
* databases:
*
* <ul>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>PostgreSQL</li>
* </ul>
*
* See also: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/jdbc.html
*/
public void setSqlParameters(List<SqlParameter> sqlParameters) {
this.executor.setSqlParameters(sqlParameters);
}
/**
* Explicit declarations are necessary if the database you use is not a
* Spring-supported database. Currently Spring supports metadata lookup of
* stored procedure calls for the following databases:
*
* <ul>
* <li>Apache Derby</li>
* <li>DB2</li>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>Sybase</li>
* <li>PostgreSQL</li>
* </ul>
* , ,
* We also support metadata lookup of stored functions for the following
* databases:
*
* <ul>
* <li>MySQL</li>
* <li>Microsoft SQL Server</li>
* <li>Oracle</li>
* <li>PostgreSQL</li>
* </ul>
*
* See also: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/jdbc.html
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSqlParameters(List)
*/
@Deprecated
public void setSqlParameters(List<SqlParameter> sqlParameters) {
this.executor.setSqlParameters(sqlParameters);
}
/**
* Does your stored procedure return one or more result sets? If so, you
* can use the provided method for setting the respective Rowmappers.
*/
public void setReturningResultSetRowMappers(
Map<String, RowMapper<?>> returningResultSetRowMappers) {
this.executor.setReturningResultSetRowMappers(returningResultSetRowMappers);
}
/**
* Does your stored procedure return one or more result sets? If so, you
* can use the provided method for setting the respective Rowmappers.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setReturningResultSetRowMappers(Map)
*/
@Deprecated
public void setReturningResultSetRowMappers(
Map<String, RowMapper<?>> returningResultSetRowMappers) {
this.executor.setReturningResultSetRowMappers(returningResultSetRowMappers);
}
/**
* If true, the JDBC parameter definitions for the stored procedure are not
* automatically derived from the underlying JDBC connection. In that case
* you must pass in {@link SqlParameter} explicitly..
*
* @param ignoreColumnMetaData Defaults to <code>false</code>.
*/
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
}
/**
* If true, the JDBC parameter definitions for the stored procedure are not
* automatically derived from the underlying JDBC connection. In that case
* you must pass in {@link SqlParameter} explicitly..
*
* @param ignoreColumnMetaData Defaults to <code>false</code>.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setIgnoreColumnMetaData(boolean)
*/
@Deprecated
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*/
public void setReturnValueRequired(boolean returnValueRequired) {
this.executor.setReturnValueRequired(returnValueRequired);
}
/**
* Indicates the procedure's return value should be included in the results
* returned.
*
* @param returnValueRequired
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setReturnValueRequired(boolean)
*/
@Deprecated
public void setReturnValueRequired(boolean returnValueRequired) {
this.executor.setReturnValueRequired(returnValueRequired);
}
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*/
/**
* Custom Stored Procedure parameters that may contain static values
* or Strings representing an {@link Expression}.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setProcedureParameters(List)
*/
@Deprecated
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
this.executor.setProcedureParameters(procedureParameters);
}
@@ -216,9 +284,14 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
* The default value is false.
*
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setIsFunction(boolean)
*/
@Deprecated
public void setFunction(boolean isFunction) {
this.executor.setFunction(isFunction);
this.executor.setIsFunction(isFunction);
}
/**
@@ -259,9 +332,14 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
* Only few developers will probably ever like to process update counts, thus
* the value defaults to <code>true</code>.
*
* @deprecated Since 2.2 set the respective property on the passed-in {@link StoredProcExecutor}
*
* @see StoredProcExecutor#setSkipUndeclaredResults(boolean)
*
*/
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
@Deprecated
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
}
}

View File

@@ -1,73 +1,74 @@
/*
* Copyright 2002-2011 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.jdbc.config;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.JdbcMessageHandler;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
* @since 2.0
*
*/
public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(JdbcMessageHandler.class);
String dataSourceRef = element.getAttribute("data-source");
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
if ((refToDataSourceSet && refToJdbcOperationsSet)
|| (!refToDataSourceSet && !refToJdbcOperationsSet)) {
parserContext.getReaderContext().error(
"Exactly one of the attributes data-source or "
+ "simple-jdbc-operations should be set for the JDBC outbound-channel-adapter", source);
}
String query = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query", parserContext);
if (!StringUtils.hasText(query)) {
throw new BeanCreationException("The query attribute is required");
}
if (!StringUtils.hasText(query)) {
throw new BeanCreationException("The query attribute is required");
}
if (refToDataSourceSet) {
builder.addConstructorArgReference(dataSourceRef);
} else {
builder.addConstructorArgReference(jdbcOperationsRef);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
builder.addConstructorArgValue(query);
return builder.getBeanDefinition();
}
}
/*
* Copyright 2002-2012 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.jdbc.config;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.JdbcMessageHandler;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
* @since 2.0
*
*/
public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(JdbcMessageHandler.class);
String dataSourceRef = element.getAttribute("data-source");
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
if ((refToDataSourceSet && refToJdbcOperationsSet)
|| (!refToDataSourceSet && !refToJdbcOperationsSet)) {
parserContext.getReaderContext().error(
"Exactly one of the attributes data-source or "
+ "simple-jdbc-operations should be set for the JDBC outbound-channel-adapter", source);
}
String query = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query", parserContext);
if (!StringUtils.hasText(query)) {
throw new BeanCreationException("The query attribute is required");
}
if (!StringUtils.hasText(query)) {
throw new BeanCreationException("The query attribute is required");
}
if (refToDataSourceSet) {
builder.addConstructorArgReference(dataSourceRef);
}
else {
builder.addConstructorArgReference(jdbcOperationsRef);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
builder.addConstructorArgValue(query);
return builder.getBeanDefinition();
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -24,7 +24,7 @@ import org.w3c.dom.Element;
/**
* Parser for {@link org.springframework.integration.jdbc.JdbcMessageStore}.
*
*
* @author Dave Syer
* @since 2.0
*/
@@ -51,7 +51,8 @@ public class JdbcMessageStoreParser extends AbstractBeanDefinitionParser {
if (refToDataSourceSet) {
builder.addPropertyReference("dataSource", dataSourceRef);
} else {
}
else {
builder.addPropertyReference("jdbcTemplate", simpleJdbcOperationsRef);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -20,11 +20,11 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
/**
* Namespace handler for the integration JDBC schema.
*
*
* @author Jonas Partner
* @author Dave Syer
* @author Gunnar Hillert
*
*
* @since 2.0
*/
public class JdbcNamespaceHandler extends AbstractIntegrationNamespaceHandler {

View File

@@ -1,97 +1,97 @@
/*
* Copyright 2002-2011 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.jdbc.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.JdbcOutboundGateway;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
* @author Gunnar Hillert
*
* @since 2.0
*
*/
public class JdbcOutboundGatewayParser extends AbstractConsumerEndpointParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
String dataSourceRef = element.getAttribute("data-source");
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
if ((refToDataSourceSet && refToJdbcOperationsSet) || (!refToDataSourceSet && !refToJdbcOperationsSet)) {
parserContext.getReaderContext().error(
"Exactly one of the attributes data-source or "
+ "simple-jdbc-operations should be set for the JDBC outbound-gateway", element);
}
String selectQuery = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query",
parserContext);
if (!StringUtils.hasText(selectQuery)) {
selectQuery = null;
}
String updateQuery = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "update",
parserContext);
if (!StringUtils.hasText(updateQuery)) {
parserContext.getReaderContext().error("The update attribute is required", element);
return null;
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(JdbcOutboundGateway.class);
if (refToDataSourceSet) {
builder.addConstructorArgReference(dataSourceRef);
}
else {
builder.addConstructorArgReference(jdbcOperationsRef);
}
builder.getRawBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(1, updateQuery);
builder.getRawBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(2, selectQuery);
IntegrationNamespaceUtils
.setReferenceIfAttributeDefined(builder, element, "reply-sql-parameter-source-factory");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
"request-sql-parameter-source-factory");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "row-mapper");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows-per-poll");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "keys-generated");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
String replyChannel = element.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
builder.addPropertyReference("outputChannel", replyChannel);
}
return builder;
}
@Override
protected String getInputChannelAttributeName() {
return "request-channel";
}
}
/*
* Copyright 2002-2012 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.jdbc.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.JdbcOutboundGateway;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
* @author Gunnar Hillert
*
* @since 2.0
*
*/
public class JdbcOutboundGatewayParser extends AbstractConsumerEndpointParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
String dataSourceRef = element.getAttribute("data-source");
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
if ((refToDataSourceSet && refToJdbcOperationsSet) || (!refToDataSourceSet && !refToJdbcOperationsSet)) {
parserContext.getReaderContext().error(
"Exactly one of the attributes data-source or "
+ "simple-jdbc-operations should be set for the JDBC outbound-gateway", element);
}
String selectQuery = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query",
parserContext);
if (!StringUtils.hasText(selectQuery)) {
selectQuery = null;
}
String updateQuery = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "update",
parserContext);
if (!StringUtils.hasText(updateQuery)) {
parserContext.getReaderContext().error("The update attribute is required", element);
return null;
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(JdbcOutboundGateway.class);
if (refToDataSourceSet) {
builder.addConstructorArgReference(dataSourceRef);
}
else {
builder.addConstructorArgReference(jdbcOperationsRef);
}
builder.getRawBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(1, updateQuery);
builder.getRawBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(2, selectQuery);
IntegrationNamespaceUtils
.setReferenceIfAttributeDefined(builder, element, "reply-sql-parameter-source-factory");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
"request-sql-parameter-source-factory");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "row-mapper");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows-per-poll");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "keys-generated");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
String replyChannel = element.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
builder.addPropertyReference("outputChannel", replyChannel);
}
return builder;
}
@Override
protected String getInputChannelAttributeName() {
return "request-channel";
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -28,7 +28,7 @@ import org.w3c.dom.Element;
/**
* Parser for {@link org.springframework.integration.jdbc.JdbcPollingChannelAdapter}.
*
*
* @author Jonas Partner
* @since 2.0
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -20,50 +20,50 @@ import java.sql.Types;
import org.springframework.util.Assert;
/**
* This Enumeration provides a handy wrapper around {@link Types}. This makes it
* possible to look up String representation of the enum constant's name, and thus
* This Enumeration provides a handy wrapper around {@link Types}. This makes it
* possible to look up String representation of the enum constant's name, and thus
* looking up the respective JDBC Type (int-value).
*
*
* @author Gunnar Hillert
* @since 2.1
*
*
*/
public enum JdbcTypesEnum {
BIT(Types.BIT),
TINYINT(Types.TINYINT),
SMALLINT(Types.SMALLINT),
INTEGER(Types.INTEGER),
BIGINT(Types.BIGINT),
FLOAT(Types.FLOAT),
REAL(Types.REAL),
DOUBLE(Types.DOUBLE),
NUMERIC(Types.NUMERIC),
DECIMAL(Types.DECIMAL),
CHAR(Types.CHAR),
VARCHAR(Types.VARCHAR),
LONGVARCHAR(Types.LONGVARCHAR),
DATE(Types.DATE),
TIME(Types.TIME),
TIMESTAMP(Types.TIMESTAMP),
BINARY(Types.BINARY),
VARBINARY(Types.VARBINARY),
LONGVARBINARY(Types.LONGVARBINARY),
NULL(Types.NULL),
OTHER(Types.OTHER),
JAVA_OBJECT(Types.JAVA_OBJECT),
DISTINCT(Types.DISTINCT),
STRUCT(Types.STRUCT),
ARRAY(Types.ARRAY),
BLOB(Types.BLOB),
CLOB(Types.CLOB),
REF(Types.REF),
DATALINK(Types.DATALINK),
BOOLEAN(Types.BOOLEAN),
ROWID(Types.ROWID),
NCHAR(Types.NCHAR),
NVARCHAR(Types.NVARCHAR),
LONGNVARCHAR(Types.LONGNVARCHAR),
NCLOB(Types.NCLOB),
BIT(Types.BIT),
TINYINT(Types.TINYINT),
SMALLINT(Types.SMALLINT),
INTEGER(Types.INTEGER),
BIGINT(Types.BIGINT),
FLOAT(Types.FLOAT),
REAL(Types.REAL),
DOUBLE(Types.DOUBLE),
NUMERIC(Types.NUMERIC),
DECIMAL(Types.DECIMAL),
CHAR(Types.CHAR),
VARCHAR(Types.VARCHAR),
LONGVARCHAR(Types.LONGVARCHAR),
DATE(Types.DATE),
TIME(Types.TIME),
TIMESTAMP(Types.TIMESTAMP),
BINARY(Types.BINARY),
VARBINARY(Types.VARBINARY),
LONGVARBINARY(Types.LONGVARBINARY),
NULL(Types.NULL),
OTHER(Types.OTHER),
JAVA_OBJECT(Types.JAVA_OBJECT),
DISTINCT(Types.DISTINCT),
STRUCT(Types.STRUCT),
ARRAY(Types.ARRAY),
BLOB(Types.BLOB),
CLOB(Types.CLOB),
REF(Types.REF),
DATALINK(Types.DATALINK),
BOOLEAN(Types.BOOLEAN),
ROWID(Types.ROWID),
NCHAR(Types.NCHAR),
NVARCHAR(Types.NVARCHAR),
LONGNVARCHAR(Types.LONGNVARCHAR),
NCLOB(Types.NCLOB),
SQLXML(Types.SQLXML);
private int code;
@@ -74,34 +74,34 @@ public enum JdbcTypesEnum {
}
/**
* Get the numerical representation of the JDBC Type enum. The numerical value
* Get the numerical representation of the JDBC Type enum. The numerical value
* matches exactly the equivalent value in {@link Types}
*
*
* @return The numerical representation of the constant.
*/
public int getCode() {
return this.code;
}
/**
* Retrieves the matching enum constant for a provided String representation
* of the SQL Types. The provided name must match exactly the identifier as
/**
* Retrieves the matching enum constant for a provided String representation
* of the SQL Types. The provided name must match exactly the identifier as
* used to declare the enum constant.
*
*
* @param sqlTypeAsString Name of the enum to convert. Must be not null and not empty.
* @return The enumeration that matches. Returns Null of no match was found.
*
*
*/
public static JdbcTypesEnum convertToJdbcTypesEnum(String sqlTypeAsString) {
Assert.hasText(sqlTypeAsString, "Parameter sqlTypeAsString, must not be null nor empty");
for (JdbcTypesEnum jdbcType : JdbcTypesEnum.values()) {
if (jdbcType.name().equalsIgnoreCase(sqlTypeAsString)) {
return jdbcType;
}
}
if (jdbcType.name().equalsIgnoreCase(sqlTypeAsString)) {
return jdbcType;
}
}
return null;
}
}
}

View File

@@ -1,72 +1,62 @@
/*
* Copyright 2002-2011 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.jdbc.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcMessageHandler;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(StoredProcMessageHandler.class);
String dataSourceRef = element.getAttribute("data-source");
String storedProcedureName = element.getAttribute("stored-procedure-name");
builder.addConstructorArgReference(dataSourceRef);
builder.addConstructorArgValue(storedProcedureName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-column-meta-data");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "use-payload-as-parameter-source");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext);
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext);
if (!procedureParameterList.isEmpty()) {
builder.addPropertyValue("procedureParameters", procedureParameterList);
}
if (!sqlParameterDefinitionList.isEmpty()) {
builder.addPropertyValue("sqlParameters", sqlParameterDefinitionList);
}
return builder.getBeanDefinition();
}
}
/*
* Copyright 2002-2012 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.jdbc.config;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcMessageHandler;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcMessageHandler.class);
final BeanDefinitionBuilder storedProcExecutorBuilder = StoredProcParserUtils.getStoredProcExecutorBuilder(element, parserContext);
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "use-payload-as-parameter-source");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(storedProcExecutorBuilder, element, "sql-parameter-source-factory");
final AbstractBeanDefinition storedProcExecutorBuilderBeanDefinition = storedProcExecutorBuilder.getBeanDefinition();
final String messageHandlerId = this.resolveId(element, builder.getRawBeanDefinition(), parserContext);
final String storedProcExecutorBeanName = messageHandlerId + ".storedProcExecutor";
parserContext.registerBeanComponent(new BeanComponentDefinition(storedProcExecutorBuilderBeanDefinition, storedProcExecutorBeanName));
builder.addConstructorArgReference(storedProcExecutorBeanName);
return builder.getBeanDefinition();
}
}

View File

@@ -1,90 +1,87 @@
/*
* Copyright 2002-2011 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.jdbc.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcOutboundGateway;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanDefinitionBuilder parseHandler(Element gatewayElement, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(StoredProcOutboundGateway.class);
String dataSourceRef = gatewayElement.getAttribute("data-source");
String storedProcedureName = gatewayElement.getAttribute("stored-procedure-name");
builder.addConstructorArgReference(dataSourceRef);
builder.addConstructorArgValue(storedProcedureName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "is-function");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "ignore-column-meta-data");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "expect-single-result");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "return-value-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "use-payload-as-parameter-source");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, gatewayElement, "sql-parameter-source-factory");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "skip-undeclared-results");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "reply-timeout", "sendTimeout");
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(gatewayElement, parserContext);
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(gatewayElement, parserContext);
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(gatewayElement, parserContext);
if (!procedureParameterList.isEmpty()) {
builder.addPropertyValue("procedureParameters", procedureParameterList);
}
if (!sqlParameterDefinitionList.isEmpty()) {
builder.addPropertyValue("sqlParameters", sqlParameterDefinitionList);
}
if (!returningResultsetMap.isEmpty()) {
builder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap);
}
String replyChannel = gatewayElement.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
builder.addPropertyReference("outputChannel", replyChannel);
}
return builder;
}
@Override
protected String getInputChannelAttributeName() {
return "request-channel";
}
}
/*
* Copyright 2002-2012 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.jdbc.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcOutboundGateway;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcOutboundGateway.class);
final BeanDefinitionBuilder storedProcExecutorBuilder = StoredProcParserUtils.getStoredProcExecutorBuilder(element, parserContext);
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "is-function");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "return-value-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "use-payload-as-parameter-source");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(storedProcExecutorBuilder, element, "sql-parameter-source-factory");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "skip-undeclared-results");
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext);
if (!returningResultsetMap.isEmpty()) {
storedProcExecutorBuilder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap);
}
final AbstractBeanDefinition storedProcExecutorBuilderBeanDefinition = storedProcExecutorBuilder.getBeanDefinition();
final String gatewayId = this.resolveId(element, builder.getRawBeanDefinition(), parserContext);
final String storedProcExecutorBeanName = gatewayId + ".storedProcExecutor";
parserContext.registerBeanComponent(new BeanComponentDefinition(storedProcExecutorBuilderBeanDefinition, storedProcExecutorBeanName));
builder.addConstructorArgReference(storedProcExecutorBeanName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
String replyChannel = element.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
builder.addPropertyReference("outputChannel", replyChannel);
}
return builder;
}
@Override
protected String getInputChannelAttributeName() {
return "request-channel";
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -27,10 +27,15 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcExecutor;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.jdbc.core.SqlInOutParameter;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -47,7 +52,7 @@ public final class StoredProcParserUtils {
private StoredProcParserUtils() {
throw new AssertionError();
}
/**
* @param storedProcComponent
* @param parserContext
@@ -56,54 +61,59 @@ public final class StoredProcParserUtils {
Element storedProcComponent, ParserContext parserContext) {
List<Element> sqlParameterDefinitionChildElements = DomUtils.getChildElementsByTagName(storedProcComponent, "sql-parameter-definition");
ManagedList<BeanDefinition> sqlParameterList = new ManagedList<BeanDefinition>();
for (Element childElement : sqlParameterDefinitionChildElements) {
String name = childElement.getAttribute("name");
String sqlType = childElement.getAttribute("type");
String direction = childElement.getAttribute("direction");
String scale = childElement.getAttribute("scale");
final BeanDefinitionBuilder parameterBuilder;
if ("OUT".equalsIgnoreCase(direction)) {
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlOutParameter.class);
} else if ("INOUT".equalsIgnoreCase(direction)) {
}
else if ("INOUT".equalsIgnoreCase(direction)) {
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlInOutParameter.class);
} else {
}
else {
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlParameter.class);
}
if (StringUtils.hasText(name)) {
parameterBuilder.addConstructorArgValue(name);
} else {
}
else {
parserContext.getReaderContext().error(
"The 'name' attribute must be set for the Sql parameter element.", storedProcComponent);
}
if (StringUtils.hasText(sqlType)) {
JdbcTypesEnum jdbcTypeEnum = JdbcTypesEnum.convertToJdbcTypesEnum(sqlType);
if (jdbcTypeEnum != null) {
parameterBuilder.addConstructorArgValue(jdbcTypeEnum.getCode());
} else {
}
else {
parameterBuilder.addConstructorArgValue(sqlType);
}
} else {
}
else {
parameterBuilder.addConstructorArgValue(Types.VARCHAR);
}
if (StringUtils.hasText(scale)) {
parameterBuilder.addConstructorArgValue(new TypedStringValue(scale, Integer.class));
}
sqlParameterList.add(parameterBuilder.getBeanDefinition());
}
return sqlParameterList;
return sqlParameterList;
}
/**
* @param storedProcComponent
* @param parserContext
@@ -127,7 +137,7 @@ public final class StoredProcParserUtils {
if (StringUtils.hasText(name)) {
parameterBuilder.addPropertyValue("name", name);
}
}
if (StringUtils.hasText(expression)) {
parameterBuilder.addPropertyValue("expression", expression);
@@ -136,18 +146,19 @@ public final class StoredProcParserUtils {
if (StringUtils.hasText(value)) {
if (!StringUtils.hasText(type)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String
.format("Type attribute not set for Store "
+ "Procedure parameter '%s'. Defaulting to "
+ "'java.lang.String'.", value));
.format("Type attribute not set for Store "
+ "Procedure parameter '%s'. Defaulting to "
+ "'java.lang.String'.", value));
}
parameterBuilder.addPropertyValue("value",
new TypedStringValue(value, String.class));
} else {
}
else {
parameterBuilder.addPropertyValue("value",
new TypedStringValue(value, type));
}
@@ -169,26 +180,26 @@ public final class StoredProcParserUtils {
Element storedProcComponent, ParserContext parserContext) {
List<Element> returningResultsetChildElements = DomUtils.getChildElementsByTagName(storedProcComponent, "returning-resultset");
ManagedMap<String, BeanDefinition> returningResultsetMap = new ManagedMap<String, BeanDefinition>();
for (Element childElement : returningResultsetChildElements) {
String name = childElement.getAttribute("name");
String rowMapperAsString = childElement.getAttribute("row-mapper");
if (!StringUtils.hasText(name)) {
parserContext.getReaderContext().error(
"The 'name' attribute must be set for the 'returning-resultset' element.", storedProcComponent);
}
}
if (!StringUtils.hasText(rowMapperAsString)) {
parserContext.getReaderContext().error(
"The 'row-mapper' attribute must be set for the 'returning-resultset' element.", storedProcComponent);
}
BeanDefinitionBuilder rowMapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(rowMapperAsString);
returningResultsetMap.put(name, rowMapperBuilder.getBeanDefinition());
}
@@ -196,4 +207,62 @@ public final class StoredProcParserUtils {
}
/**
* Create a new {@link BeanDefinitionBuilder} for the class {@link StoredProcExecutor}.
* Initialize the wrapped {@link StoredProcExecutor} with common properties.
*
* @param element Must not be Null
* @param parserContext Must not be Null
* @return The {@link BeanDefinitionBuilder} for the {@link StoredProcExecutor}
*/
public static BeanDefinitionBuilder getStoredProcExecutorBuilder(final Element element,
final ParserContext parserContext) {
Assert.notNull(element, "The provided element must not be Null.");
Assert.notNull(parserContext, "The provided parserContext must not be Null.");
final String dataSourceRef = element.getAttribute("data-source");
final BeanDefinitionBuilder storedProcExecutorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcExecutor.class);
storedProcExecutorBuilder.addConstructorArgReference(dataSourceRef);
final String storedProcedureName = element.getAttribute("stored-procedure-name");
final String storedProcedureNameExpression = element.getAttribute("stored-procedure-name-expression");
boolean hasStoredProcedureName = StringUtils.hasText(storedProcedureName);
boolean hasStoredProcedureNameExpression = StringUtils.hasText(storedProcedureNameExpression);
if (!(hasStoredProcedureName ^ hasStoredProcedureNameExpression)) {
parserContext.getReaderContext()
.error("Exactly one of 'stored-procedure-name' or 'stored-procedure-name-expression' is required",
element);
}
BeanDefinitionBuilder expressionBuilder;
if (hasStoredProcedureNameExpression) {
expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class);
expressionBuilder.addConstructorArgValue(storedProcedureNameExpression);
}
else {
expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(LiteralExpression.class);
expressionBuilder.addConstructorArgValue(storedProcedureName);
}
storedProcExecutorBuilder.addPropertyValue("storedProcedureNameExpression", expressionBuilder.getBeanDefinition());
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "ignore-column-meta-data");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "jdbc-call-operations-cache-size");
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext);
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext);
if (!procedureParameterList.isEmpty()) {
storedProcExecutorBuilder.addPropertyValue("procedureParameters", procedureParameterList);
}
if (!sqlParameterDefinitionList.isEmpty()) {
storedProcExecutorBuilder.addPropertyValue("sqlParameters", sqlParameterDefinitionList);
}
return storedProcExecutorBuilder;
}
}

View File

@@ -1,77 +1,74 @@
/*
* Copyright 2002-2011 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.jdbc.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcPollingChannelAdapter;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcPollingChannelAdapter.class);
String dataSourceRef = element.getAttribute("data-source");
String storedProcedureName = element.getAttribute("stored-procedure-name");
builder.addConstructorArgReference(dataSourceRef);
builder.addConstructorArgValue(storedProcedureName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-column-meta-data");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "return-value-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "function");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "skip-undeclared-results");
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext);
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext);
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext);
if (!procedureParameterList.isEmpty()) {
builder.addPropertyValue("procedureParameters", procedureParameterList);
}
if (!sqlParameterDefinitionList.isEmpty()) {
builder.addPropertyValue("sqlParameters", sqlParameterDefinitionList);
}
if (!returningResultsetMap.isEmpty()) {
builder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap);
}
return builder.getBeanDefinition();
}
}
/*
* Copyright 2002-2012 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.jdbc.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jdbc.StoredProcPollingChannelAdapter;
import org.w3c.dom.Element;
/**
* @author Gunnar Hillert
* @since 2.1
*
*/
public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcPollingChannelAdapter.class);
final BeanDefinitionBuilder storedProcExecutorBuilder = StoredProcParserUtils.getStoredProcExecutorBuilder(element, parserContext);
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "return-value-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "function");
IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "skip-undeclared-results");
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext);
if (!returningResultsetMap.isEmpty()) {
storedProcExecutorBuilder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap);
}
final AbstractBeanDefinition storedProcExecutorBuilderBeanDefinition = storedProcExecutorBuilder.getBeanDefinition();
final String storedProcPollingChannelAdapterId = this.resolveId(element, builder.getRawBeanDefinition(), parserContext);
final String storedProcExecutorBeanName = storedProcPollingChannelAdapterId + ".storedProcExecutor";
parserContext.registerBeanComponent(new BeanComponentDefinition(storedProcExecutorBuilderBeanDefinition, storedProcExecutorBeanName));
builder.addConstructorArgReference(storedProcExecutorBeanName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
return builder.getBeanDefinition();
}
}

View File

@@ -1,5 +1,5 @@
/**
* Root package of the Spring Integration JDBC module, which contains various
* JDBC and Stored Procedure/Function supporting components.
* JDBC and Stored Procedure/Function supporting components.
*/
package org.springframework.integration.jdbc;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -22,8 +22,8 @@ import java.util.Map;
import org.springframework.util.Assert;
/**
* Abstraction of Procedure parameters allowing to provide static parameters
* and SpEl Expression based parameters.
* Abstraction of Procedure parameters allowing to provide static parameters
* and SpEl Expression based parameters.
*
* @author Gunnar Hillert
* @since 2.1
@@ -31,113 +31,113 @@ import org.springframework.util.Assert;
*/
public class ProcedureParameter {
private String name;
private Object value;
private String expression;
private String name;
private Object value;
private String expression;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return this.value;
}
public void setValue(Object value) {
this.value = value;
}
public String getExpression() {
return this.expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return this.value;
}
public void setValue(Object value) {
this.value = value;
}
public String getExpression() {
return this.expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
/**
* Instantiates a new Procedure Parameter.
*
* @param name Name of the procedure parameter, must not be null or empty
* @param value If null, the expression property must be set
* @param expression If null, the value property must be set
*/
public ProcedureParameter(String name, Object value, String expression) {
super();
Assert.hasText(name, "'name' must not be empty.");
/**
* Instantiates a new Procedure Parameter.
*
* @param name Name of the procedure parameter, must not be null or empty
* @param value If null, the expression property must be set
* @param expression If null, the value property must be set
*/
public ProcedureParameter(String name, Object value, String expression) {
super();
Assert.hasText(name, "'name' must not be empty.");
this.name = name;
this.value = value;
this.expression = expression;
}
this.name = name;
this.value = value;
this.expression = expression;
}
/**
* Default constructor.
*/
public ProcedureParameter() {
super();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ProcedureParameter [name=").append(this.name)
.append(", value=").append(this.value)
.append(", expression=").append(this.expression)
.append("]");
return builder.toString();
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ProcedureParameter [name=").append(this.name)
.append(", value=").append(this.value)
.append(", expression=").append(this.expression)
.append("]");
return builder.toString();
}
/**
* Utility method that converts a Collection of {@link ProcedureParameter} to
* a Map containing only expression parameters.
*
* @param procedureParameters Must not be null.
*
* @param procedureParameters Must not be null.
* @return Map containing only the Expression bound parameters. Will never be null.
*/
public static Map<String, String> convertExpressions(Collection<ProcedureParameter> procedureParameters) {
Assert.notNull(procedureParameters, "The Collection of procedureParameters must not be null.");
for (ProcedureParameter parameter : procedureParameters) {
Assert.notNull(parameter, "'procedureParameters' must not contain null values.");
}
Map<String, String> staticParameters = new HashMap<String, String>();
for (ProcedureParameter parameter : procedureParameters) {
if (parameter.getExpression() != null) {
staticParameters.put(parameter.getName(), parameter.getExpression());
}
}
return staticParameters;
}
public static Map<String, String> convertExpressions(Collection<ProcedureParameter> procedureParameters) {
Assert.notNull(procedureParameters, "The Collection of procedureParameters must not be null.");
for (ProcedureParameter parameter : procedureParameters) {
Assert.notNull(parameter, "'procedureParameters' must not contain null values.");
}
Map<String, String> staticParameters = new HashMap<String, String>();
for (ProcedureParameter parameter : procedureParameters) {
if (parameter.getExpression() != null) {
staticParameters.put(parameter.getName(), parameter.getExpression());
}
}
return staticParameters;
}
/**
* Utility method that converts a Collection of {@link ProcedureParameter} to
* a Map containing only static parameters.
*
* @param procedureParameters Must not be null.
*
* @param procedureParameters Must not be null.
* @return Map containing only the static parameters. Will never be null.
*/
public static Map<String, Object> convertStaticParameters(Collection<ProcedureParameter> procedureParameters) {
Assert.notNull(procedureParameters, "The Collection of procedureParameters must not be null.");
for (ProcedureParameter parameter : procedureParameters) {
Assert.notNull(parameter, "'procedureParameters' must not contain null values.");
}
Map<String, Object> staticParameters = new HashMap<String, Object>();
for (ProcedureParameter parameter : procedureParameters) {
if (parameter.getValue() != null) {
staticParameters.put(parameter.getName(), parameter.getValue());
}
}
return staticParameters;
}
public static Map<String, Object> convertStaticParameters(Collection<ProcedureParameter> procedureParameters) {
Assert.notNull(procedureParameters, "The Collection of procedureParameters must not be null.");
for (ProcedureParameter parameter : procedureParameters) {
Assert.notNull(parameter, "'procedureParameters' must not contain null values.");
}
Map<String, Object> staticParameters = new HashMap<String, Object>();
for (ProcedureParameter parameter : procedureParameters) {
if (parameter.getValue() != null) {
staticParameters.put(parameter.getName(), parameter.getValue());
}
}
return staticParameters;
}
}

View File

@@ -27,18 +27,35 @@ import java.util.Map;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.expression.Expression;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import com.google.common.cache.CacheStats;
@RunWith(PowerMockRunner.class)
@PrepareForTest({StoredProcExecutor.class})
@PowerMockIgnore ({"org.apache.log4j.*"})
public class StoredProcExecutorTests {
private static final Logger LOGGER = Logger.getLogger(StoredProcExecutorTests.class);
@Test
public void testStoredProcExecutorWithNullDataSource() {
try {
new StoredProcExecutor(null, "storedProcedureName");
new StoredProcExecutor(null);
} catch (IllegalArgumentException e) {
assertEquals("dataSource must not be null.", e.getMessage());
return;
@@ -53,9 +70,11 @@ public class StoredProcExecutorTests {
DataSource datasource = mock(DataSource.class);
try {
new StoredProcExecutor(datasource, null);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
storedProcExecutor.afterPropertiesSet();
} catch (IllegalArgumentException e) {
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
assertEquals("You must either provide a "
+ "Stored Procedure Name or a Stored Procedure Name Expression.", e.getMessage());
return;
}
@@ -66,9 +85,10 @@ public class StoredProcExecutorTests {
public void testStoredProcExecutorWithEmptyProcedureName() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
try {
new StoredProcExecutor(datasource, " ");
storedProcExecutor.setStoredProcedureName(" ");
} catch (IllegalArgumentException e) {
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
return;
@@ -77,11 +97,40 @@ public class StoredProcExecutorTests {
fail("Exception expected.");
}
@Test
public void testGetStoredProcedureNameExpressionAsString() throws Exception {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
final ExpressionFactoryBean efb = new ExpressionFactoryBean("headers['stored_procedure_name']");
efb.afterPropertiesSet();
final Expression expression = efb.getObject();
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
assertEquals("headers['stored_procedure_name']", storedProcExecutor.getStoredProcedureNameExpressionAsString());
}
@Test
public void testGetStoredProcedureNameExpressionAsString2() throws Exception {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
storedProcExecutor.setStoredProcedureName("123");
storedProcExecutor.afterPropertiesSet();
assertEquals("123", storedProcExecutor.getStoredProcedureName());
assertEquals("123", storedProcExecutor.getStoredProcedureNameExpressionAsString());
}
@Test
public void testSetReturningResultSetRowMappersWithNullMap() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
try {
storedProcExecutor.setReturningResultSetRowMappers(null);
@@ -98,7 +147,7 @@ public class StoredProcExecutorTests {
public void testSetReturningResultSetRowMappersWithMapContainingNullValues() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
rowmappers.put("results", null);
@@ -118,7 +167,7 @@ public class StoredProcExecutorTests {
public void testSetReturningResultSetRowMappersWithEmptyMap() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
@@ -131,7 +180,7 @@ public class StoredProcExecutorTests {
@Test
public void testSetSqlParameterSourceFactoryWithNullParameter() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
try {
storedProcExecutor.setSqlParameterSourceFactory(null);
@@ -148,7 +197,7 @@ public class StoredProcExecutorTests {
public void testSetSqlParametersWithNullValueInList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
sqlParameters.add(null);
@@ -168,7 +217,7 @@ public class StoredProcExecutorTests {
public void testSetSqlParametersWithEmptyList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
@@ -187,7 +236,7 @@ public class StoredProcExecutorTests {
public void testSetSqlParametersWithNullList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
try {
storedProcExecutor.setSqlParameters(null);
@@ -204,7 +253,7 @@ public class StoredProcExecutorTests {
public void testSetProcedureParametersWithNullValueInList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
procedureParameters.add(null);
@@ -224,7 +273,7 @@ public class StoredProcExecutorTests {
public void testSetProcedureParametersWithEmptyList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
@@ -243,7 +292,7 @@ public class StoredProcExecutorTests {
public void testSetProcedureParametersWithNullList() {
DataSource datasource = mock(DataSource.class);
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
try {
storedProcExecutor.setProcedureParameters(null);
@@ -256,4 +305,118 @@ public class StoredProcExecutorTests {
}
@Test
public void testStoredProcExecutorWithNonResolvingExpression() throws Exception {
final DataSource datasource = mock(DataSource.class);
PowerMockito.mockStatic(StoredProcExecutor.class);
PowerMockito.spy(StoredProcExecutor.class);
PowerMockito.doReturn(null).when(StoredProcExecutor.class, "executeStoredProcedure", Mockito.any(), Mockito.any());
final StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
final ExpressionFactoryBean efb = new ExpressionFactoryBean("headers['stored_procedure_name']");
efb.afterPropertiesSet();
final Expression expression = efb.getObject();
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
//This should work
storedProcExecutor.executeStoredProcedure(
MessageBuilder.withPayload("test")
.setHeader("stored_procedure_name", "123")
.build());
//This should cause an exception
try {
storedProcExecutor.executeStoredProcedure(
MessageBuilder.withPayload("test")
.setHeader("some_other_header", "123")
.build());
} catch (IllegalArgumentException e) {
assertEquals("Unable to resolve Stored Procedure/Function name for the provided Expression 'headers['stored_procedure_name']'.", e.getMessage());
return;
}
fail("IllegalArgumentException expected.");
}
@Test
public void testStoredProcExecutorJdbcCallOperationsCache() throws Exception {
final DataSource datasource = mock(DataSource.class);
PowerMockito.mockStatic(StoredProcExecutor.class);
PowerMockito.spy(StoredProcExecutor.class);
PowerMockito.doReturn(null).when(StoredProcExecutor.class, "executeStoredProcedure", Mockito.any(), Mockito.any());
final StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
final ExpressionFactoryBean efb = new ExpressionFactoryBean("headers['stored_procedure_name']");
efb.afterPropertiesSet();
final Expression expression = efb.getObject();
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
for (int i = 1; i <= 3; i++) {
storedProcExecutor.executeStoredProcedure(
MessageBuilder.withPayload("test")
.setHeader("stored_procedure_name", "123")
.build());
}
final CacheStats stats = storedProcExecutor.getJdbcCallOperationsCacheStatistics();
LOGGER.info(stats);
LOGGER.info(stats.totalLoadTime() / 1000 / 1000);
assertEquals(stats.hitCount(), 2);
assertEquals(stats.missCount(), 1);
assertEquals(stats.loadCount(), 1);
}
@Test
public void testSetJdbcCallOperationsCacheSize() throws Exception {
final DataSource datasource = mock(DataSource.class);
PowerMockito.mockStatic(StoredProcExecutor.class);
PowerMockito.spy(StoredProcExecutor.class);
PowerMockito.doReturn(null).when(StoredProcExecutor.class, "executeStoredProcedure", Mockito.any(), Mockito.any());
final StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource);
storedProcExecutor.setJdbcCallOperationsCacheSize(0);
final ExpressionFactoryBean efb = new ExpressionFactoryBean("headers['stored_procedure_name']");
efb.afterPropertiesSet();
final Expression expression = efb.getObject();
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
for (int i = 1; i <= 10; i++) {
storedProcExecutor.executeStoredProcedure(
MessageBuilder.withPayload("test")
.setHeader("stored_procedure_name", "123")
.build());
}
final CacheStats stats = storedProcExecutor.getJdbcCallOperationsCacheStatistics();
LOGGER.info(stats);
assertEquals("Expected a cache misscount of 10", 10, stats.missCount());
}
}

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:mbean-server />
<context:mbean-export default-domain="org.springframework.integration.jdbc.test" />
<import resource="classpath:derby-stored-procedures-setup-context.xml"/>
<int:poller id="defaultPoller" default="true" fixed-delay="55000"/>
<int:gateway id="startGateway" default-request-channel="startChannel"
service-interface="org.springframework.integration.jdbc.storedproc.CreateUser" />
<int:channel id="startChannel"/>
<int-jdbc:stored-proc-outbound-gateway id="my gateway"
request-channel="startChannel"
stored-procedure-name="CREATE_USER_RETURN_ALL"
data-source="dataSource"
auto-startup="true"
ignore-column-meta-data="false"
is-function="false"
expect-single-result="true"
reply-channel="outputChannel">
<int-jdbc:parameter name="username" expression="payload.username"/>
<int-jdbc:parameter name="password" expression="payload.password"/>
<int-jdbc:parameter name="email" expression="payload.email"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.UserMapper" />
</int-jdbc:stored-proc-outbound-gateway>
<int:channel id="outputChannel"/>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcJmxManagedBeanTests$Consumer"/>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
<int-jdbc:stored-proc-outbound-channel-adapter id="outboundChannelAdapter"
stored-procedure-name="CREATE_USER" data-source="dataSource"
auto-startup="true"
ignore-column-meta-data="false">
<int-jdbc:parameter name="username" expression="payload.username"/>
<int-jdbc:parameter name="password" expression="payload.password"/>
<int-jdbc:parameter name="email" expression="payload.email"/>
</int-jdbc:stored-proc-outbound-channel-adapter>
<int-jdbc:stored-proc-inbound-channel-adapter channel="outputChannel"
data-source="dataSource" auto-startup="false"
stored-procedure-name="CREATE_USER" id="inbound-channel-adapter">
<int-jdbc:parameter name="username" value="name"/>
<int-jdbc:parameter name="password" value="dummy"/>
<int-jdbc:parameter name="email" value="email"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
</beans>

View File

@@ -0,0 +1,194 @@
/*
* Copyright 2002-2012 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.jdbc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.jdbc.storedproc.CreateUser;
import org.springframework.integration.jdbc.storedproc.User;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gunnar Hillert
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class StoredProcJmxManagedBeanTests {
@Autowired
private AbstractApplicationContext context;
@Autowired
private Consumer consumer;
@Autowired
CreateUser userService;
@Test
@SuppressWarnings("unchecked")
public void testCollectJmxAttributes() throws Exception {
final List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
assertEquals(1, servers.size());
final MBeanServer server = servers.iterator().next();
// MessageHandler
final Set<ObjectName> messageHandlerObjectNames = server.queryNames(ObjectName.getInstance("org.springframework.integration.jdbc.test:name=outboundChannelAdapter.adapter.storedProcExecutor,*"), null);
assertEquals(1, messageHandlerObjectNames.size());
ObjectName messageHandlerObjectName = messageHandlerObjectNames.iterator().next();
Map<String, Object> messageHandlerCacheStatistics = (Map<String, Object>) server.getAttribute(messageHandlerObjectName, "JdbcCallOperationsCacheStatisticsAsMap");
assertEquals(11, messageHandlerCacheStatistics.size());
assertEquals(Long.valueOf(0), messageHandlerCacheStatistics.get("hitCount"));
assertEquals(Long.valueOf(0), messageHandlerCacheStatistics.get("loadCount"));
assertEquals(Long.valueOf(0), messageHandlerCacheStatistics.get("loadExceptionCount"));
assertEquals(Long.valueOf(0), messageHandlerCacheStatistics.get("loadSuccessCount"));
assertEquals(Long.valueOf(0), messageHandlerCacheStatistics.get("missCount"));
// StoredProcOutboundGateway
final Set<ObjectName> storedProcOutboundGatewayObjectNames = server.queryNames(ObjectName.getInstance("org.springframework.integration.jdbc.test:name=my gateway.storedProcExecutor,*"), null);
assertEquals(1, storedProcOutboundGatewayObjectNames.size());
ObjectName storedProcOutboundGatewayObjectName = storedProcOutboundGatewayObjectNames.iterator().next();
Map<String, Object> storedProcOutboundGatewayCacheStatistics = (Map<String, Object>) server.getAttribute(storedProcOutboundGatewayObjectName, "JdbcCallOperationsCacheStatisticsAsMap");
assertEquals(11, messageHandlerCacheStatistics.size());
assertEquals(Long.valueOf(0), storedProcOutboundGatewayCacheStatistics.get("hitCount"));
assertEquals(Long.valueOf(0), storedProcOutboundGatewayCacheStatistics.get("loadCount"));
assertEquals(Long.valueOf(0), storedProcOutboundGatewayCacheStatistics.get("loadExceptionCount"));
assertEquals(Long.valueOf(0), storedProcOutboundGatewayCacheStatistics.get("loadSuccessCount"));
assertEquals(Long.valueOf(0), storedProcOutboundGatewayCacheStatistics.get("missCount"));
// StoredProcPollingChannelAdapter
final Set<ObjectName> storedProcPollingChannelAdapterObjectNames = server.queryNames(ObjectName.getInstance("org.springframework.integration.jdbc.test:name=inbound-channel-adapter.storedProcExecutor,*"), null);
assertEquals(1, storedProcPollingChannelAdapterObjectNames.size());
ObjectName storedProcPollingChannelAdapterObjectName = storedProcPollingChannelAdapterObjectNames.iterator().next();
Map<String, Object>storedProcPollingChannelAdapterCacheStatistics = (Map<String, Object>) server.getAttribute(storedProcPollingChannelAdapterObjectName, "JdbcCallOperationsCacheStatisticsAsMap");
assertEquals(11, storedProcPollingChannelAdapterCacheStatistics.size());
assertEquals(Long.valueOf(0), storedProcPollingChannelAdapterCacheStatistics.get("hitCount"));
assertEquals(Long.valueOf(0), storedProcPollingChannelAdapterCacheStatistics.get("loadCount"));
assertEquals(Long.valueOf(0), storedProcPollingChannelAdapterCacheStatistics.get("loadExceptionCount"));
assertEquals(Long.valueOf(0), storedProcPollingChannelAdapterCacheStatistics.get("loadSuccessCount"));
assertEquals(Long.valueOf(0), storedProcPollingChannelAdapterCacheStatistics.get("missCount"));
}
@Test
@SuppressWarnings("unchecked")
public void testOutboundGateWayJmxAttributes() throws Exception {
final List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
assertEquals(1, servers.size());
final MBeanServer server = servers.iterator().next();
final Set<ObjectName> objectNames = server.queryNames(ObjectName.getInstance("org.springframework.integration.jdbc.test:name=my gateway.storedProcExecutor,*"), null);
assertEquals(1, objectNames.size());
ObjectName name = objectNames.iterator().next();
Map<String, Object> cacheStatistics = (Map<String, Object>) server.getAttribute(name, "JdbcCallOperationsCacheStatisticsAsMap");
assertEquals(11, cacheStatistics.size());
assertEquals(Long.valueOf(0), cacheStatistics.get("hitCount"));
assertEquals(Long.valueOf(0), cacheStatistics.get("loadCount"));
assertEquals(Long.valueOf(0), cacheStatistics.get("loadExceptionCount"));
assertEquals(Long.valueOf(0), cacheStatistics.get("loadSuccessCount"));
assertEquals(Long.valueOf(0), cacheStatistics.get("missCount"));
userService.createUser(new User("myUsername", "myPassword", "myEmail"));
List<Message<Collection<User>>> received = new ArrayList<Message<Collection<User>>>();
received.add(consumer.poll(2000));
Message<Collection<User>> message = received.get(0);
context.stop();
assertNotNull(message);
assertNotNull(message.getPayload());
assertNotNull(message.getPayload() instanceof Collection<?>);
Map<String, Object> cacheStatistics2 = (Map<String, Object>) server.getAttribute(name, "JdbcCallOperationsCacheStatisticsAsMap");
assertEquals(11, cacheStatistics2.size());
assertEquals(Long.valueOf(1), cacheStatistics2.get("hitCount"));
assertEquals(Long.valueOf(0), cacheStatistics2.get("loadCount"));
assertEquals(Long.valueOf(0), cacheStatistics2.get("loadExceptionCount"));
assertEquals(Long.valueOf(0), cacheStatistics2.get("loadSuccessCount"));
assertEquals(Long.valueOf(0), cacheStatistics2.get("missCount"));
}
static class Counter {
private final AtomicInteger count = new AtomicInteger();
public Integer next() throws InterruptedException {
if (count.get()>2){
//prevent message overload
return null;
}
return Integer.valueOf(count.incrementAndGet());
}
}
static class Consumer {
private final BlockingQueue<Message<Collection<User>>> messages = new LinkedBlockingQueue<Message<Collection<User>>>();
@ServiceActivator
public void receive(Message<Collection<User>> message) {
messages.add(message);
}
Message<Collection<User>> poll(long timeoutInMillis) throws InterruptedException {
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -26,7 +26,8 @@ import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.expression.Expression;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.integration.jdbc.storedproc.User;
import org.springframework.integration.support.MessageBuilder;
@@ -40,90 +41,158 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
*/
public class StoredProcMessageHandlerDerbyIntegrationTests {
private EmbeddedDatabase embeddedDatabase;
private EmbeddedDatabase embeddedDatabase;
private JdbcTemplate jdbcTemplate;
private JdbcTemplate jdbcTemplate;
@Before
public void setUp() throws SQLException {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
builder.setType(EmbeddedDatabaseType.DERBY);
@Before
public void setUp() throws SQLException {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
builder.setType(EmbeddedDatabaseType.DERBY);
builder.addScript("classpath:derby-stored-procedures.sql");
this.embeddedDatabase = builder.build();
this.jdbcTemplate = new JdbcTemplate(this.embeddedDatabase);
}
builder.addScript("classpath:derby-stored-procedures.sql");
this.embeddedDatabase = builder.build();
this.jdbcTemplate = new JdbcTemplate(this.embeddedDatabase);
@After
public void tearDown() {
this.embeddedDatabase.shutdown();
}
}
@Test
public void testDerbyStoredProcedureInsertWithDefaultSqlSource() {
@After
public void tearDown() {
this.embeddedDatabase.shutdown();
}
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(this.embeddedDatabase);
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(storedProcExecutor);
@Test
public void testDerbyStoredProcedureInsertWithDefaultSqlSource() {
storedProcExecutor.setStoredProcedureName("CREATE_USER");
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "CREATE_USER");
messageHandler.afterPropertiesSet();
MessageBuilder<User> message = MessageBuilder.withPayload(new User("username", "password", "email"));
messageHandler.handleMessage(message.build());
storedProcExecutor.afterPropertiesSet();
messageHandler.afterPropertiesSet();
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "username");
MessageBuilder<User> message = MessageBuilder.withPayload(new User("username", "password", "email"));
messageHandler.handleMessage(message.build());
assertEquals("Wrong username", "username", map.get("USERNAME"));
assertEquals("Wrong password", "password", map.get("PASSWORD"));
assertEquals("Wrong email", "email", map.get("EMAIL"));
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "username");
}
assertEquals("Wrong username", "username", map.get("USERNAME"));
assertEquals("Wrong password", "password", map.get("PASSWORD"));
assertEquals("Wrong email", "email", map.get("EMAIL"));
@Test
public void testDerbyStoredProcedureInsertWithExpression() {
}
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "CREATE_USER");
@Test
public void testDerbyStoredProcInsertWithDefaultSqlSourceAndDynamicProcName() throws Exception {
final List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
procedureParameters.add(new ProcedureParameter("username", null, "payload.username.toUpperCase()"));
procedureParameters.add(new ProcedureParameter("password", null, "payload.password.toUpperCase()"));
procedureParameters.add(new ProcedureParameter("email", null, "payload.email.toUpperCase()"));
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(this.embeddedDatabase);
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(storedProcExecutor);
messageHandler.setProcedureParameters(procedureParameters);
messageHandler.afterPropertiesSet();
final ExpressionFactoryBean efb = new ExpressionFactoryBean("headers['stored_procedure_name']");
efb.afterPropertiesSet();
final Expression expression = efb.getObject();
MessageBuilder<User> message = MessageBuilder.withPayload(new User("Eric.Cartman", "c4rtm4n", "eric@cartman.com"));
messageHandler.handleMessage(message.build());
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
messageHandler.afterPropertiesSet();
MessageBuilder<User> message = MessageBuilder.withPayload(new User("username", "password", "email"));
message.setHeader("stored_procedure_name", "CREATE_USER");
messageHandler.handleMessage(message.build());
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "username");
assertEquals("Wrong username", "username", map.get("USERNAME"));
assertEquals("Wrong password", "password", map.get("PASSWORD"));
assertEquals("Wrong email", "email", map.get("EMAIL"));
}
@Test
public void testDerbyStoredProcInsertWithDefaultSqlSourceAndSpelProcName() throws Exception {
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(this.embeddedDatabase);
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(storedProcExecutor);
ExpressionFactoryBean efb = new ExpressionFactoryBean("headers.headerWithProcedureName");
efb.afterPropertiesSet();
Expression expression = efb.getObject();
storedProcExecutor.setStoredProcedureNameExpression(expression);
storedProcExecutor.afterPropertiesSet();
messageHandler.afterPropertiesSet();
MessageBuilder<User> message = MessageBuilder.withPayload(new User("username", "password", "email"));
message.setHeader("headerWithProcedureName", "CREATE_USER");
messageHandler.handleMessage(message.build());
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "username");
assertEquals("Wrong username", "username", map.get("USERNAME"));
assertEquals("Wrong password", "password", map.get("PASSWORD"));
assertEquals("Wrong email", "email", map.get("EMAIL"));
}
@Test
public void testDerbyStoredProcedureInsertWithExpression() {
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(this.embeddedDatabase);
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(storedProcExecutor);
storedProcExecutor.setStoredProcedureName("CREATE_USER");
final List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
procedureParameters.add(new ProcedureParameter("username", null, "payload.username.toUpperCase()"));
procedureParameters.add(new ProcedureParameter("password", null, "payload.password.toUpperCase()"));
procedureParameters.add(new ProcedureParameter("email", null, "payload.email.toUpperCase()"));
storedProcExecutor.setProcedureParameters(procedureParameters);
storedProcExecutor.afterPropertiesSet();
messageHandler.afterPropertiesSet();
MessageBuilder<User> message = MessageBuilder.withPayload(new User("Eric.Cartman", "c4rtm4n", "eric@cartman.com"));
messageHandler.handleMessage(message.build());
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "ERIC.CARTMAN");
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "ERIC.CARTMAN");
assertEquals("Wrong username", "ERIC.CARTMAN", map.get("USERNAME"));
assertEquals("Wrong password", "C4RTM4N", map.get("PASSWORD"));
assertEquals("Wrong email", "ERIC@CARTMAN.COM", map.get("EMAIL"));
assertEquals("Wrong username", "ERIC.CARTMAN", map.get("USERNAME"));
assertEquals("Wrong password", "C4RTM4N", map.get("PASSWORD"));
assertEquals("Wrong email", "ERIC@CARTMAN.COM", map.get("EMAIL"));
}
}
@Test
public void testDerbyStoredProcedureInsertWithHeaderExpression() {
@Test
public void testDerbyStoredProcedureInsertWithHeaderExpression() {
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "CREATE_USER");
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(this.embeddedDatabase);
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(storedProcExecutor);
final List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
procedureParameters.add(new ProcedureParameter("USERNAME", null, "headers[business_id] + '_' + payload.username"));
procedureParameters.add(new ProcedureParameter("password", "static_password", null));
procedureParameters.add(new ProcedureParameter("email", "static_email" , null));
storedProcExecutor.setStoredProcedureName("CREATE_USER");
messageHandler.setProcedureParameters(procedureParameters);
messageHandler.afterPropertiesSet();
final List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
procedureParameters.add(new ProcedureParameter("USERNAME", null, "headers[business_id] + '_' + payload.username"));
procedureParameters.add(new ProcedureParameter("password", "static_password", null));
procedureParameters.add(new ProcedureParameter("email", "static_email" , null));
MessageBuilder<User> message = MessageBuilder.withPayload(new User("Eric.Cartman", "c4rtm4n", "eric@cartman.com"));
message.setHeader("business_id", "1234");
messageHandler.handleMessage(message.build());
storedProcExecutor.setProcedureParameters(procedureParameters);
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "1234_Eric.Cartman");
storedProcExecutor.afterPropertiesSet();
messageHandler.afterPropertiesSet();
assertEquals("Wrong username", "1234_Eric.Cartman", map.get("USERNAME"));
assertEquals("Wrong password", "static_password", map.get("PASSWORD"));
assertEquals("Wrong email", "static_email", map.get("EMAIL"));
}
MessageBuilder<User> message = MessageBuilder.withPayload(new User("Eric.Cartman", "c4rtm4n", "eric@cartman.com"));
message.setHeader("business_id", "1234");
messageHandler.handleMessage(message.build());
Map<String, Object> map = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME=?", "1234_Eric.Cartman");
assertEquals("Wrong username", "1234_Eric.Cartman", map.get("USERNAME"));
assertEquals("Wrong password", "static_password", map.get("PASSWORD"));
assertEquals("Wrong email", "static_email", map.get("EMAIL"));
}
}

View File

@@ -1,20 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="DERBY"/>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:drop-derby-stored-procedures.sql"/>
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
</jdbc:initialize-database>
<import resource="classpath:derby-stored-procedures-setup-context.xml"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
@@ -28,5 +23,4 @@
</int-jdbc:stored-proc-outbound-channel-adapter>
</int:chain>
</beans>

View File

@@ -1,53 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<jdbc:embedded-database id="datasource" type="DERBY">
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
</jdbc:embedded-database>
<import resource="classpath:derby-stored-procedures-setup-context.xml"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:gateway id="startGateway" default-request-channel="startChannel"
service-interface="org.springframework.integration.jdbc.storedproc.CreateUser" />
<int:channel id="startChannel"/>
<int:gateway id="startGateway" default-request-channel="startChannel"
service-interface="org.springframework.integration.jdbc.storedproc.CreateUser" />
<int-jdbc:stored-proc-outbound-gateway request-channel="startChannel" stored-procedure-name="CREATE_USER_RETURN_ALL" data-source="datasource"
auto-startup="true"
id="gateway"
ignore-column-meta-data="false"
is-function="false"
expect-single-result="true"
reply-channel="outputChannel">
<int-jdbc:parameter name="username" expression="payload.username"/>
<int-jdbc:parameter name="password" expression="payload.password"/>
<int-jdbc:parameter name="email" expression="payload.email"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.UserMapper" />
</int-jdbc:stored-proc-outbound-gateway>
<int:channel id="startChannel"/>
<int:channel id="outputChannel"/>
<int-jdbc:stored-proc-outbound-gateway request-channel="startChannel"
stored-procedure-name="CREATE_USER_RETURN_ALL" data-source="dataSource"
auto-startup="true"
id="gateway"
ignore-column-meta-data="false"
is-function="false"
expect-single-result="true"
reply-channel="outputChannel">
<int-jdbc:parameter name="username" expression="payload.username"/>
<int-jdbc:parameter name="password" expression="payload.password"/>
<int-jdbc:parameter name="email" expression="payload.email"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.UserMapper" />
</int-jdbc:stored-proc-outbound-gateway>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithNamespaceIntegrationTests$Consumer"/>
<int:channel id="outputChannel"/>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithNamespaceIntegrationTests$Consumer"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource" />
</bean>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -46,67 +46,67 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
public class StoredProcOutboundGatewayWithNamespaceIntegrationTests {
@Autowired
private AbstractApplicationContext context;
@Autowired
private AbstractApplicationContext context;
@Autowired
private Consumer consumer;
@Autowired
private Consumer consumer;
@Autowired
CreateUser createUser;
@Autowired
CreateUser createUser;
@Test
public void test() throws Exception {
createUser.createUser(new User("myUsername", "myPassword", "myEmail"));
List<Message<Collection<User>>> received = new ArrayList<Message<Collection<User>>>();
public void test() throws Exception {
received.add(consumer.poll(2000));
createUser.createUser(new User("myUsername", "myPassword", "myEmail"));
Message<Collection<User>> message = received.get(0);
context.stop();
assertNotNull(message);
assertNotNull(message.getPayload());
assertNotNull(message.getPayload() instanceof Collection<?>);
List<Message<Collection<User>>> received = new ArrayList<Message<Collection<User>>>();
Collection<User> allUsers = message.getPayload();
received.add(consumer.poll(2000));
assertTrue(allUsers.size() == 1);
User userFromDb = allUsers.iterator().next();
assertEquals("Wrong username", "myUsername", userFromDb.getUsername());
assertEquals("Wrong password", "myPassword", userFromDb.getPassword());
assertEquals("Wrong email", "myEmail", userFromDb.getEmail());
Message<Collection<User>> message = received.get(0);
context.stop();
assertNotNull(message);
assertNotNull(message.getPayload());
assertNotNull(message.getPayload() instanceof Collection<?>);
}
Collection<User> allUsers = message.getPayload();
static class Counter {
assertTrue(allUsers.size() == 1);
private final AtomicInteger count = new AtomicInteger();
User userFromDb = allUsers.iterator().next();
public Integer next() throws InterruptedException {
if (count.get()>2){
//prevent message overload
return null;
}
return Integer.valueOf(count.incrementAndGet());
}
}
assertEquals("Wrong username", "myUsername", userFromDb.getUsername());
assertEquals("Wrong password", "myPassword", userFromDb.getPassword());
assertEquals("Wrong email", "myEmail", userFromDb.getEmail());
}
static class Counter {
private final AtomicInteger count = new AtomicInteger();
public Integer next() throws InterruptedException {
if (count.get()>2){
//prevent message overload
return null;
}
return Integer.valueOf(count.incrementAndGet());
}
}
static class Consumer {
static class Consumer {
private final BlockingQueue<Message<Collection<User>>> messages = new LinkedBlockingQueue<Message<Collection<User>>>();
private final BlockingQueue<Message<Collection<User>>> messages = new LinkedBlockingQueue<Message<Collection<User>>>();
@ServiceActivator
public void receive(Message<Collection<User>> message) {
messages.add(message);
}
@ServiceActivator
public void receive(Message<Collection<User>> message) {
messages.add(message);
}
Message<Collection<User>> poll(long timeoutInMillis) throws InterruptedException {
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
}
}
Message<Collection<User>> poll(long timeoutInMillis) throws InterruptedException {
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
}
}
}

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<import resource="classpath:derby-stored-procedures-setup-context.xml"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:channel id="startChannel"/>
<int-jdbc:stored-proc-outbound-gateway request-channel="startChannel"
data-source="dataSource"
stored-procedure-name-expression="headers['my_stored_procedure']"
auto-startup="true"
id="gateway"
ignore-column-meta-data="false"
is-function="false"
expect-single-result="true"
reply-channel="outputChannel">
<int-jdbc:parameter name="username" expression="payload.username"/>
<int-jdbc:parameter name="password" expression="payload.password"/>
<int-jdbc:parameter name="email" expression="payload.email"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.UserMapper" />
</int-jdbc:stored-proc-outbound-gateway>
<int:channel id="outputChannel"/>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithSpelIntegrationTests$Consumer"/>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
</beans>

View File

@@ -0,0 +1,156 @@
/*
* Copyright 2002-2012 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.jdbc;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.jdbc.storedproc.User;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gunnar Hillert
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class StoredProcOutboundGatewayWithSpelIntegrationTests {
@Autowired
private AbstractApplicationContext context;
@Autowired
private Consumer consumer;
@Autowired
@Qualifier("startChannel")
DirectChannel channel;
@Test
@DirtiesContext
public void executeStoredProcedureWithMessageHeader() throws Exception {
User user1 = new User("First User", "my first password", "email1");
User user2 = new User("Second User", "my second password", "email2");
Message<User> user1Message = MessageBuilder.withPayload(user1)
.setHeader("my_stored_procedure", "CREATE_USER")
.build();
Message<User> user2Message = MessageBuilder.withPayload(user2)
.setHeader("my_stored_procedure", "CREATE_USER_RETURN_ALL")
.build();
channel.send(user1Message);
channel.send(user2Message);
List<Message<Collection<User>>> received = new ArrayList<Message<Collection<User>>>();
received.add(consumer.poll(2000));
Assert.assertEquals(Integer.valueOf(1), Integer.valueOf(received.size()));
Message<Collection<User>> message = received.get(0);
context.stop();
assertNotNull(message);
assertNotNull(message.getPayload());
assertNotNull(message.getPayload() instanceof Collection<?>);
Collection<User> allUsers = message.getPayload();
assertTrue(allUsers.size() == 2);
}
@Test
@DirtiesContext
public void testWithMissingMessageHeader() throws Exception {
User user1 = new User("First User", "my first password", "email1");
Message<User> user1Message = MessageBuilder.withPayload(user1).build();
try {
channel.send(user1Message);
} catch (MessageHandlingException e) {
String expectedMessage = "Unable to resolve Stored Procedure/Function name " +
"for the provided Expression 'headers['my_stored_procedure']'.";
String actualMessage = e.getCause().getMessage();
Assert.assertEquals(expectedMessage, actualMessage);
return;
}
Assert.fail("Expected a MessageHandlingException to be thrown.");
}
static class Counter {
private final AtomicInteger count = new AtomicInteger();
public Integer next() throws InterruptedException {
if (count.get()>2){
//prevent message overload
return null;
}
return Integer.valueOf(count.incrementAndGet());
}
}
/**
* This class is called by the Service Activator and populates {@link Consumer#messages}
* with the Gateway's response message and is used by the Test to verify that
* the Gateway executed correctly.
*/
static class Consumer {
private volatile BlockingQueue<Message<Collection<User>>> messages = new LinkedBlockingQueue<Message<Collection<User>>>();
@ServiceActivator
public void receive(Message<Collection<User>> message) {
messages.add(message);
}
Message<Collection<User>> poll(long timeoutInMillis) throws InterruptedException {
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
}
}
}

View File

@@ -1,77 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<jdbc:embedded-database id="dataSource" type="DERBY">
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
</jdbc:embedded-database>
<import resource="classpath:derby-stored-procedures-setup-context.xml"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:gateway id="startGateway" default-request-channel="startChannel"
service-interface="org.springframework.integration.jdbc.storedproc.CreateUser" />
<int:channel id="startChannel"/>
<bean id="gateway" class="org.springframework.integration.jdbc.StoredProcOutboundGateway">
<constructor-arg name="dataSource" ref="dataSource" />
<constructor-arg name="storedProcedureName" value="CREATE_USER_RETURN_ALL"/>
<property name="isFunction" value="false"/>
<property name="expectSingleResult" value="true"/>
<property name="outputChannel" ref="outputChannel"/>
<property name="procedureParameters" >
<util:list>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="username"/>
<property name="expression" value="payload.username"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="password"/>
<property name="expression" value="payload.password"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="email"/>
<property name="expression" value="payload.email"/>
</bean>
</util:list>
</property>
<property name="returningResultSetRowMappers">
<util:map map-class="java.util.Hashtable">
<entry key="out" value-ref="rowMapper"/>
</util:map>
</property>
</bean>
<int:gateway id="startGateway" default-request-channel="startChannel"
service-interface="org.springframework.integration.jdbc.storedproc.CreateUser" />
<bean id="storedProcedureEndpoint"
class="org.springframework.integration.endpoint.EventDrivenConsumer">
<constructor-arg name="inputChannel" ref="startChannel"/>
<constructor-arg name="handler" ref="gateway"/>
</bean>
<int:channel id="startChannel"/>
<bean id="rowMapper" class="org.springframework.integration.jdbc.storedproc.UserMapper"/>
<bean id="storedProcExecutor" class="org.springframework.integration.jdbc.StoredProcExecutor">
<constructor-arg name="dataSource" ref="dataSource"/>
<property name="storedProcedureName" value="CREATE_USER_RETURN_ALL"/>
<property name="isFunction" value="false"/>
<property name="procedureParameters">
<util:list>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="username"/>
<property name="expression" value="payload.username"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="password"/>
<property name="expression" value="payload.password"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="email"/>
<property name="expression" value="payload.email"/>
</bean>
</util:list>
</property>
<property name="returningResultSetRowMappers">
<util:map map-class="java.util.Hashtable">
<entry key="out" value-ref="rowMapper"/>
</util:map>
</property>
</bean>
<int:channel id="outputChannel"/>
<bean id="gateway" class="org.springframework.integration.jdbc.StoredProcOutboundGateway">
<constructor-arg name="storedProcExecutor" ref="storedProcExecutor" />
<property name="expectSingleResult" value="true"/>
<property name="outputChannel" ref="outputChannel"/>
</bean>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithSpringContextIntegrationTests$Consumer"/>
<bean id="storedProcedureEndpoint"
class="org.springframework.integration.endpoint.EventDrivenConsumer">
<constructor-arg name="inputChannel" ref="startChannel"/>
<constructor-arg name="handler" ref="gateway"/>
</bean>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
<bean id="rowMapper" class="org.springframework.integration.jdbc.storedproc.UserMapper"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<int:channel id="outputChannel"/>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithSpringContextIntegrationTests$Consumer"/>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
</beans>

View File

@@ -1,82 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:h2-stored-procedures.sql"/>
</jdbc:embedded-database>
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:h2-stored-procedures.sql"/>
</jdbc:embedded-database>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
<bean id="source" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapter">
<constructor-arg name="dataSource" ref="dataSource" />
<constructor-arg name="storedProcedureName" value="GET_PRIME_NUMBERS"/>
<property name="function" value="false"/>
<property name="expectSingleResult" value="true"/>
<property name="procedureParameters" >
<util:list>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="beginRange"/>
<property name="value" value="1"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="endRange"/>
<property name="value" value="10"/>
</bean>
</util:list>
</property>
<property name="sqlParameters">
<util:list>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg name="name" value="beginRange"/>
<constructor-arg name="sqlType"><util:constant static-field="java.sql.Types.INTEGER"/></constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg name="name" value="endRange"/>
<constructor-arg name="sqlType"><util:constant static-field="java.sql.Types.INTEGER"/></constructor-arg>
</bean>
</util:list>
</property>
<property name="returningResultSetRowMappers">
<util:map map-class="java.util.Hashtable">
<entry key="out" value-ref="rowMapper"/>
</util:map>
</property>
<property name="ignoreColumnMetaData" value="true"/>
</bean>
<bean id="storedProcExecutor" class="org.springframework.integration.jdbc.StoredProcExecutor">
<constructor-arg name="dataSource" ref="dataSource" />
<property name="storedProcedureName" value="GET_PRIME_NUMBERS"/>
<property name="function" value="false"/>
<property name="procedureParameters" >
<util:list>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="beginRange"/>
<property name="value" value="1"/>
</bean>
<bean class="org.springframework.integration.jdbc.storedproc.ProcedureParameter">
<property name="name" value="endRange"/>
<property name="value" value="10"/>
</bean>
</util:list>
</property>
<property name="sqlParameters">
<util:list>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg name="name" value="beginRange"/>
<constructor-arg name="sqlType"><util:constant static-field="java.sql.Types.INTEGER"/></constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg name="name" value="endRange"/>
<constructor-arg name="sqlType"><util:constant static-field="java.sql.Types.INTEGER"/></constructor-arg>
</bean>
</util:list>
</property>
<property name="returningResultSetRowMappers">
<util:map map-class="java.util.Hashtable">
<entry key="out" value-ref="rowMapper"/>
</util:map>
</property>
<property name="ignoreColumnMetaData" value="true"/>
</bean>
<bean id="rowMapper" class="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
<bean id="source" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapter">
<constructor-arg name="storedProcExecutor" ref="storedProcExecutor"/>
<property name="expectSingleResult" value="true"/>
</bean>
<bean id="storedProcedureEndpoint"
class="org.springframework.integration.endpoint.SourcePollingChannelAdapter">
<property name="source" ref="source"/>
<property name="outputChannel" ref="outputChannel"/>
<property name="pollerMetadata" ref="defaultPoller"/>
</bean>
<bean id="rowMapper" class="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
<int:channel id="outputChannel"/>
<!-- <int:channel id="errorChannel" /> -->
<bean id="storedProcedureEndpoint"
class="org.springframework.integration.endpoint.SourcePollingChannelAdapter">
<property name="source" ref="source"/>
<property name="outputChannel" ref="outputChannel"/>
<property name="pollerMetadata" ref="defaultPoller"/>
</bean>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapterWithSpringContextIntegrationTests$Consumer"/>
<int:channel id="outputChannel"/>
<!-- <int:channel id="errorChannel" /> -->
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapterWithSpringContextIntegrationTests$Consumer"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="storedProcedurePollingChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:poller default="true" fixed-rate="10000"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="autoChannel"
data-source="dataSource"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR" />
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5" />
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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
@@ -26,6 +26,7 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.jdbc.core.SqlInOutParameter;
@@ -39,125 +40,125 @@ import org.springframework.jdbc.core.SqlParameter;
*/
public class StoredProcMessageHandlerParserTests {
private ConfigurableApplicationContext context;
private ConfigurableApplicationContext context;
private EventDrivenConsumer consumer;
private EventDrivenConsumer consumer;
@Test
public void testProcedureNameIsSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Object testProcedure1 = executorAccessor.getPropertyValue("storedProcedureName");
assertEquals("Resolution Required should be 'testProcedure1' but was " + testProcedure1, "testProcedure1", testProcedure1);
}
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
public void testProcedureNameIsSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Object procedureParameters = executorAccessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
Expression testProcedure1 = (Expression) executorAccessor.getPropertyValue("storedProcedureNameExpression");
assertEquals("Resolution Required should be 'testProcedure1' but was " + testProcedure1, "testProcedure1", testProcedure1.getValue());
}
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
assertTrue(procedureParametersAsList.size() == 4);
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), (Integer) parameter4.getValue());
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
}
@SuppressWarnings("unchecked")
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
public void testProcedurepParametersAreSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Object sqlParameters = executorAccessor.getPropertyValue("sqlParameters");
Object procedureParameters = executorAccessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
assertTrue(procedureParametersAsList.size() == 4);
assertTrue(sqlParametersAsList.size() == 4);
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), parameter4.getValue());
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
}
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
}
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
@After
public void tearDown(){
if(context != null){
context.close();
}
}
Object executor = accessor.getPropertyValue("executor");
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
public void setUp(String name, Class<?> cls){
context = new ClassPathXmlApplicationContext(name, cls);
consumer = this.context.getBean("storedProcedureOutboundChannelAdapter", EventDrivenConsumer.class);
}
Object sqlParameters = executorAccessor.getPropertyValue("sqlParameters");
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
assertTrue(sqlParametersAsList.size() == 4);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
}
@After
public void tearDown(){
if(context != null){
context.close();
}
}
public void setUp(String name, Class<?> cls){
context = new ClassPathXmlApplicationContext(name, cls);
consumer = this.context.getBean("storedProcedureOutboundChannelAdapter", EventDrivenConsumer.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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
@@ -29,6 +29,7 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.jdbc.storedproc.PrimeMapper;
@@ -45,176 +46,176 @@ import org.springframework.jdbc.core.SqlParameter;
*/
public class StoredProcOutboundGatewayParserTests {
private ConfigurableApplicationContext context;
private ConfigurableApplicationContext context;
private EventDrivenConsumer outboundGateway;
private EventDrivenConsumer outboundGateway;
@Test
public void testProcedureNameIsSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object storedProcedureName = accessor.getPropertyValue("storedProcedureName");
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName);
}
@Test
public void testReplyTimeoutIsSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("messagingTemplate");
MessagingTemplate messagingTemplate = (MessagingTemplate) source;
accessor = new DirectFieldAccessor(messagingTemplate);
Long sendTimeout = (Long) accessor.getPropertyValue("sendTimeout");
assertEquals("Wrong sendTimeout", Long.valueOf(555L), sendTimeout);
}
@Test
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
assertFalse(skipUndeclaredResults);
}
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
public void testProcedureNameIsSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object procedureParameters = accessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Expression storedProcedureName = (Expression) accessor.getPropertyValue("storedProcedureNameExpression");
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName.getValue());
}
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
assertTrue(procedureParametersAsList.size() == 4);
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), (Integer) parameter4.getValue());
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
}
@SuppressWarnings("unchecked")
@Test
public void testReturningResultSetRowMappersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
public void testReplyTimeoutIsSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object returningResultSetRowMappers = accessor.getPropertyValue("returningResultSetRowMappers");
assertNotNull(returningResultSetRowMappers);
assertTrue(returningResultSetRowMappers instanceof Map);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("messagingTemplate");
Map<String, RowMapper<?>> returningResultSetRowMappersAsMap = (Map<String, RowMapper<?>>) returningResultSetRowMappers;
MessagingTemplate messagingTemplate = (MessagingTemplate) source;
assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 1", returningResultSetRowMappersAsMap.size() == 1);
accessor = new DirectFieldAccessor(messagingTemplate);
Entry<String, ?> mapEntry1 = returningResultSetRowMappersAsMap.entrySet().iterator().next();
Long sendTimeout = (Long) accessor.getPropertyValue("sendTimeout");
assertEquals("Wrong sendTimeout", Long.valueOf(555L), sendTimeout);
assertEquals("out", mapEntry1.getKey());
assertTrue(mapEntry1.getValue() instanceof PrimeMapper);
}
}
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object sqlParameters = accessor.getPropertyValue("sqlParameters");
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
assertFalse(skipUndeclaredResults);
}
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
assertTrue(sqlParametersAsList.size() == 4);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object procedureParameters = accessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
assertTrue(procedureParametersAsList.size() == 4);
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), parameter4.getValue());
}
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
@After
public void tearDown(){
if(context != null){
context.close();
}
}
}
public void setUp(String name, Class<?> cls){
this.context = new ClassPathXmlApplicationContext(name, cls);
this.outboundGateway = this.context.getBean("storedProcedureOutboundGateway", EventDrivenConsumer.class);
}
@SuppressWarnings("unchecked")
@Test
public void testReturningResultSetRowMappersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object returningResultSetRowMappers = accessor.getPropertyValue("returningResultSetRowMappers");
assertNotNull(returningResultSetRowMappers);
assertTrue(returningResultSetRowMappers instanceof Map);
Map<String, RowMapper<?>> returningResultSetRowMappersAsMap = (Map<String, RowMapper<?>>) returningResultSetRowMappers;
assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 1", returningResultSetRowMappersAsMap.size() == 1);
Entry<String, ?> mapEntry1 = returningResultSetRowMappersAsMap.entrySet().iterator().next();
assertEquals("out", mapEntry1.getKey());
assertTrue(mapEntry1.getValue() instanceof PrimeMapper);
}
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
Object source = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object sqlParameters = accessor.getPropertyValue("sqlParameters");
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
assertTrue(sqlParametersAsList.size() == 4);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
}
@After
public void tearDown(){
if(context != null){
context.close();
}
}
public void setUp(String name, Class<?> cls){
this.context = new ClassPathXmlApplicationContext(name, cls);
this.outboundGateway = this.context.getBean("storedProcedureOutboundGateway", EventDrivenConsumer.class);
}
}

View File

@@ -29,6 +29,7 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.jdbc.storedproc.PrimeMapper;
@@ -47,165 +48,205 @@ import org.springframework.jdbc.core.SqlParameter;
*/
public class StoredProcPollingChannelAdapterParserTests {
private ConfigurableApplicationContext context;
private ConfigurableApplicationContext context;
private SourcePollingChannelAdapter pollingAdapter;
private SourcePollingChannelAdapter pollingAdapter;
@Test
public void testProcedureNameIsSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object storedProcedureName = accessor.getPropertyValue("storedProcedureName");
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName);
}
@Test
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
assertTrue("skipUndeclaredResults was not set and should default to 'true'", skipUndeclaredResults);
}
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
public void testProcedureNameIsSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object procedureParameters = accessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Expression storedProcedureName = (Expression) accessor.getPropertyValue("storedProcedureNameExpression");
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName.getValue());
}
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
assertTrue(procedureParametersAsList.size() == 4);
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), (Integer) parameter4.getValue());
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
}
@SuppressWarnings("unchecked")
@Test
public void testReturningResultSetRowMappersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
public void testProcedureNameExpressionIsSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest2.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object returningResultSetRowMappers = accessor.getPropertyValue("returningResultSetRowMappers");
assertNotNull(returningResultSetRowMappers);
assertTrue(returningResultSetRowMappers instanceof Map);
Expression storedProcedureNameExpression =
TestUtils.getPropertyValue(this.pollingAdapter,
"source.executor.storedProcedureNameExpression",
Expression.class);
Map<String, RowMapper<?>> returningResultSetRowMappersAsMap = (Map<String, RowMapper<?>>) returningResultSetRowMappers;
assertEquals("Wrong stored procedure name", "'GET_PRIME_NUMBERS'",
storedProcedureNameExpression.getExpressionString());
}
assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 1", returningResultSetRowMappersAsMap.size() == 1);
Entry<String, ?> mapEntry1 = returningResultSetRowMappersAsMap.entrySet().iterator().next();
assertEquals("out", mapEntry1.getKey());
assertTrue(mapEntry1.getValue() instanceof PrimeMapper);
}
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
public void testDefaultJdbcCallOperationsCacheSizeIsSet() {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object sqlParameters = accessor.getPropertyValue("sqlParameters");
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
Integer cacheSize =
TestUtils.getPropertyValue(this.pollingAdapter,
"source.executor.jdbcCallOperationsCacheSize",
Integer.class);
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
assertEquals("Wrong Default JdbcCallOperations Cache Size", Integer.valueOf(10),
cacheSize);
}
assertTrue(sqlParametersAsList.size() == 4);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
@Test
public void testJdbcCallOperationsCacheSizeIsSet() {
setUp("storedProcPollingChannelAdapterParserTest2.xml", getClass());
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
Integer cacheSize =
TestUtils.getPropertyValue(this.pollingAdapter,
"source.executor.jdbcCallOperationsCacheSize",
Integer.class);
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
assertEquals("Wrong JdbcCallOperations Cache Size", Integer.valueOf(77),
cacheSize);
}
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
@Test
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
assertTrue("skipUndeclaredResults was not set and should default to 'true'", skipUndeclaredResults);
}
}
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
@Test
public void testAutoChannel() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object procedureParameters = accessor.getPropertyValue("procedureParameters");
assertNotNull(procedureParameters);
assertTrue(procedureParameters instanceof List);
@After
public void tearDown(){
if(context != null){
context.close();
}
}
List<ProcedureParameter>procedureParametersAsList = (List<ProcedureParameter>) procedureParameters;
public void setUp(String name, Class<?> cls){
this.context = new ClassPathXmlApplicationContext(name, cls);
this.pollingAdapter = this.context.getBean("storedProcedurePollingChannelAdapter", SourcePollingChannelAdapter.class);
}
assertTrue(procedureParametersAsList.size() == 4);
ProcedureParameter parameter1 = procedureParametersAsList.get(0);
ProcedureParameter parameter2 = procedureParametersAsList.get(1);
ProcedureParameter parameter3 = procedureParametersAsList.get(2);
ProcedureParameter parameter4 = procedureParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("description", parameter2.getName());
assertEquals("password", parameter3.getName());
assertEquals("age", parameter4.getName());
assertEquals("kenny", parameter1.getValue());
assertEquals("Who killed Kenny?", parameter2.getValue());
assertNull(parameter3.getValue());
assertEquals(Integer.valueOf(30), parameter4.getValue());
assertNull(parameter1.getExpression());
assertNull(parameter2.getExpression());
assertEquals("payload.username", parameter3.getExpression());
assertNull(parameter4.getExpression());
}
@SuppressWarnings("unchecked")
@Test
public void testReturningResultSetRowMappersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object returningResultSetRowMappers = accessor.getPropertyValue("returningResultSetRowMappers");
assertNotNull(returningResultSetRowMappers);
assertTrue(returningResultSetRowMappers instanceof Map);
Map<String, RowMapper<?>> returningResultSetRowMappersAsMap = (Map<String, RowMapper<?>>) returningResultSetRowMappers;
assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 1", returningResultSetRowMappersAsMap.size() == 1);
Entry<String, ?> mapEntry1 = returningResultSetRowMappersAsMap.entrySet().iterator().next();
assertEquals("out", mapEntry1.getKey());
assertTrue(mapEntry1.getValue() instanceof PrimeMapper);
}
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
Object source = accessor.getPropertyValue("source");
accessor = new DirectFieldAccessor(source);
source = accessor.getPropertyValue("executor");
accessor = new DirectFieldAccessor(source);
Object sqlParameters = accessor.getPropertyValue("sqlParameters");
assertNotNull(sqlParameters);
assertTrue(sqlParameters instanceof List);
List<SqlParameter>sqlParametersAsList = (List<SqlParameter>) sqlParameters;
assertTrue(sqlParametersAsList.size() == 4);
SqlParameter parameter1 = sqlParametersAsList.get(0);
SqlParameter parameter2 = sqlParametersAsList.get(1);
SqlParameter parameter3 = sqlParametersAsList.get(2);
SqlParameter parameter4 = sqlParametersAsList.get(3);
assertEquals("username", parameter1.getName());
assertEquals("password", parameter2.getName());
assertEquals("age", parameter3.getName());
assertEquals("description", parameter4.getName());
assertNull("Expect that the scale is null.", parameter1.getScale());
assertNull("Expect that the scale is null.", parameter2.getScale());
assertEquals("Expect that the scale is 5.", Integer.valueOf(5), parameter3.getScale());
assertNull("Expect that the scale is null.", parameter4.getScale());
assertEquals("SqlType is ", Types.VARCHAR, parameter1.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter2.getSqlType());
assertEquals("SqlType is ", Types.INTEGER, parameter3.getSqlType());
assertEquals("SqlType is ", Types.VARCHAR, parameter4.getSqlType());
assertTrue(parameter1 instanceof SqlParameter);
assertTrue(parameter2 instanceof SqlOutParameter);
assertTrue(parameter3 instanceof SqlInOutParameter);
assertTrue(parameter4 instanceof SqlParameter);
}
@Test
public void testAutoChannel() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
@After
public void tearDown(){
if(context != null){
context.close();
}
}
public void setUp(String name, Class<?> cls){
this.context = new ClassPathXmlApplicationContext(name, cls);
this.pollingAdapter = this.context.getBean("storedProcedurePollingChannelAdapter", SourcePollingChannelAdapter.class);
}
}

View File

@@ -1,41 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="requestChannel"/>
<int:channel id="replyChannel"/>
<int:channel id="requestChannel" />
<int:channel id="replyChannel" />
<jdbc:embedded-database id="datasource" type="HSQL"/>
<jdbc:embedded-database id="datasource" type="HSQL" />
<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" stored-procedure-name="GET_PRIME_NUMBERS" data-source="datasource"
auto-startup="true"
id="storedProcedureOutboundGateway"
ignore-column-meta-data="false"
is-function="false"
skip-undeclared-results="false"
order="2"
reply-channel="replyChannel"
reply-timeout="555"
return-value-required="false">
<int-jdbc:stored-proc-outbound-gateway
request-channel="requestChannel" stored-procedure-name="GET_PRIME_NUMBERS"
data-source="datasource" auto-startup="true" id="storedProcedureOutboundGateway"
ignore-column-meta-data="false" is-function="false"
skip-undeclared-results="false" order="2" reply-channel="replyChannel"
reply-timeout="555" return-value-required="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR" />
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5" />
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String" />
<int-jdbc:parameter name="description" value="Who killed Kenny?" />
<int-jdbc:parameter name="password" expression="payload.username" />
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer" />
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper" />
</int-jdbc:stored-proc-outbound-gateway>
</int-jdbc:stored-proc-outbound-gateway>
<int:poller default="true" fixed-rate="10000"/>
<int:poller default="true" fixed-rate="10000" />
</beans>

View File

@@ -1,51 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="storedProcedurePollingChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="storedProcedurePollingChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:poller default="true" fixed-rate="10000"/>
<int:poller default="true" fixed-rate="10000"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="autoChannel"
data-source="dataSource"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="autoChannel"
data-source="dataSource"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR" />
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5" />
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="storedProcedurePollingChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name-expression="'GET_PRIME_NUMBERS'"
is-function="false"
jdbc-call-operations-cache-size="77">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:poller default="true" fixed-rate="10000"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="autoChannel"
data-source="dataSource"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR" />
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5" />
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -15,6 +15,11 @@
*/
package org.springframework.integration.jdbc.storedproc;
/**
*
* @author Gunnar Hillert
*
*/
public interface CreateUser {
void createUser(User user);
void createUser(User user);
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -17,8 +17,13 @@ import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
/**
*
* @author Gunnar Hillert
*
*/
public class PrimeMapper implements RowMapper<Integer> {
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getInt("PRIME");
}
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getInt("PRIME");
}
}

View File

@@ -1,38 +1,92 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.jdbc.storedproc;
/**
*
* @author Gunnar Hillert
*
*/
public class User {
private String username;
private String password;
private String email;
private String username;
private String password;
private String email;
public User(String username, String password, String email) {
super();
this.username = username;
this.password = password;
this.email = email;
}
public User(String username, String password, String email) {
super();
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return this.username;
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public String getPassword() {
return this.password;
}
public String getEmail() {
return this.email;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", email=" + email + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (email == null) {
if (other.email != null)
return false;
}
else if (!email.equals(other.email))
return false;
if (password == null) {
if (other.password != null)
return false;
}
else if (!password.equals(other.password))
return false;
if (username == null) {
if (other.username != null)
return false;
}
else if (!username.equals(other.username))
return false;
return true;
}
public String getEmail() {
return this.email;
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2012 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.
@@ -17,8 +17,13 @@ import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
/**
*
* @author Gunnar Hillert
*
*/
public class UserMapper implements RowMapper<User> {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getString("username"), rs.getString("password"), rs.getString("email"));
}
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getString("username"), rs.getString("password"), rs.getString("email"));
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2002-2012 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.jdbc.storedproc.derby;
import java.util.Locale;
@@ -9,8 +24,8 @@ import java.util.Locale;
*/
public final class DerbyFunctions {
public static String convertStringToUpperCase( String invalue ) {
return invalue.toUpperCase(Locale.ENGLISH);
}
public static String convertStringToUpperCase( String invalue ) {
return invalue.toUpperCase(Locale.ENGLISH);
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2002-2012 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.jdbc.storedproc.derby;
import java.sql.Connection;
@@ -9,9 +24,9 @@ import java.sql.SQLException;
import org.springframework.jdbc.support.JdbcUtils;
/**
*
*
* @author Gunnar Hillert
*
*
*/
public final class DerbyStoredProcedures {
@@ -49,7 +64,7 @@ public final class DerbyStoredProcedures {
stmt.setString(2, password);
stmt.setString(3, email);
stmt.executeUpdate();
stmt2 = conn.prepareStatement("select * from USERS");
returnedData[0] = stmt2.executeQuery();

View File

@@ -0,0 +1,4 @@
DROP FUNCTION CONVERT_STRING_TO_UPPER_CASE;
DROP TABLE USERS;
DROP PROCEDURE CREATE_USER;
DROP PROCEDURE CREATE_USER_RETURN_ALL;

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<jdbc:embedded-database id="dataSource" type="DERBY"/>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS" >
<jdbc:script location="classpath:derby-stored-procedures-drops.sql"/>
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
</jdbc:initialize-database>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>