Initial draft of the stored proc. adapters
The following 3 components are provided: * stored-proc-outbound-channel-adapter * stored-proc-outbound-gateway * stored-proc-inbound-channel-adapter
This commit is contained in:
committed by
Mark Fisher
parent
3e1b0596bb
commit
b018ea84c8
@@ -310,7 +310,7 @@ project('spring-integration-jdbc') {
|
||||
compile "org.springframework:spring-jdbc:$springVersion"
|
||||
compile "org.springframework:spring-tx:$springVersion"
|
||||
testCompile project(":spring-integration-test")
|
||||
testCompile "com.h2database:h2:1.2.125"
|
||||
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"
|
||||
|
||||
@@ -220,5 +220,293 @@
|
||||
separate for different physical channels that happen to have the same
|
||||
logical name.</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section id="stored-procedures">
|
||||
<title>Stored Procedures</title>
|
||||
<para>Spring Integration provides 3 components for stored procedures support:</para>
|
||||
<itemizedlist>
|
||||
<listitem>Stored Procedures Inbound Channel Adapter</listitem>
|
||||
<listitem>Stored Procedures Outbound Channel Adapter</listitem>
|
||||
<listitem>Stored Procedures Outbound Gateway</listitem>
|
||||
</itemizedlist>
|
||||
<section id="sp-common-config-params">
|
||||
<title>Common Configuration Parameters</title>
|
||||
</section>
|
||||
<section id="sp-supported-databases">
|
||||
<title>Supported Parameters</title>
|
||||
<para>The Store procedures components use the <classname>org.springframework.jdbc.core.simple.SimpleJdbcCall</classname>
|
||||
class to facilitate Stored Procedure support. The following databases
|
||||
are fully supported for executing Stored procedures:</para>
|
||||
<itemizedlist>
|
||||
<listitem>Apache Derby</listitem>
|
||||
<listitem>DB2</listitem>
|
||||
<listitem>MySQL</listitem>
|
||||
<listitem>Microsoft SQL Server</listitem>
|
||||
<listitem>Oracle</listitem>
|
||||
<listitem>PostgreSQL</listitem>
|
||||
<listitem>Sybase</listitem>
|
||||
</itemizedlist>
|
||||
<para>The following databases are fully supported for executing Sql
|
||||
functions:</para>
|
||||
<itemizedlist>
|
||||
<listitem>MySQL</listitem>
|
||||
<listitem>Microsoft SQL Server</listitem>
|
||||
<listitem>Oracle</listitem>
|
||||
<listitem>PostgreSQL</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<note><para>Even though your particular database may not be fully supported, chances
|
||||
are that you can use the Stored Procedures Spring Integration
|
||||
components quite successfully anyway, provided your RDBMS supports
|
||||
Stored Procedures or Functions.</para>
|
||||
<para>As a matter of fact, some of the provided
|
||||
integration tests use the the H2 database. Nevertheless it is very important
|
||||
to thouroughly test those usasge scenarios.</para></note>
|
||||
<section id="sp-defining-parameter-sources">
|
||||
<title>Defining Parameter Sources</title>
|
||||
<para>TBD</para>
|
||||
</section>
|
||||
<section id="stored-procedures-inbound-channel-adapter">
|
||||
<title>Stored Procedures Inbound Channel Adapter</title>
|
||||
|
||||
<programlisting language="xml">
|
||||
<![CDATA[
|
||||
<int-jdbc:stored-proc-inbound-channel-adapter
|
||||
channel="" ]]><co id="sp-inbound-xml01-co" linkends="sp-inbound-xml01" /><![CDATA[
|
||||
stored-procedure-name="" ]]><co id="sp-inbound-xml02-co" linkends="sp-inbound-xml02" /><![CDATA[
|
||||
data-source="" ]]><co id="sp-inbound-xml03-co" linkends="sp-inbound-xml03" /><![CDATA[
|
||||
auto-startup="true" ]]><co id="sp-inbound-xml04-co" linkends="sp-inbound-xml04" /><![CDATA[
|
||||
id="" ]]><co id="sp-inbound-xml05-co" linkends="sp-inbound-xml05" /><![CDATA[
|
||||
ignore-column-meta-data="false" ]]><co id="sp-inbound-xml06-co" linkends="sp-inbound-xml06" /><![CDATA[
|
||||
is-function="false" ]]><co id="sp-inbound-xml07-co" linkends="sp-inbound-xml07" /><![CDATA[
|
||||
max-rows-per-poll="" ]]><co id="sp-inbound-xml08-co" linkends="sp-inbound-xml08" /><![CDATA[
|
||||
update="" ]]><co id="sp-inbound-xml09-co" linkends="sp-inbound-xml09" /><![CDATA[
|
||||
update-per-row="false" ]]><co id="sp-inbound-xml10-co" linkends="sp-inbound-xml10" /><![CDATA[
|
||||
update-sql-parameter-source-factory=""> ]]><co id="sp-inbound-xml11-co" linkends="sp-inbound-xml11" /><![CDATA[
|
||||
<int:poller/> ]]><co id="sp-inbound-xml12-co" linkends="sp-inbound-xml12" /><![CDATA[
|
||||
<int-jdbc:sql-parameter-definition name="" direction="IN" ]]><co id="sp-inbound-xml13-co" linkends="sp-inbound-xml13" /><![CDATA[
|
||||
type="INTEGER" ]]><co id="sp-inbound-xml14-co" linkends="sp-inbound-xml14" /><![CDATA[
|
||||
scale="10"/> ]]><co id="sp-inbound-xml15-co" linkends="sp-inbound-xml15" /><![CDATA[
|
||||
<int-jdbc:parameter name="" type="" value=""/> ]]><co id="sp-inbound-xml16-co" linkends="sp-inbound-xml16" /><![CDATA[
|
||||
<int-jdbc:parameter name="" expression=""/> ]]><co id="sp-inbound-xml17-co" linkends="sp-inbound-xml17" /><![CDATA[
|
||||
<int-jdbc:returning-resultset name="" row-mapper="" /> ]]><co id="sp-inbound-xml18-co" linkends="sp-inbound-xml18" /><![CDATA[
|
||||
</int-jdbc:stored-proc-inbound-channel-adapter> ]]><co id="sp-inbound-xml19-co" linkends="sp-inbound-xml19" /><![CDATA[
|
||||
]]>
|
||||
</programlisting>
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="sp-inbound-xml01-co" id="sp-inbound-xml01">
|
||||
<para>Channel to which polled messages will be send. If the stored
|
||||
procedure or function does not return any data, the payload
|
||||
of the Message will be Null. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml02-co" id="sp-inbound-xml02">
|
||||
<para>The name of the stored procedure. If the "is-function"
|
||||
attribute is "true", this attributes specifies the
|
||||
function name. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml03-co" id="sp-inbound-xml03">
|
||||
<para>Reference to a data source to use to access
|
||||
the database. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml04-co" id="sp-inbound-xml04">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml05-co" id="sp-inbound-xml05">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml06-co" id="sp-inbound-xml06">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml07-co" id="sp-inbound-xml07">
|
||||
<para>If "true", a SQL Function is called. In that case
|
||||
the "stored-procedure-name" attribute defines
|
||||
the name of the called function. Defaults to false. <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml08-co" id="sp-inbound-xml08">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml09-co" id="sp-inbound-xml09">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml10-co" id="sp-inbound-xml10">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml11-co" id="sp-inbound-xml11">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml12-co" id="sp-inbound-xml12">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml13-co" id="sp-inbound-xml13">
|
||||
<para>Specifies the direction of the Sql parameter definition.
|
||||
Defaults to 'IN'. If your procedure is returning ResultSets,
|
||||
please use the 'returning-resultset' element. <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml14-co" id="sp-inbound-xml14">
|
||||
<para>The Sql type used for this Sql parameter defintion. Will translate
|
||||
into the integer value as defined by java.sql.Types. Alternatively
|
||||
you can provide the integer value as well. If this attribute is
|
||||
not explicitly set, then it will default to 'VARCHAR'.<emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml15-co" id="sp-inbound-xml15">
|
||||
<para>The scale of the Sql parameter. Only used for numeric and decimal
|
||||
parameters. <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml16-co" id="sp-inbound-xml16">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml17-co" id="sp-inbound-xml17">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml18-co" id="sp-inbound-xml18">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-inbound-xml19-co" id="sp-inbound-xml19">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
</calloutlist></para>
|
||||
</section>
|
||||
<section id="stored-procedures-outbound-channel-adapter">
|
||||
<title>Stored Procedures Outbound Channel Adapter</title>
|
||||
|
||||
<programlisting language="xml">
|
||||
<![CDATA[
|
||||
<int-jdbc:stored-proc-outbound-channel-adapter channel="" ]]><co id="sp-outbound-xml01-co" linkends="sp-outbound-xml01" /><![CDATA[
|
||||
stored-procedure-name="" ]]><co id="sp-outbound-xml02-co" linkends="sp-outbound-xml02" /><![CDATA[
|
||||
data-source="" ]]><co id="sp-outbound-xml03-co" linkends="sp-outbound-xml03" /><![CDATA[
|
||||
auto-startup="true" ]]><co id="sp-outbound-xml04-co" linkends="sp-outbound-xml04" /><![CDATA[
|
||||
id="" ]]><co id="sp-outbound-xml05-co" linkends="sp-outbound-xml05" /><![CDATA[
|
||||
ignore-column-meta-data="false" ]]><co id="sp-outbound-xml06-co" linkends="sp-outbound-xml06" /><![CDATA[
|
||||
order="" ]]><co id="sp-outbound-xml07-co" linkends="sp-outbound-xml07" /><![CDATA[
|
||||
return-value-required="false" ]]><co id="sp-outbound-xml08-co" linkends="sp-outbound-xml08" /><![CDATA[
|
||||
sql-parameter-source-factory=""> ]]><co id="sp-outbound-xml09-co" linkends="sp-outbound-xml09" /><![CDATA[
|
||||
<int:poller fixed-rate=""/>
|
||||
<int-jdbc:sql-parameter-definition name=""/>
|
||||
<int-jdbc:parameter name=""/>
|
||||
|
||||
</int-jdbc:stored-proc-outbound-channel-adapter>
|
||||
]]>
|
||||
</programlisting>
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="sp-outbound-xml01-co" id="sp-outbound-xml01">
|
||||
<para> <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml02-co" id="sp-outbound-xml02">
|
||||
<para>The name of the stored procedure. If the "is-function"
|
||||
attribute is "true", this attributes specifies the
|
||||
function name. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml03-co" id="sp-outbound-xml03">
|
||||
<para>Reference to a data source to use to access
|
||||
the database. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml04-co" id="sp-outbound-xml04">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml05-co" id="sp-outbound-xml05">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml06-co" id="sp-outbound-xml06">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml07-co" id="sp-outbound-xml07">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml08-co" id="sp-outbound-xml08">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-outbound-xml09-co" id="sp-outbound-xml09">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
</calloutlist></para>
|
||||
</section>
|
||||
<section id="stored-procedures-outbound-gateway">
|
||||
<title>Stored Procedures Outbound Gateway</title>
|
||||
|
||||
<programlisting language="xml">
|
||||
<![CDATA[
|
||||
<int-jdbc:stored-proc-outbound-gateway request-channel="" ]]><co id="sp-gateway-xml01-co" linkends="sp-gateway-xml01" /><![CDATA[
|
||||
stored-procedure-name="" ]]><co id="sp-gateway-xml02-co" linkends="sp-gateway-xml02" /><![CDATA[
|
||||
data-source="" ]]><co id="sp-gateway-xml03-co" linkends="sp-gateway-xml03" /><![CDATA[
|
||||
auto-startup="true" ]]><co id="sp-gateway-xml04-co" linkends="sp-gateway-xml04" /><![CDATA[
|
||||
id="" ]]><co id="sp-gateway-xml05-co" linkends="sp-gateway-xml05" /><![CDATA[
|
||||
ignore-column-meta-data="false" ]]><co id="sp-gateway-xml06-co" linkends="sp-gateway-xml06" /><![CDATA[
|
||||
is-function="false" ]]><co id="sp-gateway-xml07-co" linkends="sp-gateway-xml07" /><![CDATA[
|
||||
order="" ]]><co id="sp-gateway-xml08-co" linkends="sp-gateway-xml08" /><![CDATA[
|
||||
reply-channel="" ]]><co id="sp-gateway-xml09-co" linkends="sp-gateway-xml09" /><![CDATA[
|
||||
request-timeout="" ]]><co id="sp-gateway-xml10-co" linkends="sp-gateway-xml10" /><![CDATA[
|
||||
return-value-required="false" ]]><co id="sp-gateway-xml11-co" linkends="sp-gateway-xml11" /><![CDATA[
|
||||
sql-parameter-source-factory=""> ]]><co id="sp-gateway-xml12-co" linkends="sp-gateway-xml12" /><![CDATA[
|
||||
<int-jdbc:sql-parameter-definition name="" direction="IN"
|
||||
type=""
|
||||
scale="10"/> ]]><co id="sp-gateway-xml13-co" linkends="sp-gateway-xml13" /><![CDATA[
|
||||
<int-jdbc:sql-parameter-definition name=""/> ]]><co id="sp-gateway-xml14-co" linkends="sp-gateway-xml14" /><![CDATA[
|
||||
<int-jdbc:parameter name="" type="" value=""/> ]]><co id="sp-gateway-xml15-co" linkends="sp-gateway-xml15" /><![CDATA[
|
||||
<int-jdbc:parameter name="" expression=""/> ]]><co id="sp-gateway-xml16-co" linkends="sp-gateway-xml16" /><![CDATA[
|
||||
<int-jdbc:returning-resultset name="" row-mapper="" /> ]]><co id="sp-gateway-xml17-co" linkends="sp-gateway-xml17" /><![CDATA[
|
||||
]]></programlisting>
|
||||
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="sp-gateway-xml01-co" id="sp-gateway-xml01">
|
||||
<para> <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml02-co" id="sp-gateway-xml02">
|
||||
<para>The name of the stored procedure. If the "is-function"
|
||||
attribute is "true", this attributes specifies the
|
||||
function name. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml03-co" id="sp-gateway-xml03">
|
||||
<para>Reference to a data source to use to access
|
||||
the database. <emphasis>Required</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml04-co" id="sp-gateway-xml04">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml05-co" id="sp-gateway-xml05">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml06-co" id="sp-gateway-xml06">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml07-co" id="sp-gateway-xml07">
|
||||
<para>If "true", a SQL Function is called. In that case
|
||||
the "stored-procedure-name" attribute defines
|
||||
the name of the called function. Defaults to false. <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml08-co" id="sp-gateway-xml08">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml09-co" id="sp-gateway-xml09">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml10-co" id="sp-gateway-xml10">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml11-co" id="sp-gateway-xml11">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml12-co" id="sp-gateway-xml12">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml13-co" id="sp-gateway-xml13">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml14-co" id="sp-gateway-xml14">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml15-co" id="sp-gateway-xml15">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml16-co" id="sp-gateway-xml16">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-gateway-xml17-co" id="sp-gateway-xml17">
|
||||
<para> <emphasis>Optional</emphasis>.</para>
|
||||
</callout>
|
||||
</calloutlist></para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.2.125</version>
|
||||
<version>1.3.160</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
@@ -20,7 +20,6 @@ import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.expression.ExpressionException;
|
||||
import org.springframework.integration.util.AbstractExpressionEvaluator;
|
||||
import org.springframework.jdbc.core.namedparam.AbstractSqlParameterSource;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
@@ -29,6 +29,7 @@ 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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -36,6 +36,7 @@ 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
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.util.Assert;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcExecutor implements InitializingBean {
|
||||
|
||||
/**
|
||||
* Uses the {@link SimpleJdbcCall} implementation for executing Stored Procedures.
|
||||
* For more details please see:
|
||||
*/
|
||||
private final SimpleJdbcCallOperations jdbcCallOperations;
|
||||
|
||||
/**
|
||||
* Name of the stored procedure to execute.
|
||||
*/
|
||||
private volatile String 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 'true'. It defaults to 'false'.
|
||||
*/
|
||||
private volatile boolean ignoreColumnMetaData = false;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* This may be sufficient for basic use cases. For more sophisticated options
|
||||
* consider passing in one or more {@link ProcedureParameter}.
|
||||
*/
|
||||
private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new BeanPropertySqlParameterSourceFactory();
|
||||
|
||||
/**
|
||||
* 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 = false;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* 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 of 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 instanceof ExpressionEvaluatingSqlParameterSourceFactory)) {
|
||||
this.sqlParameterSourceFactory = new ExpressionEvaluatingSqlParameterSourceFactory();
|
||||
}
|
||||
|
||||
ExpressionEvaluatingSqlParameterSourceFactory expressionSourceFactory
|
||||
= (ExpressionEvaluatingSqlParameterSourceFactory) this.sqlParameterSourceFactory;
|
||||
|
||||
expressionSourceFactory.setStaticParameters(ProcedureParameter.convertStaticParameters(procedureParameters));
|
||||
expressionSourceFactory.setParameterExpressions(ProcedureParameter.convertExpressions(procedureParameters));
|
||||
|
||||
}
|
||||
|
||||
if (this.ignoreColumnMetaData) {
|
||||
this.jdbcCallOperations.withoutProcedureColumnMetaDataAccess();
|
||||
}
|
||||
|
||||
this.jdbcCallOperations.declareParameters(this.sqlParameters.toArray(new SqlParameter[this.sqlParameters.size()]));
|
||||
|
||||
|
||||
if (!this.returningResultSetRowMappers.isEmpty()) {
|
||||
|
||||
for (Entry<String, RowMapper<?>> mapEntry : this.returningResultSetRowMappers.entrySet()) {
|
||||
jdbcCallOperations.returningResultSet(mapEntry.getKey(), mapEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.returnValueRequired) {
|
||||
jdbcCallOperations.withReturnValue();
|
||||
}
|
||||
|
||||
if (this.isFunction) {
|
||||
this.jdbcCallOperations.withFunctionName(this.storedProcedureName);
|
||||
} else {
|
||||
this.jdbcCallOperations.withProcedureName(this.storedProcedureName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a Stored Procedure of Function - Use when not {@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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a Stored Procedure of 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.");
|
||||
|
||||
if (usePayloadAsParameterSource) {
|
||||
return executeStoredProcedureInternal(message.getPayload());
|
||||
} else {
|
||||
return executeStoredProcedureInternal(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
SqlParameterSource storedProcedureParameterSource =
|
||||
sqlParameterSourceFactory.createParameterSource(input);
|
||||
|
||||
return StoredProcExecutor.executeStoredProcedure(jdbcCallOperations,
|
||||
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;
|
||||
this.usePayloadAsParameterSource = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
this.usePayloadAsParameterSource = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the Stored Procedure or Function
|
||||
* */
|
||||
public String getStoredProcedureName() {
|
||||
return this.storedProcedureName;
|
||||
}
|
||||
|
||||
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
|
||||
this.usePayloadAsParameterSource = usePayloadAsParameterSource;
|
||||
}
|
||||
|
||||
public void setFunction(boolean isFunction) {
|
||||
this.isFunction = isFunction;
|
||||
}
|
||||
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.returnValueRequired = returnValueRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.");
|
||||
|
||||
for (RowMapper<?> rowMapper : returningResultSetRowMappers.values()) {
|
||||
Assert.notNull(rowMapper, "The provided map cannot contain null values.");
|
||||
}
|
||||
|
||||
this.returningResultSetRowMappers = returningResultSetRowMappers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageDeliveryException;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.MessageRejectedException;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcMessageHandler extends AbstractMessageHandler implements InitializingBean {
|
||||
|
||||
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) {
|
||||
|
||||
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.setUsePayloadAsParameterSource(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) throws MessageRejectedException, MessageHandlingException,
|
||||
MessageDeliveryException {
|
||||
|
||||
Map<String, Object> resultMap = executor.executeStoredProcedure(message);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//~~~~~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.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Stored Procedure parameters that may contain static values
|
||||
* or Strings representing an {@link Expression}.
|
||||
*/
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(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) {
|
||||
this.executor.setSqlParameters(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) {
|
||||
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
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 org.springframework.jdbc.core.simple.SimpleJdbcCallOperations;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHandler implements InitializingBean {
|
||||
|
||||
private final StoredProcExecutor executor;
|
||||
|
||||
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) {
|
||||
|
||||
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.setUsePayloadAsParameterSource(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
|
||||
Map<String, Object> resultMap = executor.executeStoredProcedure(requestMessage);
|
||||
|
||||
final Object payload;
|
||||
|
||||
if (resultMap.isEmpty()) {
|
||||
payload = null;
|
||||
} else {
|
||||
|
||||
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'. ");
|
||||
|
||||
} else {
|
||||
payload = resultMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return MessageBuilder.withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: {@link 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);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ignoreColumnMetaData
|
||||
*/
|
||||
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
|
||||
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param returnValueRequired
|
||||
*/
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.executor.setReturnValueRequired(returnValueRequired);
|
||||
}
|
||||
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(procedureParameters);
|
||||
}
|
||||
|
||||
public void setIsFunction(boolean isFunction) {
|
||||
this.executor.setFunction(isFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter indicates that only one result object shall be returned from
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* only 1 element, will have that 1 element extracted and returned as payload.
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
* Otherwise the complete resultMap is returned as the {@link Message} payload.
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
* a collection being returned.
|
||||
*
|
||||
* @param expectSingleResult
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.context.IntegrationObjectSupport;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
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 org.springframework.jdbc.core.simple.SimpleJdbcCall;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A polling channel adapter that creates messages from the payload returned by
|
||||
* executing a stored procedure or Sql function. Optionally an update can be executed
|
||||
* after the execution of the Stored Procedure or Function in order to update
|
||||
* processed rows.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*/
|
||||
public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport implements MessageSource<Object> {
|
||||
|
||||
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 of Function to execute
|
||||
*/
|
||||
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.");
|
||||
|
||||
this.executor = new StoredProcExecutor(dataSource, 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
final Object payload;
|
||||
|
||||
Map<String, ?> resultMap = doPoll();
|
||||
|
||||
if (resultMap.isEmpty()) {
|
||||
payload = null;
|
||||
} else {
|
||||
|
||||
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'. ");
|
||||
|
||||
} else {
|
||||
payload = resultMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return payload;
|
||||
|
||||
}
|
||||
|
||||
protected Map<String, ?> doPoll() {
|
||||
Map<String, Object> payload = this.executor.executeStoredProcedure();
|
||||
return payload;
|
||||
}
|
||||
|
||||
public String getComponentType(){
|
||||
return "stored-proc:inbound-channel-adapter";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
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: {@link 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);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ignoreColumnMetaData
|
||||
*/
|
||||
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
|
||||
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param returnValueRequired
|
||||
*/
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.executor.setReturnValueRequired(returnValueRequired);
|
||||
}
|
||||
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(procedureParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void setFunction(boolean isFunction) {
|
||||
this.executor.setFunction(isFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter indicates that only one result object shall be returned from
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* only 1 element, will have that 1 element extracted and returned as payload.
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
* Otherwise the complete resultMap is returned as the {@link Message} payload.
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
* a collection being returned.
|
||||
*
|
||||
* @param expectSingleResult
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
@@ -19,6 +19,7 @@ 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;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterPars
|
||||
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.integration.jdbc.JdbcMessageHandler");
|
||||
.genericBeanDefinition(JdbcMessageHandler.class);
|
||||
String dataSourceRef = element.getAttribute("data-source");
|
||||
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
|
||||
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
@@ -18,6 +18,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.jdbc.JdbcMessageStore;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class JdbcMessageStoreParser extends AbstractBeanDefinitionParser {
|
||||
Object source = parserContext.extractSource(element);
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.integration.jdbc.JdbcMessageStore");
|
||||
.genericBeanDefinition(JdbcMessageStore.class);
|
||||
|
||||
String dataSourceRef = element.getAttribute("data-source");
|
||||
String simpleJdbcOperationsRef = element.getAttribute("jdbc-operations");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -23,6 +23,8 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @author Dave Syer
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class JdbcNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
@@ -32,6 +34,9 @@ public class JdbcNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
registerBeanDefinitionParser("outbound-channel-adapter", new JdbcMessageHandlerParser());
|
||||
registerBeanDefinitionParser("outbound-gateway", new JdbcOutboundGatewayParser());
|
||||
registerBeanDefinitionParser("message-store", new JdbcMessageStoreParser());
|
||||
registerBeanDefinitionParser("stored-proc-outbound-channel-adapter", new StoredProcMessageHandlerParser());
|
||||
registerBeanDefinitionParser("stored-proc-inbound-channel-adapter", new StoredProcPollingChannelAdapterParser());
|
||||
registerBeanDefinitionParser("stored-proc-outbound-gateway", new StoredProcOutboundGatewayParser());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
@@ -17,6 +17,7 @@ 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;
|
||||
|
||||
@@ -58,7 +59,7 @@ public class JdbcOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
return null;
|
||||
}
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.integration.jdbc.JdbcOutboundGateway");
|
||||
.genericBeanDefinition(JdbcOutboundGateway.class);
|
||||
if (refToDataSourceSet) {
|
||||
builder.addConstructorArgReference(dataSourceRef);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
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.JdbcPollingChannelAdapter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for {@link org.springframework.integration.jdbc.JdbcPollingChannelAdapter}.
|
||||
@@ -46,7 +46,7 @@ public class JdbcPollingChannelAdapterParser extends AbstractPollingInboundChann
|
||||
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.integration.jdbc.JdbcPollingChannelAdapter");
|
||||
.genericBeanDefinition(JdbcPollingChannelAdapter.class);
|
||||
String dataSourceRef = element.getAttribute("data-source");
|
||||
String jdbcOperationsRef = element.getAttribute("jdbc-operations");
|
||||
boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 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
|
||||
* 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),
|
||||
SQLXML(Types.SQLXML);
|
||||
|
||||
private int code;
|
||||
|
||||
/** Constructor */
|
||||
JdbcTypesEnum(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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");
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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");
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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 java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.TypedStringValue;
|
||||
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.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.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public final class StoredProcParserUtils {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(StoredProcParserUtils.class);
|
||||
|
||||
/** Prevent instantiation. */
|
||||
private StoredProcParserUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gatewayElement
|
||||
* @param parserContext
|
||||
* @return
|
||||
*/
|
||||
public static ManagedList<BeanDefinition> getSqlParameterDefinitionBeanDefinitions(
|
||||
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)) {
|
||||
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlInOutParameter.class);
|
||||
} else {
|
||||
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlParameter.class);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(name)) {
|
||||
parameterBuilder.addConstructorArgValue(name);
|
||||
} 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 {
|
||||
parameterBuilder.addConstructorArgValue(sqlType);
|
||||
}
|
||||
|
||||
} else {
|
||||
parameterBuilder.addConstructorArgValue(Types.VARCHAR);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(scale)) {
|
||||
parameterBuilder.addConstructorArgValue(new TypedStringValue(scale, Integer.class));
|
||||
}
|
||||
|
||||
sqlParameterList.add(parameterBuilder.getBeanDefinition());
|
||||
}
|
||||
return sqlParameterList;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gatewayElement
|
||||
* @param parserContext
|
||||
* @return
|
||||
*/
|
||||
public static ManagedList<BeanDefinition> getProcedureParameterBeanDefinitions(
|
||||
Element storedProcComponent, ParserContext parserContext) {
|
||||
|
||||
ManagedList<BeanDefinition> procedureParameterList = new ManagedList<BeanDefinition>();
|
||||
|
||||
List<Element> parameterChildElements = DomUtils
|
||||
.getChildElementsByTagName(storedProcComponent, "parameter");
|
||||
|
||||
for (Element childElement : parameterChildElements) {
|
||||
|
||||
BeanDefinitionBuilder parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(ProcedureParameter.class);
|
||||
|
||||
String name = childElement.getAttribute("name");
|
||||
String expression = childElement.getAttribute("expression");
|
||||
String value = childElement.getAttribute("value");
|
||||
String type = childElement.getAttribute("type");
|
||||
|
||||
if (StringUtils.hasText(name)) {
|
||||
parameterBuilder.addPropertyValue("name", name);
|
||||
} else {
|
||||
parserContext
|
||||
.getReaderContext()
|
||||
.error("The 'name' attribute must be set for the Stored Procedure parameter element.",
|
||||
storedProcComponent);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(expression)) {
|
||||
parameterBuilder.addPropertyValue("expression", expression);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(value)) {
|
||||
|
||||
if (!StringUtils.hasText(type)) {
|
||||
logger.info(String
|
||||
.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 {
|
||||
parameterBuilder.addPropertyValue("value",
|
||||
new TypedStringValue(value, type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
procedureParameterList.add(parameterBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
return procedureParameterList;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gatewayElement
|
||||
* @param parserContext
|
||||
* @return
|
||||
*/
|
||||
public static ManagedMap<String, BeanDefinition> getReturningResultsetBeanDefinitions(
|
||||
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());
|
||||
}
|
||||
|
||||
return returningResultsetMap;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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");
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.storedproc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstraction of Procedure parameters allowing to provide static parameters
|
||||
* and SpEl Expression based parameters.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class ProcedureParameter {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, "Please provide a name.");
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that converts a Collection of {@link ProcedureParameter} to
|
||||
* a Map containing only expression parameters.
|
||||
*
|
||||
* @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.");
|
||||
|
||||
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.
|
||||
* @return Map containing only the static parameters. Will never be null.
|
||||
*/
|
||||
public static Map<String, Object> convertStaticParameters(Collection<ProcedureParameter> procedureParameters) {
|
||||
|
||||
Map<String, Object> staticParameters = new HashMap<String, Object>();
|
||||
|
||||
for (ProcedureParameter parameter : procedureParameters) {
|
||||
if (parameter.getValue() != null) {
|
||||
staticParameters.put(parameter.getName(), parameter.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return staticParameters;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -551,4 +551,609 @@
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="stored-proc-outbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines an outbound Channel Adapter for updating a
|
||||
database using stored procedures.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
<xsd:element name="sql-parameter-definition" minOccurs="0"
|
||||
maxOccurs="unbounded" type="sqlParameterDefinitionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded"
|
||||
type="parameterSubElementType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides a mechanism to provide stored procedure
|
||||
parameters.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="coreStoredProcComponentAttributes"/>
|
||||
<xsd:attribute name="sql-parameter-source-factory"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
outgoing message. The
|
||||
default factory creates a bean
|
||||
property parameter source so the query can specify named
|
||||
parameters like :payload and :headers[foo].
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.jdbc.SqlParameterSourceFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Channel from which messages will be output.
|
||||
When a message is sent to this channel it will
|
||||
cause the query
|
||||
to be executed.
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies the order for invocation when this endpoint is connected as a
|
||||
subscriber to a SubscribableChannel.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="return-value-required" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="stored-proc-outbound-gateway">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines an Outbound Channel Gateway for updating a database using
|
||||
a stored procedure. The response of the stored procedure is used
|
||||
to populate the Message for the reply channel.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sql-parameter-definition" minOccurs="0"
|
||||
maxOccurs="unbounded" type="sqlParameterDefinitionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
generally need not be declared as for those
|
||||
databases the type information can be
|
||||
retrieved from the JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded"
|
||||
type="parameterSubElementType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides a mechanism to provide stored procedure
|
||||
parameters. Parameters can be either static
|
||||
or provided using a SpEL Expression.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="returning-resultset" minOccurs="0"
|
||||
maxOccurs="unbounded" type="returningResultSetRowMappersType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Storeed procedured may return multiple resultsets.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="coreStoredProcComponentAttributes"/>
|
||||
<xsd:attribute name="sql-parameter-source-factory"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
outgoing message. The
|
||||
default factory creates a bean
|
||||
property parameter source so the query can specify named
|
||||
parameters like :payload and :headers[foo].
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.jdbc.SqlParameterSourceFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="is-function" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
If "true", a SQL Function is called. In that case
|
||||
the "stored-procedure-name" attribute defines
|
||||
the name of the called function.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This parameter indicates that only one result object shall be returned from
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
from the Stored Procedure/Function Call contains only 1 element,
|
||||
then that 1 element is extracted and returned as payload.
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
payload.
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
The H2 database, for example, does not fully support the CallableStatement
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
you may end up with a collection being returned.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-channel" type="xsd:string"
|
||||
use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="reply-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-timeout" type="xsd:string" />
|
||||
<xsd:attribute name="order">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies the order for invocation when this endpoint is connected as a
|
||||
subscriber to a SubscribableChannel.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="return-value-required" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Indicates whether this procedure's return value
|
||||
should be included.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="stored-proc-inbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines an inbound Channel Adapter for polling a
|
||||
database using a stored procedure or function.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
<xsd:element name="sql-parameter-definition" minOccurs="0"
|
||||
maxOccurs="unbounded" type="sqlParameterDefinitionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded"
|
||||
type="parameterSubElementType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides a mechanism to provide stored procedure
|
||||
parameters.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="returning-resultset" minOccurs="0"
|
||||
maxOccurs="unbounded" type="returningResultSetRowMappersType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Storeed procedured may return multiple resultsets.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="coreStoredProcComponentAttributes"/>
|
||||
<xsd:attribute name="is-function" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
If "true", a SQL Function is called. In that case
|
||||
the "stored-procedure-name" attribute defines
|
||||
the name of the called function.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This parameter indicates that only one result object shall be returned from
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
from the Stored Procedure/Function Call contains only 1 element,
|
||||
then that 1 element is extracted and returned as payload.
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
payload.
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
The H2 database, for example, does not fully support the CallableStatement
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
you may end up with a collection being returned.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Channel to which polled messages will be send. If the stored
|
||||
procedure or function does not return any data, the payload
|
||||
of the Message will be Null.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:attributeGroup name="coreStoredProcComponentAttributes">
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional" />
|
||||
<xsd:attribute name="stored-procedure-name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The name of the stored procedure. If the "is-function"
|
||||
attribute is "true", this attributes specifies the
|
||||
function name.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="data-source" type="xsd:string" use="required" >
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a data source to use to access
|
||||
the database.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.sql.DataSource" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-startup" type="xsd:string" default="true" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Flag to indicate that the poller should start automatically
|
||||
on startup (default true).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ignore-column-meta-data" default="false" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
If true, the JDBC parameter definitions for the stored procedure
|
||||
are not automatically derived from the underlying JDBC connection. In
|
||||
that case you must specify all Sql parameter definitions explicitly
|
||||
using the 'sql-parameter-definition' sub-element.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:complexType name="parameterSubElementType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of stored procedure or function parameter.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="value" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The value of the parameter. Either this or the 'expression'
|
||||
attribute must be provided.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The type of the value used. If nothing is provided this attribute
|
||||
will default to java.lang.String. This attribute is not used
|
||||
when the 'expression' attribute is used instead.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Expression to be evaluated to produce a value for the header.
|
||||
Either this or the 'value' attribute must be provided.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="returningResultSetRowMappersType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the under which the resultset will be returned.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="row-mapper" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||
The fully qualified class name of the row mapper.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="sqlParameterDefinitionType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the Sql parameter.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="direction" use="optional" default="IN">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the direction of the Sql parameter definition. Defaults
|
||||
to 'IN'. If your procedure is returning ResultSets, please
|
||||
use the 'returning-resultset' element.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="sqlTypeDirection xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The Sql type used for this Sql parameter defintion. Will translate
|
||||
into the integer value as defined by java.sql.Types. Alternatively
|
||||
you can provide the integer value as well. If this attribute is
|
||||
not explicitly set, then it will default to 'VARCHAR'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="sqlType xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="scale" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The scale of the Sql parameter. Only used for numeric and decimal
|
||||
parameters.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="sqlType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="VARCHAR"/>
|
||||
<xsd:enumeration value="ARRAY"/>
|
||||
<xsd:enumeration value="BIGINT"/>
|
||||
<xsd:enumeration value="BINARY"/>
|
||||
<xsd:enumeration value="BIT"/>
|
||||
<xsd:enumeration value="BLOB"/>
|
||||
<xsd:enumeration value="BOOLEAN"/>
|
||||
<xsd:enumeration value="CHAR"/>
|
||||
<xsd:enumeration value="CLOB"/>
|
||||
<xsd:enumeration value="DATALINK"/>
|
||||
<xsd:enumeration value="DATE"/>
|
||||
<xsd:enumeration value="DECIMAL"/>
|
||||
<xsd:enumeration value="DISTINCT"/>
|
||||
<xsd:enumeration value="DOUBLE"/>
|
||||
<xsd:enumeration value="FLOAT"/>
|
||||
<xsd:enumeration value="INTEGER"/>
|
||||
<xsd:enumeration value="JAVA_OBJECT"/>
|
||||
<xsd:enumeration value="LONGVARBINARY"/>
|
||||
<xsd:enumeration value="LONGNVARCHAR"/>
|
||||
<xsd:enumeration value="LONGVARCHAR"/>
|
||||
<xsd:enumeration value="NCHAR"/>
|
||||
<xsd:enumeration value="NCLOB"/>
|
||||
<xsd:enumeration value="NULL"/>
|
||||
<xsd:enumeration value="NUMERIC"/>
|
||||
<xsd:enumeration value="NVARCHAR"/>
|
||||
<xsd:enumeration value="OTHER"/>
|
||||
<xsd:enumeration value="REAL"/>
|
||||
<xsd:enumeration value="REF"/>
|
||||
<xsd:enumeration value="ROWID"/>
|
||||
<xsd:enumeration value="SMALLINT"/>
|
||||
<xsd:enumeration value="SQLXML"/>
|
||||
<xsd:enumeration value="STRUCT"/>
|
||||
<xsd:enumeration value="TIME"/>
|
||||
<xsd:enumeration value="TIMESTAMP"/>
|
||||
<xsd:enumeration value="TINYINT"/>
|
||||
<xsd:enumeration value="VARBINARY"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="sqlTypeDirection">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="IN"/>
|
||||
<xsd:enumeration value="OUT"/>
|
||||
<xsd:enumeration value="INOUT"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
@@ -1,11 +0,0 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
|
||||
|
||||
|
||||
log4j.category.org.springframework=WARN
|
||||
# log4j.category.org.springframework.integration=DEBUG
|
||||
# log4j.category.org.springframework.integration.jdbc=DEBUG
|
||||
log4j.category.org.springframework.jdbc=DEBUG
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -29,8 +31,6 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
<int:logging-channel-adapter channel="output" />
|
||||
|
||||
<service-activator id="service-activator"
|
||||
input-channel="input" output-channel="output"
|
||||
input-channel="input" output-channel="output"
|
||||
xmlns="http://www.springframework.org/schema/integration">
|
||||
<beans:bean
|
||||
<beans:bean
|
||||
class="org.springframework.integration.jdbc.JdbcMessageStoreChannelIntegrationTests$Service" />
|
||||
<poller fixed-rate="200">
|
||||
<advice-chain>
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.junit.Before;
|
||||
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.integration.channel.QueueChannel;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
@@ -35,10 +39,6 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Jonas Partner
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
public class StoredProcExecutorTest {
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithNullDataSource() {
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(null, "storedProcedureName");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("dataSource must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithNullProcedureName() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(datasource, null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithEmptyProcedureName() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(datasource, " ");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithNullMap() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
try {
|
||||
storedProcExecutor.setReturningResultSetRowMappers(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("returningResultSetRowMappers must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithMapContainingNullValues() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
|
||||
rowmappers.put("results", null);
|
||||
|
||||
try {
|
||||
storedProcExecutor.setReturningResultSetRowMappers(rowmappers);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided map cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithEmptyMap() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
|
||||
|
||||
storedProcExecutor.setReturningResultSetRowMappers(rowmappers);
|
||||
|
||||
//Should Successfully finish
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSqlParameterSourceFactoryWithNullParameter() {
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameterSourceFactory(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("sqlParameterSourceFactory must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithNullValueInList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
|
||||
sqlParameters.add(null);
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameters(sqlParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided list (sqlParameters) cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithEmptyList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameters(sqlParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("sqlParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithNullList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameters(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("sqlParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithNullValueInList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
|
||||
procedureParameters.add(null);
|
||||
|
||||
try {
|
||||
storedProcExecutor.setProcedureParameters(procedureParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided list (procedureParameters) cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithEmptyList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
|
||||
|
||||
try {
|
||||
storedProcExecutor.setProcedureParameters(procedureParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("procedureParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithNullList() {
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
try {
|
||||
storedProcExecutor.setProcedureParameters(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("procedureParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.integration.jdbc.storedproc.User;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
public class StoredProcMessageHandlerDerbyIntegrationTests {
|
||||
|
||||
private static Log LOGGER = LogFactory.getLog(StoredProcMessageHandlerDerbyIntegrationTests.class);
|
||||
|
||||
private EmbeddedDatabase embeddedDatabase;
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.embeddedDatabase.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDerbyStoredProcedureInsertWithDefaultSqlSource() {
|
||||
|
||||
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "CREATE_USER");
|
||||
messageHandler.afterPropertiesSet();
|
||||
MessageBuilder<User> message = MessageBuilder.withPayload(new User("username", "password", "email"));
|
||||
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() {
|
||||
|
||||
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "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()"));
|
||||
|
||||
messageHandler.setProcedureParameters(procedureParameters);
|
||||
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");
|
||||
|
||||
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() {
|
||||
|
||||
StoredProcMessageHandler messageHandler = new StoredProcMessageHandler(this.embeddedDatabase, "CREATE_USER");
|
||||
|
||||
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));
|
||||
|
||||
messageHandler.setProcedureParameters(procedureParameters);
|
||||
messageHandler.afterPropertiesSet();
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?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-2.1.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">
|
||||
|
||||
<jdbc:embedded-database id="datasource" type="DERBY">
|
||||
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<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-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="outputChannel"/>
|
||||
|
||||
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
|
||||
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithNamespaceIntegrationTests$Consumer"/>
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
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 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.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class StoredProcOutboundGatewayWithNamespaceIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private AbstractApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Consumer consumer;
|
||||
|
||||
@Autowired
|
||||
CreateUser createUser;
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
|
||||
createUser.createUser(new User("myUsername", "myPassword", "myEmail"));
|
||||
|
||||
List<Message<?>> received = new ArrayList<Message<?>>();
|
||||
|
||||
received.add(consumer.poll(2000));
|
||||
|
||||
Message<?> message = received.get(0);
|
||||
context.stop();
|
||||
assertNotNull(message);
|
||||
assertNotNull(message.getPayload());
|
||||
assertNotNull(message.getPayload() instanceof Collection<?>);
|
||||
|
||||
Collection<User> allUsers = (Collection<User>) message.getPayload();
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
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<?>> messages = new LinkedBlockingQueue<Message<?>>();
|
||||
|
||||
@ServiceActivator
|
||||
public void receive(Message<?>message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
Message<?> poll(long timeoutInMillis) throws InterruptedException {
|
||||
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?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-2.1.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">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="DERBY">
|
||||
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<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>
|
||||
|
||||
<bean id="storedProcedureEndpoint"
|
||||
class="org.springframework.integration.endpoint.EventDrivenConsumer">
|
||||
<constructor-arg name="inputChannel" ref="startChannel"/>
|
||||
<constructor-arg name="handler" ref="gateway"/>
|
||||
</bean>
|
||||
|
||||
<bean id="rowMapper" class="org.springframework.integration.jdbc.storedproc.UserMapper"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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 javax.sql.DataSource;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
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.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class StoredProcOutboundGatewayWithSpringContextIntegrationTests {
|
||||
|
||||
private static Logger logger = Logger.getLogger(StoredProcOutboundGatewayWithSpringContextIntegrationTests.class);
|
||||
|
||||
@Autowired
|
||||
private DataSource datasource;
|
||||
|
||||
@Autowired
|
||||
private AbstractApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Consumer consumer;
|
||||
|
||||
@Autowired
|
||||
CreateUser createUser;
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
|
||||
createUser.createUser(new User("myUsername", "myPassword", "myEmail"));
|
||||
|
||||
List<Message<?>> received = new ArrayList<Message<?>>();
|
||||
|
||||
received.add(consumer.poll(2000));
|
||||
|
||||
Message<?> message = received.get(0);
|
||||
context.stop();
|
||||
assertNotNull(message);
|
||||
assertNotNull(message.getPayload());
|
||||
assertNotNull(message.getPayload() instanceof Collection<?>);
|
||||
|
||||
Collection<User> allUsers = (Collection<User>) message.getPayload();
|
||||
|
||||
assertTrue(allUsers.size() == 1);
|
||||
|
||||
}
|
||||
|
||||
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<?>> messages = new LinkedBlockingQueue<Message<?>>();
|
||||
|
||||
@ServiceActivator
|
||||
public void receive(Message<?>message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
Message<?> poll(long timeoutInMillis) throws InterruptedException {
|
||||
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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
|
||||
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">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="H2">
|
||||
<jdbc:script location="classpath:h2-stored-procedures.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<int-jdbc:stored-proc-inbound-channel-adapter id="inbound-adapter" channel="outputChannel" data-source="dataSource"
|
||||
ignore-column-meta-data="true"
|
||||
expect-single-result="true"
|
||||
stored-procedure-name="GET_RANDOM_NUMBER">
|
||||
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.jdbc.core.SingleColumnRowMapper"/>
|
||||
</int-jdbc:stored-proc-inbound-channel-adapter>
|
||||
|
||||
<int:poller id="defaultPoller" default="true" fixed-rate="5000"/>
|
||||
|
||||
<int:channel id="outputChannel"/>
|
||||
|
||||
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
|
||||
|
||||
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapterWithNamespace2IntegrationTests$Consumer"/>
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class StoredProcPollingChannelAdapterWithNamespace2IntegrationTests {
|
||||
|
||||
private static Logger logger = Logger.getLogger(StoredProcPollingChannelAdapterWithNamespace2IntegrationTests.class);
|
||||
|
||||
@Autowired
|
||||
private AbstractApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Consumer consumer;
|
||||
|
||||
@Test
|
||||
public void pollH2DatabaseUsingStoredProcedureCall() throws Exception {
|
||||
List<Message<?>> received = new ArrayList<Message<?>>();
|
||||
|
||||
received.add(consumer.poll(60000));
|
||||
|
||||
Message<?> message = received.get(0);
|
||||
context.stop();
|
||||
assertNotNull(message);
|
||||
assertNotNull(message.getPayload());
|
||||
assertTrue(message.getPayload() instanceof List<?>);
|
||||
|
||||
List<Integer> resultList = (List<Integer>) message.getPayload();
|
||||
|
||||
assertTrue(resultList.size() == 1);
|
||||
|
||||
}
|
||||
|
||||
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<?>> messages = new LinkedBlockingQueue<Message<?>>();
|
||||
|
||||
@ServiceActivator
|
||||
public void receive(Message<?>message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
Message<?> poll(long timeoutInMillis) throws InterruptedException {
|
||||
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?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:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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
|
||||
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">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="H2">
|
||||
<jdbc:script location="classpath:h2-stored-procedures.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<int-jdbc:stored-proc-inbound-channel-adapter id="inbound-adapter" channel="outputChannel" data-source="dataSource"
|
||||
ignore-column-meta-data="true"
|
||||
expect-single-result="true"
|
||||
stored-procedure-name="GET_PRIME_NUMBERS">
|
||||
<int-jdbc:sql-parameter-definition name="beginRange" direction="IN" type="INTEGER"/>
|
||||
<int-jdbc:sql-parameter-definition name="endRange" direction="IN" type="INTEGER"/>
|
||||
<int-jdbc:parameter name="beginRange" value="1" type="java.lang.Integer"/>
|
||||
<int-jdbc:parameter name="endRange" value="10" 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 id="defaultPoller" default="true" fixed-rate="5000"/>
|
||||
|
||||
<int:channel id="outputChannel"/>
|
||||
|
||||
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
|
||||
|
||||
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapterWithNamespaceIntegrationTests$Consumer"/>
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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 org.apache.log4j.Logger;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class StoredProcPollingChannelAdapterWithNamespaceIntegrationTests {
|
||||
|
||||
private static Logger logger = Logger.getLogger(StoredProcPollingChannelAdapterWithNamespaceIntegrationTests.class);
|
||||
|
||||
@Autowired
|
||||
private AbstractApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Consumer consumer;
|
||||
|
||||
@Test
|
||||
public void pollH2DatabaseUsingStoredProcedureCall() throws Exception {
|
||||
List<Message<?>> received = new ArrayList<Message<?>>();
|
||||
|
||||
received.add(consumer.poll(60000));
|
||||
|
||||
Message<?> message = received.get(0);
|
||||
context.stop();
|
||||
assertNotNull(message);
|
||||
assertNotNull(message.getPayload());
|
||||
assertNotNull(message.getPayload() instanceof Collection<?>);
|
||||
|
||||
List<Integer> primeNumbers = (List<Integer>) message.getPayload();
|
||||
|
||||
assertTrue(primeNumbers.size() == 4);
|
||||
|
||||
assertTrue(Integer.valueOf(2).equals(primeNumbers.get(0)));
|
||||
assertTrue(Integer.valueOf(3).equals(primeNumbers.get(1)));
|
||||
assertTrue(Integer.valueOf(5).equals(primeNumbers.get(2)));
|
||||
assertTrue(Integer.valueOf(7).equals(primeNumbers.get(3)));
|
||||
|
||||
}
|
||||
|
||||
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<?>> messages = new LinkedBlockingQueue<Message<?>>();
|
||||
|
||||
@ServiceActivator
|
||||
public void receive(Message<?>message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
Message<?> poll(long timeoutInMillis) throws InterruptedException {
|
||||
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?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-2.1.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">
|
||||
|
||||
<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"/>
|
||||
|
||||
<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="rowMapper" class="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
|
||||
|
||||
<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:channel id="outputChannel"/>
|
||||
<!-- <int:channel id="errorChannel" /> -->
|
||||
|
||||
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
|
||||
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcPollingChannelAdapterWithSpringContextIntegrationTests$Consumer"/>
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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 javax.sql.DataSource;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class StoredProcPollingChannelAdapterWithSpringContextIntegrationTests {
|
||||
|
||||
private static Logger logger = Logger.getLogger(StoredProcPollingChannelAdapterWithSpringContextIntegrationTests.class);
|
||||
|
||||
@Autowired
|
||||
private DataSource datasource;
|
||||
|
||||
@Autowired
|
||||
private AbstractApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Consumer consumer;
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
List<Message<?>> received = new ArrayList<Message<?>>();
|
||||
|
||||
received.add(consumer.poll(2000));
|
||||
|
||||
Message<?> message = received.get(0);
|
||||
context.stop();
|
||||
assertNotNull(message);
|
||||
assertNotNull(message.getPayload());
|
||||
assertNotNull(message.getPayload() instanceof Collection<?>);
|
||||
|
||||
Collection<Integer> primeNumbers = (Collection<Integer>) message.getPayload();
|
||||
|
||||
assertTrue(primeNumbers.size() == 4);
|
||||
|
||||
}
|
||||
|
||||
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<?>> messages = new LinkedBlockingQueue<Message<?>>();
|
||||
|
||||
@ServiceActivator
|
||||
public void receive(Message<?>message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
Message<?> poll(long timeoutInMillis) throws InterruptedException {
|
||||
return messages.poll(timeoutInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -30,10 +33,6 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Mark Fisher
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.io.OutputStream;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.serializer.DefaultDeserializer;
|
||||
import org.springframework.core.serializer.DefaultSerializer;
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
*/
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -31,11 +35,6 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Oleg Zhurakousky
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -38,11 +43,6 @@ import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
// Not transactional because the poller threads need access to the data
|
||||
// @Transactional
|
||||
public class JdbcPollingChannelAdapterParserTests {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.hsqldb.Types;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JdbcTypesEnumTests {
|
||||
|
||||
@Test
|
||||
public void testGetCode() {
|
||||
|
||||
JdbcTypesEnum jdbcTypesEnum = JdbcTypesEnum.convertToJdbcTypesEnum("VARCHAR");
|
||||
assertNotNull("Expected not null jdbcTypesEnum.", jdbcTypesEnum);
|
||||
assertEquals(Integer.valueOf(Types.VARCHAR), Integer.valueOf(jdbcTypesEnum.getCode()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToJdbcTypesEnumWithInvalidParameter() {
|
||||
|
||||
JdbcTypesEnum jdbcTypesEnum = JdbcTypesEnum.convertToJdbcTypesEnum("KENNY4JDBC");
|
||||
assertNull("Expected null return value.", jdbcTypesEnum);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToJdbcTypesEnumWithNullParameter() {
|
||||
|
||||
try {
|
||||
JdbcTypesEnum.convertToJdbcTypesEnum(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Parameter sqlTypeAsString, must not be null nor empty", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected Exception");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToJdbcTypesEnumWithEmptyParameter() {
|
||||
|
||||
try {
|
||||
JdbcTypesEnum.convertToJdbcTypesEnum(" ");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Parameter sqlTypeAsString, must not be null nor empty", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected Exception");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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 static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcMessageHandlerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedurepParametersAreSet() 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 procedureParameters = executorAccessor.getPropertyValue("procedureParameters");
|
||||
assertNotNull(procedureParameters);
|
||||
assertTrue(procedureParameters instanceof List);
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
Object executor = accessor.getPropertyValue("executor");
|
||||
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.jdbc.storedproc.PrimeMapper;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlInOutParameter;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcOutboundGatewayParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
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 testProcedurepParametersAreSet() 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);
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.jdbc.storedproc.PrimeMapper;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlInOutParameter;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcPollingChannelAdapterParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
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 testProcedurepParametersAreSet() 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);
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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:message-store id="messageStore" data-source="dataSource"/>
|
||||
|
||||
<int-jdbc:stored-proc-outbound-channel-adapter id="storedProcedureOutboundChannelAdapter"
|
||||
data-source="dataSource" channel="target"
|
||||
stored-procedure-name="testProcedure1">
|
||||
<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:stored-proc-outbound-channel-adapter>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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="requestChannel"/>
|
||||
<int:channel id="replyChannel"/>
|
||||
|
||||
<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"
|
||||
order="2"
|
||||
reply-channel="replyChannel"
|
||||
request-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:stored-proc-outbound-gateway>
|
||||
|
||||
<int:poller default="true" fixed-rate="10000"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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-2.1.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"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.springframework.integration.jdbc.storedproc;
|
||||
|
||||
public interface CreateUser {
|
||||
void createUser(User user);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.storedproc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
public class PrimeMapper implements RowMapper<Integer> {
|
||||
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
return rs.getInt("PRIME");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.storedproc;
|
||||
|
||||
public class User {
|
||||
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 String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return this.email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.storedproc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.springframework.integration.jdbc.storedproc.derby;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
*/
|
||||
public final class DerbyFunctions {
|
||||
|
||||
public static String convertStringToUpperCase( String invalue ) {
|
||||
return invalue.toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.springframework.integration.jdbc.storedproc.derby;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
*/
|
||||
public final class DerbyStoredProcedures {
|
||||
|
||||
public static void createUser(String username, String password, String email)
|
||||
throws SQLException {
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
try {
|
||||
conn = DriverManager.getConnection("jdbc:default:connection");
|
||||
String sql = "INSERT INTO USERS "
|
||||
+ "(USERNAME, PASSWORD, EMAIL) VALUES (?,?,?)";
|
||||
stmt = conn.prepareStatement(sql);
|
||||
stmt.setString(1, username);
|
||||
stmt.setString(2, password);
|
||||
stmt.setString(3, email);
|
||||
stmt.executeUpdate();
|
||||
} finally {
|
||||
JdbcUtils.closeStatement(stmt);
|
||||
JdbcUtils.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createUserAndReturnAll(String username, String password,
|
||||
String email, ResultSet[] returnedData) throws SQLException {
|
||||
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatement stmt2 = null;
|
||||
try {
|
||||
conn = DriverManager.getConnection("jdbc:default:connection");
|
||||
String sql = "INSERT INTO USERS "
|
||||
+ "(USERNAME, PASSWORD, EMAIL) VALUES (?,?,?)";
|
||||
stmt = conn.prepareStatement(sql);
|
||||
stmt.setString(1, username);
|
||||
stmt.setString(2, password);
|
||||
stmt.setString(3, email);
|
||||
stmt.executeUpdate();
|
||||
|
||||
stmt2 = conn.prepareStatement("select * from USERS");
|
||||
returnedData[0] = stmt2.executeQuery();
|
||||
|
||||
} finally {
|
||||
JdbcUtils.closeConnection(conn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.integration.jdbc.storedproc.h2;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.h2.tools.SimpleResultSet;
|
||||
import org.hsqldb.Types;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
*/
|
||||
public final class H2StoredProcedures {
|
||||
|
||||
public static ResultSet getPrimes(int beginRange, int endRange) throws SQLException {
|
||||
|
||||
SimpleResultSet rs = new SimpleResultSet();
|
||||
rs.addColumn("PRIME", Types.INTEGER, 10, 0);
|
||||
|
||||
for (int i = beginRange; i <= endRange; i++) {
|
||||
|
||||
if (new BigInteger(String.valueOf(i)).isProbablePrime(100)) {
|
||||
rs.addRow(i);
|
||||
}
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
public static Integer random() {
|
||||
return 1 + (int)(Math.random() * 100);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Use Log4j
|
||||
priority=1
|
||||
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
|
||||
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
|
||||
|
||||
# Configuration file of the log
|
||||
#log4j.configuration=file:log4j-rabbit-stocks.properties
|
||||
@@ -0,0 +1,4 @@
|
||||
CREATE FUNCTION CONVERT_STRING_TO_UPPER_CASE (invalue VARCHAR(50)) RETURNS VARCHAR(50) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyFunctions.convertStringToUpperCase';
|
||||
create table USERS(USERNAME varchar(100),PASSWORD varchar(100), EMAIL varchar(100));
|
||||
CREATE PROCEDURE CREATE_USER( IN username VARCHAR(100), IN password VARCHAR(100), IN email VARCHAR(100) ) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.createUser';
|
||||
CREATE PROCEDURE CREATE_USER_RETURN_ALL(IN username VARCHAR(100), IN password VARCHAR(100), IN email VARCHAR(100)) PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.createUserAndReturnAll';
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE ALIAS IF NOT EXISTS GET_PRIME_NUMBERS FOR "org.springframework.integration.jdbc.storedproc.h2.H2StoredProcedures.getPrimes"
|
||||
CREATE ALIAS IF NOT EXISTS GET_RANDOM_NUMBER FOR "org.springframework.integration.jdbc.storedproc.h2.H2StoredProcedures.random"
|
||||
@@ -0,0 +1,8 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
|
||||
|
||||
log4j.category.org.springframework.integration=INFO
|
||||
log4j.category.org.apache.derby=INFO
|
||||
Reference in New Issue
Block a user