You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by "Olivier Roger (JIRA)" <ji...@apache.org> on 2011/01/05 18:24:45 UTC

[jira] Created: (CAMEL-3502) JDBC Persistent Aggregator

JDBC Persistent Aggregator
--------------------------

                 Key: CAMEL-3502
                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
             Project: Camel
          Issue Type: New Feature
    Affects Versions: 2.6.0
         Environment: JDBC Aggregator Database
            Reporter: Olivier Roger


The patch provided is an implementation of a Aggregator for JDBC.

It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.

The implementation is very similar to the one for HawtDB. 
Unit tests have been included and use the H2 in-memory database.

About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 

Here is a small documentation

{quote}
h2. Database

To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.

The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
However one difference should be remembered: the *id* field does not have the same content depending on the table.
In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.

Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
{code}
CREATE TABLE aggregation (
    id varchar(255) NOT NULL,
    exchange blob NOT NULL,
    constraint aggregation_pk PRIMARY KEY (id)
);
CREATE TABLE aggregation_completed (
    id varchar(255) NOT NULL,
    exchange blob NOT NULL,
    constraint aggregation_completed_pk PRIMARY KEY (id)
);
{code}

h3. Codec (Serialization)

Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.

The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
This allows the exchange body and headers to have custom types object references.

h2. Transactional 

TransactionTemplate is use to wrap all the calls to the database.
Therefore a Transaction Manager is required (see bean-declaration)

h2. Service (Start/Stop)

The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
The _start()_ method verify the connection of the database and the presence of the required tables.

h2. Aggregator configuration

Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.

Here is the declaration for Oracle :

{code}
    <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
        <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
    </bean>

    <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>

    <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
        <constructor-arg name="transactionManager" ref="transactionManager"/>
        <constructor-arg name="repositoryName" value="aggregation"/>
        <constructor-arg name="dataSource" ref="dataSource"/>
        <!-- Only with Oracle, else use default -->
        <property name="lobHandler" ref="lobHandler"/>
    </bean>
{code}

h2. Feature

A feature has been created : *camel-jdbc-aggregator*.

{quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12980032#action_12980032 ] 

Olivier Roger commented on CAMEL-3502:
--------------------------------------

About the documentation,

I created a user on Camel Confluence instance: 

{quote}
Full Name: Olivier Roger
Email: olivier.roger@bsb.com 
{quote}

I might not have a full documentation ready for Camel 2.6 release but I can still improve it later.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator-setter-injection.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Closed: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Olivier Roger closed CAMEL-3502.
--------------------------------

    Resolution: Fixed

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator-setter-injection.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen updated CAMEL-3502:
-------------------------------

    Fix Version/s: 2.7.0

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>             Fix For: 2.7.0
>
>         Attachments: jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978227#action_12978227 ] 

Claus Ibsen commented on CAMEL-3502:
------------------------------------

Oliver we should improve the {{JdbcAggregationRepository}} to have a default constructor so you dont have to do the ugly constructor-arg stuff in spring xml file.
If we have getter/setters then tooling can better assist you as they have auto completion in spring XML files.

And we can check that all options has been set in the doStart method, this is the Camel idiom.

We can revisit this when the patch has been commited to trunk.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Olivier Roger updated CAMEL-3502:
---------------------------------

    Attachment: jdbc-aggregator-setter-injection.patch

Attached the patch to replace constructor arguments by properties.


> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator-setter-injection.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978214#action_12978214 ] 

Olivier Roger commented on CAMEL-3502:
--------------------------------------

I just registered for a new user account. I don't have access at the moment.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Olivier Roger updated CAMEL-3502:
---------------------------------

    Attachment: jdbc-aggregator.patch
                jdbc-aggregator-other-changes.patch
                camel-jdbc-aggregator.zip

I attached the differents requested files:

* *jdbc-aggregator.patch* is a corrected version of the patch without uppercase
* *camel-jdbc-aggregator.zip* is the component directory archive
* *jdbc-aggregator-other-changes.patch* for all the other changes

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>             Fix For: 2.7.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978239#action_12978239 ] 

Claus Ibsen commented on CAMEL-3502:
------------------------------------

Thanks Oliver for donating this great work. I have committed it to trunk: 1055799.

I added missing licenses and fixed checkstyle
http://camel.apache.org/building.html

Oliver would be nice if you could work on the properties for the options and provide a patch for that.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978197#action_12978197 ] 

Claus Ibsen commented on CAMEL-3502:
------------------------------------

Oh can you please change the package name to *not* use any upper case letters.

org.apache.camel.component.jdbc.aggregationRepository
-->
org.apache.camel.component.jdbc.aggregationrepository


> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>             Fix For: 2.7.0
>
>         Attachments: jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978307#action_12978307 ] 

Claus Ibsen commented on CAMEL-3502:
------------------------------------

trunk: 1055860.

Thanks Oliver.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator-setter-injection.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978233#action_12978233 ] 

Olivier Roger commented on CAMEL-3502:
--------------------------------------

Sure !

Having properties instead of constructor arguments would be nice.

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen updated CAMEL-3502:
-------------------------------

    Fix Version/s:     (was: 2.7.0)
                   2.6.0

Thanks Oliver that was fast. So lets try to get it included in Camel 2.6.

Do you have access to edit the wiki pages? In case you want to add documentation and in general help improve the documentation?

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.6.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978196#action_12978196 ] 

Claus Ibsen commented on CAMEL-3502:
------------------------------------

Oliver this is great. 

Do you mind attaching a ZIP file with the {{camel-jdbc-aggregator}} directory?
And maybe attach a smaller patch for the changes requires (excluding the stuff in the camel-jdbc-aggregator directory).


> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>         Attachments: jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Olivier Roger (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Olivier Roger updated CAMEL-3502:
---------------------------------

    Attachment: jdbc-aggregator.patch

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>         Attachments: jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (CAMEL-3502) JDBC Persistent Aggregator

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-3502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen reassigned CAMEL-3502:
----------------------------------

    Assignee: Claus Ibsen

> JDBC Persistent Aggregator
> --------------------------
>
>                 Key: CAMEL-3502
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3502
>             Project: Camel
>          Issue Type: New Feature
>    Affects Versions: 2.6.0
>         Environment: JDBC Aggregator Database
>            Reporter: Olivier Roger
>            Assignee: Claus Ibsen
>             Fix For: 2.7.0
>
>         Attachments: camel-jdbc-aggregator.zip, jdbc-aggregator-other-changes.patch, jdbc-aggregator.patch, jdbc-aggregator.patch
>
>
> The patch provided is an implementation of a Aggregator for JDBC.
> It implements *org.apache.camel.spi.AggregationRepository* (2.4+) and has been tested on Camel 2.4 and 2.6.
> Some details have been disscussed on the [mailling list|http://camel.465427.n5.nabble.com/Aggregator-Persistence-td2800301.html] with Claus.
> The implementation is very similar to the one for HawtDB. 
> Unit tests have been included and use the H2 in-memory database.
> About that, the Test *JdbcAggregateLoadAndRecoverTest* has been adapted to exclude the redeliveries from the failling messages. It is possible for a message to be sent due to a _scan()_ background operation evn before it is send by the _onCompletion()_ method ? 
> Here is a small documentation
> {quote}
> h2. Database
> To be operational, each aggregator uses two table: the aggregation and completed one. By convention the completed has the same name as the aggregation one suffixed with "_COMPLETED". The name must be configured in the Spring bean with the _RepositoryName_ property. In the following example aggregation will be used.
> The table structure definition of both table are identical: in both case a String value is used as key (*id*) whereas a Blob contains the exchange serialized in byte array.
> However one difference should be remembered: the *id* field does not have the same content depending on the table.
> In the aggregation table *id* holds the correlation Id used by the component to aggregate the messages. In the completed table, *id* holds the id of the exchange stored in corresponding the blob field.
> Here is the SQL query used to create the tables, just replace "aggregation" with your aggregator repository name.
> {code}
> CREATE TABLE aggregation (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_pk PRIMARY KEY (id)
> );
> CREATE TABLE aggregation_completed (
>     id varchar(255) NOT NULL,
>     exchange blob NOT NULL,
>     constraint aggregation_completed_pk PRIMARY KEY (id)
> );
> {code}
> h3. Codec (Serialization)
> Since they can contain any type of payload, Exchanges are not serializable by design. It is converted into a byte array to be stored in a database BLOB field.
> All those conversions are handled by the *JdbcCodec* class. One detail of the code requires your attention: the *ClassLoadingAwareObjectInputStream*.
> The *ClassLoadingAwareObjectInputStream* has been reused from the ActiveMQ project. It wraps an *ObjectInputStream* and use it with the ContextClassLoader rather than the currentThread one. The benefit is to be able to load classes exposed by other bundles.
> This allows the exchange body and headers to have custom types object references.
> h2. Transactional 
> TransactionTemplate is use to wrap all the calls to the database.
> Therefore a Transaction Manager is required (see bean-declaration)
> h2. Service (Start/Stop)
> The *JdbcAggregationRepository* extends ServiceSupport. This includes the components in Camel component life cycle. 
> The _start()_ method verify the connection of the database and the presence of the required tables.
> h2. Aggregator configuration
> Depending on the targeted environment, the aggregator might need some configuration. As you already know, each aggregator should have its own repository (with the corresponding pair of table created in the database) and a data source. If the default lobHandler is not adapted to your database system, it can be injected with the _lobHandler_ property.
> Here is the declaration for Oracle :
> {code}
>     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
>         <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
>     </bean>
>     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
>     <bean id="repo" class="org.apache.camel.component.jdbc.aggregationRepository.JdbcAggregationRepository">
>         <constructor-arg name="transactionManager" ref="transactionManager"/>
>         <constructor-arg name="repositoryName" value="aggregation"/>
>         <constructor-arg name="dataSource" ref="dataSource"/>
>         <!-- Only with Oracle, else use default -->
>         <property name="lobHandler" ref="lobHandler"/>
>     </bean>
> {code}
> h2. Feature
> A feature has been created : *camel-jdbc-aggregator*.
> {quote}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.