You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2009/03/10 21:50:54 UTC

svn commit: r752258 [1/2] - in /servicemix/smx4/nmr/trunk: ./ assembly/ assembly/src/main/filtered-resources/ nmr/ nmr/audit/ nmr/audit/src/ nmr/audit/src/main/ nmr/audit/src/main/java/ nmr/audit/src/main/java/org/ nmr/audit/src/main/java/org/apache/ n...

Author: gnodet
Date: Tue Mar 10 20:50:52 2009
New Revision: 752258

URL: http://svn.apache.org/viewvc?rev=752258&view=rev
Log:
SMX4NMR-22: more tests / docs needed, but the file auditor is working

Added:
    servicemix/smx4/nmr/trunk/nmr/audit/
    servicemix/smx4/nmr/trunk/nmr/audit/pom.xml
    servicemix/smx4/nmr/trunk/nmr/audit/src/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/jbi/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/jbi/audit/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/jbi/audit/file/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/jbi/audit/jdbc/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/jbi/audit/lucene/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AbstractAuditor.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorException.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorMBean.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorQueryMBean.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditor.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditorStrategy.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditor.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/package.html
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/DefaultLuceneCallback.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneAuditor.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneCallback.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneIndexer.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/package.html
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/package.html
    servicemix/smx4/nmr/trunk/nmr/audit/src/main/resources/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/jbi/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/jbi/audit/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/jbi/audit/file/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/jbi/audit/jdbc/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/AbstractAuditorTest.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/FileAuditorTest.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditorTest.java
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j-tests.properties
    servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j.properties
Modified:
    servicemix/smx4/nmr/trunk/assembly/pom.xml
    servicemix/smx4/nmr/trunk/assembly/src/main/filtered-resources/features.xml
    servicemix/smx4/nmr/trunk/nmr/pom.xml
    servicemix/smx4/nmr/trunk/pom.xml

Modified: servicemix/smx4/nmr/trunk/assembly/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/assembly/pom.xml?rev=752258&r1=752257&r2=752258&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/assembly/pom.xml (original)
+++ servicemix/smx4/nmr/trunk/assembly/pom.xml Tue Mar 10 20:50:52 2009
@@ -236,6 +236,8 @@
                                 <descriptor>file:${basedir}/target/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
+                                <feature>nmr</feature>
+                                <feature>nmr-audit</feature>
                                 <feature>jbi</feature>
                             </features>
                             <repository>target/features-repo</repository>

Modified: servicemix/smx4/nmr/trunk/assembly/src/main/filtered-resources/features.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/assembly/src/main/filtered-resources/features.xml?rev=752258&r1=752257&r2=752258&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/assembly/src/main/filtered-resources/features.xml (original)
+++ servicemix/smx4/nmr/trunk/assembly/src/main/filtered-resources/features.xml Tue Mar 10 20:50:52 2009
@@ -38,6 +38,11 @@
         <bundle>mvn:org.apache.servicemix.nmr/org.apache.servicemix.nmr.commands/${pom.version}</bundle>
         <bundle>mvn:org.apache.servicemix.nmr/org.apache.servicemix.nmr.management/${pom.version}</bundle>
     </feature>
+    <feature name="nmr-audit" version="${version}">
+        <feature version="${version}">nmr</feature>
+        <bundle>mvn:org.apache.servicemix/servicemix-utils/${servicemix.utils.version}</bundle>
+        <bundle>mvn:org.apache.servicemix.nmr/org.apache.servicemix.nmr.audit/${pom.version}</bundle>
+    </feature>
     <feature name="jbi" version="${version}">
         <feature version="${version}">naming</feature>
         <feature version="${version}">transaction</feature>

Added: servicemix/smx4/nmr/trunk/nmr/audit/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/pom.xml?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/pom.xml (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/pom.xml Tue Mar 10 20:50:52 2009
@@ -0,0 +1,87 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <!--
+
+        Licensed to the Apache Software Foundation (ASF) under one or more
+        contributor license agreements.  See the NOTICE file distributed with
+        this work for additional information regarding copyright ownership.
+        The ASF licenses this file to You 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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.servicemix.nmr</groupId>
+        <artifactId>nmr</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.servicemix.nmr</groupId>
+    <artifactId>org.apache.servicemix.nmr.audit</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache ServiceMix NMR Audit</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.servicemix</groupId>
+            <artifactId>servicemix-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.nmr</groupId>
+            <artifactId>org.apache.servicemix.nmr.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.kernel</groupId>
+            <artifactId>org.apache.servicemix.kernel.main</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-core</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+  
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Import-Package>
+                            org.apache.lucene*;resolution:=optional,
+                            *
+                        </Import-Package>
+                        <Export-Package>${pom.artifactId}*;version=${pom.version}</Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AbstractAuditor.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AbstractAuditor.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AbstractAuditor.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AbstractAuditor.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.api.event.ExchangeListener;
+
+/**
+ * Base class for ServiceMix auditors implementations.
+ * 
+ * @author Guillaume Nodet (gnt)
+ * @since 1.0.0
+ * @version $Revision: 550578 $
+ */
+public abstract class AbstractAuditor implements AuditorMBean, ExchangeListener {
+
+    protected final Log log = LogFactory.getLog(getClass());
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeCount()
+     */
+    public abstract int getExchangeCount() throws AuditorException;
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeId(int)
+     */
+    public String getExchangeIdByIndex(int index) throws AuditorException {
+        if (index < 0) {
+            throw new IllegalArgumentException("index should be greater or equal to zero");
+        }
+        return getExchangeIdsByRange(index, index + 1)[0];
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeIds()
+     */
+    public String[] getAllExchangeIds() throws AuditorException {
+        return getExchangeIdsByRange(0, getExchangeCount());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeIds(int, int)
+     */
+    public abstract String[] getExchangeIdsByRange(int fromIndex, int toIndex)  throws AuditorException;
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchange(int)
+     */
+    public Exchange getExchangeByIndex(int index) throws AuditorException {
+        if (index < 0) {
+            throw new IllegalArgumentException("index should be greater or equal to zero");
+        }
+        return getExchangesByRange(index, index + 1)[0];
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchange(java.lang.String)
+     */
+    public Exchange getExchangeById(String id) throws AuditorException {
+        if (id == null || id.length() == 0) {
+            throw new IllegalArgumentException("id should be non null and non empty");
+        }
+        return getExchangesByIds(new String[] {id })[0];
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchanges()
+     */
+    public Exchange[] getAllExchanges() throws AuditorException {
+        return getExchangesByRange(0, getExchangeCount());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchanges(int, int)
+     */
+    public Exchange[] getExchangesByRange(int fromIndex, int toIndex) throws AuditorException {
+        return getExchangesByIds(getExchangeIdsByRange(fromIndex, toIndex));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchanges(java.lang.String[])
+     */
+    public abstract Exchange[] getExchangesByIds(String[] ids) throws AuditorException;
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchanges()
+     */
+    public int deleteAllExchanges() throws AuditorException {
+        return deleteExchangesByRange(0, getExchangeCount());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchange(int)
+     */
+    public boolean deleteExchangeByIndex(int index) throws AuditorException {
+        if (index < 0) {
+            throw new IllegalArgumentException("index should be greater or equal to zero");
+        }
+        return deleteExchangesByRange(index, index + 1) == 1;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchange(java.lang.String)
+     */
+    public boolean deleteExchangeById(String id) throws AuditorException {
+        return deleteExchangesByIds(new String[] {id }) == 1;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchanges(int, int)
+     */
+    public int deleteExchangesByRange(int fromIndex, int toIndex) throws AuditorException {
+        return deleteExchangesByIds(getExchangeIdsByRange(fromIndex, toIndex));
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchanges(java.lang.String[])
+     */
+    public abstract int deleteExchangesByIds(String[] ids) throws AuditorException;
+    
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#resendExchange(javax.jbi.messaging.MessageExchange)
+     */
+    public void resendExchange(Exchange exchange) throws AuditorException {
+        // TODO
+        //container.resendExchange(exchange);
+    }
+
+    public void exchangeDelivered(Exchange exchange) {
+    }
+
+    public void exchangeFailed(Exchange exchange) {
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorException.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorException.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorException.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorException.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit;
+
+import org.apache.servicemix.nmr.api.ServiceMixException;
+
+/**
+ * AuditorException is the exception that can be thrown by the {@link AuditorMBean}
+ * when an error occurs accessing the data store when performing an operation.
+ * 
+ * @author Guillaume Nodet (gnt)
+ * @since 1.0.0
+ * @version $Revision: 426415 $
+ */
+public class AuditorException extends ServiceMixException {
+
+    /** Serial Version UID */
+    private static final long serialVersionUID = -1259059806617598480L;
+
+    /**
+     * Constructs a new AuditorException with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * @param   aMessage   the detail message. The detail message is saved for 
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public AuditorException(String aMessage) {
+        super(aMessage);
+    }
+
+    /**
+     * Constructs a new AuditorException with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * <code>cause</code> is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  aMessage the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  aCause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     */
+    public AuditorException(String aMessage, Throwable aCause) {
+        super(aMessage, aCause);
+    }
+
+    /**
+     * Constructs a new AuditorException with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  aCause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     */
+    public AuditorException(Throwable aCause) {
+        super(aCause);
+    }
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorMBean.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorMBean.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorMBean.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorMBean.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit;
+
+import org.apache.servicemix.nmr.api.Exchange;
+
+/**
+ * Main interface for ServiceMix auditor.
+ * This interface may be used to view and delete exchanges
+ * or to re-send an exchange on behalf of the component that
+ * initiated the exchange. 
+ * 
+ * The implementation is free to offer additional features for
+ * selecting message exchanges which are dependant of the underlying
+ * store.
+ * 
+ * @author Guillaume Nodet (gnt)
+ * @since 1.0.0
+ * @version $Revision: 492738 $
+ */
+public interface AuditorMBean {
+
+    /**
+     * Get the number of exchanges stored by this auditor.
+     * 
+     * @return the number of exchanges stored 
+     * @throws AuditorException if an error occurs accessing the data store.
+     */
+    int getExchangeCount() throws AuditorException;
+    
+    /**
+     * Retrieve the exchange id of the exchange at the specified index.
+     * Index must be a null or positive integer.
+     * If index is greater than the number of exchanges stored,
+     * a null string should be returned.
+     * 
+     * @param index the index of the exchange
+     * @return the exchange id, or null of index is greater than the exchange count
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if index is less than zero
+     */
+    String getExchangeIdByIndex(int index) throws AuditorException;
+    
+    /**
+     * Retrieve all exchanges ids from the data store.
+     * 
+     * @return an array of exchange ids
+     * @throws AuditorException if an error occurs accessing the data store.
+     */
+    String[] getAllExchangeIds() throws AuditorException;
+    
+    /**
+     * Retrieve a range of message exchange ids.
+     * The ids retrieved range from fromIndex (inclusive) to
+     * toIndex (exclusive).
+     * If fromIndex == toIndex, an empty array must be returned.
+     * If fromIndex is less than zero, or if toIndex is less than
+     * fromIndex, an exception will be thrown.
+     * An array of exactly (toIndex - fromIndex) element should be
+     * returned.
+     * This array must be filled by null, for indexes that are greater
+     * than the number of exchanges stored.
+     * 
+     * @param fromIndex the lower bound index of the ids to be retrieved.
+     *                  fromIndex must be greater or equal to zero.
+     * @param toIndex the upper bound (exclusive) of the ids to be retrieved.
+     *                toIndex must be greater or equal to fromIndex
+     * @return an array of exchange ids
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if fromIndex is less than zero or if toIndex is 
+     *                                  less than fromIndex.
+     */
+    String[] getExchangeIdsByRange(int fromIndex, int toIndex)  throws AuditorException;
+    
+    /**
+     * Retrieve the exchange at the specified index.
+     * Index must be a null or positive integer, and should be less than
+     * the current exchange count stored. 
+     * If index is greater than the number of exchanges stored,
+     * a null exchange should be returned.
+     * 
+     * @param index the index of the exchange
+     * @return the exchange, or null of index is greater than the exchange count
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if index is less than zero
+     */
+    Exchange getExchangeByIndex(int index) throws AuditorException;
+    
+    /**
+     * Retrieve the exchange for a specified id.
+     * Id must be non null and non empty. 
+     * If the exchange with the specified id is not found, null should be returned.
+     * 
+     * @param id the id of the exchange
+     * @return the exchange with the specified id, or null if not found
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if id is null or empty 
+     */
+    Exchange getExchangeById(String id) throws AuditorException;
+    
+    /**
+     * Retrieve all exchanges =from the data store.
+     * 
+     * @return an array of exchange
+     * @throws AuditorException if an error occurs accessing the data store.
+     */
+    Exchange[] getAllExchanges() throws AuditorException;
+    
+    /**
+     * Retrieve a range of message exchange.
+     * The exchanges retrieved range from fromIndex (inclusive) to
+     * toIndex (exclusive).
+     * If fromIndex == toIndex, an empty array must be returned.
+     * If fromIndex is less than zero, or if toIndex is less than
+     * fromIndex, an exception will be thrown.
+     * An array of exactly (toIndex - fromIndex) element should be
+     * returned.
+     * This array must be filled by null, for indexes that are greater
+     * than the number of exchanges stored.
+     * 
+     * @param fromIndex the lower bound index of the exchanges to be retrieved.
+     *                  fromIndex must be greater or equal to zero.
+     * @param toIndex the upper bound (exclusive) of the exchanges to be retrieved.
+     *                toIndex must be greater or equal to fromIndex
+     * @return an array of exchange
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if fromIndex is less than zero or if toIndex is 
+     *                                  less than fromIndex.
+     */
+    Exchange[] getExchangesByRange(int fromIndex, int toIndex) throws AuditorException;
+
+    /**
+     * Retrieve exchanges for the specified ids.
+     * An array of exactly ids.length elements must be returned.
+     * This array should be filled with null for exchanges that
+     * have not been found in the store. 
+     * 
+     * @param ids the ids of exchanges to retrieve
+     * @return an array of exchanges
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if ids is null, or one of its
+     *         element is null or empty.
+     */
+    Exchange[] getExchangesByIds(String[] ids) throws AuditorException;
+    
+    /**
+     * Delete all exchanges =from the data store.
+     * 
+     * @return the number of exchanges deleted, or -1 if such information
+     *         can not be provided
+     * @throws AuditorException if an error occurs accessing the data store.
+     */
+    int deleteAllExchanges() throws AuditorException;
+    
+    /**
+     * Delete a message, given its index.
+     * Index must be a null or positive integer, and should be less than
+     * the current exchange count stored. 
+     * If index is greater than the number of exchanges stored,
+     * false should be returned.
+     * 
+     * @param index the index of the exchange
+     * @return true if the exchange has been successfully deleted,
+     *         false if index is greater than the number of exchanges stored
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if index is less than zero
+     */
+    boolean deleteExchangeByIndex(int index) throws AuditorException;
+    
+    /**
+     * Delete the exchange with the specified id.
+     * Id must be non null and non empty.
+     * 
+     * @param id the id of the exchange to delete
+     * @return true if the exchange has been successfully deleted,
+     *         false if the exchange was not found
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if id is null or empty 
+     */
+    boolean deleteExchangeById(String id) throws AuditorException;
+
+    /**
+     * Delete exchanges ranging from fromIndex to toIndex.
+     * 
+     * @param fromIndex the lower bound index of the exchanges to be retrieved.
+     *                  fromIndex must be greater or equal to zero.
+     * @param toIndex the upper bound (exclusive) of the exchanges to be retrieved.
+     *                toIndex must be greater or equal to fromIndex
+     * @return the number of exchanges deleted
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if fromIndex is less than zero or if toIndex is 
+     *                                  less than fromIndex.
+     */
+    int deleteExchangesByRange(int fromIndex, int toIndex) throws AuditorException;
+
+    /**
+     * Delete exchanges given their ids.
+     * 
+     * @param ids the ids of exchanges to retrieve
+     * @return the number of exchanges deleted
+     * @throws AuditorException if an error occurs accessing the data store.
+     * @throws IllegalArgumentException if ids is null, or one of its
+     *         element is null or empty.
+     */
+    int deleteExchangesByIds(String[] ids) throws AuditorException;
+
+    /**
+     * Resend an exchange on behalf of the consumer component that initiated this exchange.
+     * The exchange must have been retrieved from this auditor, else the behavior
+     * is undefined.
+     * The exchange will be given a new id and will be reset to its original state:
+     * the out and fault messages will be removed (if they exist), the error will be
+     * set to null, state to ACTIVE.
+     * The consumer component must be prepared
+     * to receive a response or a DONE status to an exchange it did not 
+     * have directly initiated.
+     * 
+     * @param exchange the exchange to be sent
+     * @throws AuditorException if an error occurs re-sending the exchange
+     */
+    void resendExchange(Exchange exchange) throws AuditorException;
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorQueryMBean.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorQueryMBean.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorQueryMBean.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/AuditorQueryMBean.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit;
+
+import org.apache.servicemix.nmr.api.Status;
+
+/**
+ * Main interface for ServiceMix auditor query.
+ * This interface may be used to query upon exchanges.
+ * 
+ * @author George Gastaldi (gastaldi)
+ * @since 1.0.0
+ * @version $Revision: 550578 $
+ */
+public interface AuditorQueryMBean extends AuditorMBean {
+
+    String[] findExchangesIDsByStatus(Status status) throws AuditorException;
+
+    String[] findExchangesIDsByMessageContent(String type, String content) throws AuditorException;
+
+    String[] findExchangesIDsByMessageProperty(String type, String property, String value) throws AuditorException;
+
+    /**
+     * Searches for Exchanges IDs using the supplied key-field and the expected content of the field 
+     * @param field
+     * @param fieldValue
+     * @return exchange ids
+     * @throws AuditorException if an error occurs
+     */
+    String[] getExchangeIds(String field, String fieldValue) throws AuditorException;
+}
\ No newline at end of file

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditor.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditor.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditor.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditor.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.file;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.api.Status;
+import org.apache.servicemix.nmr.audit.AbstractAuditor;
+import org.apache.servicemix.nmr.audit.AuditorException;
+import org.apache.servicemix.util.FileUtil;
+
+/**
+ * Simple implementation of a ServiceMix auditor that stores messages in files in a directory.
+ *
+ * Currently, the file auditor will only store the message body for ACTIVE exchanges.
+ * 
+ * @org.apache.xbean.XBean element="fileAuditor" description="The Auditor of message exchanges to a directory"
+ */
+public class FileAuditor extends AbstractAuditor {
+
+    private static final Log LOG = LogFactory.getLog(FileAuditor.class);
+    private File directory;
+    private FileAuditorStrategy strategy = new FileAuditorStrategyImpl();
+
+    /**
+     * The directory used for storing the audited messages
+     * 
+     * @param directory
+     *            the directory
+     */
+    public void setDirectory(File directory) {
+        if (!directory.exists()) {
+            LOG.info("Creating directory " + directory);
+            directory.mkdirs();
+        }
+        this.directory = directory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void exchangeSent(Exchange exchange) {
+        try {
+            if (exchange.getStatus() == Status.Active) {
+                OutputStream os = getOutputStream(exchange);
+                os.write(exchange.display(true).getBytes());
+                os.close();
+            }
+        } catch (Exception e) {
+            LOG.error(String.format("Error occurred while storing message %s", exchange.getId()), e);
+        }
+    }
+
+    /*
+     * Get the outputstream for writing the message content
+     */
+    private OutputStream getOutputStream(Exchange exchange) throws FileNotFoundException {
+        File file = new File(directory, strategy.getFileName(exchange));
+        if (!file.getParentFile().exists()) {
+            file.getParentFile().mkdirs();
+        }
+        return new BufferedOutputStream(new FileOutputStream(file));
+    }
+
+    @Override
+    public int deleteExchangesByIds(String[] ids) throws AuditorException {
+        throw new AuditorException("deleteExchangesById(s) currently unsupported by FileAuditor");
+    }
+
+    @Override
+    public int getExchangeCount() throws AuditorException {
+        return FileUtil.countFilesInDirectory(directory);
+    }
+
+    @Override
+    public String[] getExchangeIdsByRange(int fromIndex, int toIndex) throws AuditorException {
+        throw new AuditorException("getExchangeIdsByRange currently unsupported by FileAuditor");
+    }
+
+    @Override
+    public Exchange[] getExchangesByIds(String[] ids) throws AuditorException {
+        throw new AuditorException("getExchangeByIds currently unsupported by FileAuditor");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getDescription() {
+        return "File-based auditing service";
+    }
+
+    /*
+     * Default FileAuditorStrategy implementation, writing audit files in a folder per day
+     */
+    private class FileAuditorStrategyImpl implements FileAuditorStrategy {
+        
+        private final DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
+        
+        public String getFileName(Exchange exchange) {
+            return dateformat.format(new Date()) + File.separatorChar + exchange.getId().replaceAll("[:\\.]", "_");
+        }
+    }
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditorStrategy.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditorStrategy.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditorStrategy.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/file/FileAuditorStrategy.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.file;
+
+import org.apache.servicemix.nmr.api.Exchange;
+
+/**
+ * Interface that defines the name of the file written by a {@link FileAuditor} 
+ */
+public interface FileAuditorStrategy {
+    
+    /**
+     * Get the file name for writing the given {@link Exchange}
+     */
+    String getFileName(Exchange exchange);
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditor.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditor.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditor.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditor.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+import org.apache.servicemix.jdbc.JDBCAdapter;
+import org.apache.servicemix.jdbc.JDBCAdapterFactory;
+import org.apache.servicemix.jdbc.Statements;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.audit.AbstractAuditor;
+import org.apache.servicemix.nmr.audit.AuditorException;
+import org.springframework.beans.factory.InitializingBean;
+
+/**
+ * Basic implementation of ServiceMix auditor on a jdbc store.
+ * This implementation, for performance purposes, only relies
+ * on one table SM_AUDIT with two columns:
+ * <ul>
+ *   <li><b>ID</b> the exchange id (varchar)</li>
+ *   <li><b>EXCHANGE</b> the serialized exchange (blob)</li>
+ * </ul>
+ *
+ * @org.apache.xbean.XBean element="jdbcAuditor" description="The Auditor of message exchanges to a JDBC database"
+ * 
+ * @author Guillaume Nodet (gnt)
+ * @version $Revision: 550578 $
+ * @since 2.1
+ */
+public class JdbcAuditor extends AbstractAuditor implements InitializingBean {
+
+    private DataSource dataSource;
+    private boolean autoStart = true;
+    private Statements statements;
+    private String tableName = "SM_AUDIT";
+    private JDBCAdapter adapter;
+    private boolean createDataBase = true;
+    
+    public String getDescription() {
+        return "JDBC Auditing Service";
+    }
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.dataSource == null) {
+            throw new IllegalArgumentException("dataSource should not be null");
+        }
+        if (statements == null) {
+            statements = new Statements();
+            statements.setStoreTableName(tableName);
+        }
+        Connection connection = null;
+        boolean restoreAutoCommit = false;
+        try {
+            connection = getDataSource().getConnection();
+            if (connection.getAutoCommit()) {
+                connection.setAutoCommit(false);
+                restoreAutoCommit = true;
+            }
+            adapter = JDBCAdapterFactory.getAdapter(connection);
+            if (statements == null) {
+                statements = new Statements();
+                statements.setStoreTableName(tableName);
+            }
+            adapter.setStatements(statements);
+            if (createDataBase) {
+                adapter.doCreateTables(connection);
+            }
+            connection.commit();
+        } catch (SQLException e) {
+            throw (IOException) new IOException("Exception while creating database").initCause(e); 
+        } finally {
+            close(connection, restoreAutoCommit);
+        }
+    }
+    
+    public void exchangeSent(Exchange exchange) {
+        try {
+            String id = exchange.getId();
+            Connection connection = null;
+            boolean restoreAutoCommit = false;
+            try {
+                connection = dataSource.getConnection();
+                if (connection.getAutoCommit()) {
+                    connection.setAutoCommit(false);
+                    restoreAutoCommit = true;
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ObjectOutputStream os = new ObjectOutputStream(baos);
+                os.writeObject(exchange);
+                os.close();
+                store(connection, id, baos.toByteArray());
+                connection.commit();
+            } finally {
+                close(connection, restoreAutoCommit);
+            }
+        } catch (Exception e) {
+            log.error("Could not persist exchange", e);
+        }
+    }
+    
+    protected void store(Connection connection, String id, byte[] data) throws Exception {
+        if (adapter.doLoadData(connection, id) != null) {
+            adapter.doUpdateData(connection, id, data);
+        } else {
+            adapter.doStoreData(connection, id, data);
+        }
+    }
+    
+    public DataSource getDataSource() {
+        return dataSource;
+    }
+
+    public void setDataSource(DataSource dataSource) {
+        this.dataSource = dataSource;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeCount()
+     */
+    public int getExchangeCount() throws AuditorException {
+        Connection connection = null;
+        try {
+            connection = dataSource.getConnection();
+            return adapter.doGetCount(connection);
+        } catch (Exception e) {
+            throw new AuditorException("Could not retrieve exchange count", e);
+        } finally {
+            close(connection, false);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchangeIds(int, int)
+     */
+    public String[] getExchangeIdsByRange(int fromIndex, int toIndex) throws AuditorException {
+        if (fromIndex < 0) {
+            throw new IllegalArgumentException("fromIndex should be greater or equal to zero");
+        }
+        if (toIndex < fromIndex) {
+            throw new IllegalArgumentException("toIndex should be greater or equal to fromIndex");
+        }
+        // Do not hit the database if no ids are requested
+        if (fromIndex == toIndex) {
+            return new String[0];
+        }
+        Connection connection = null;
+        try {
+            connection = dataSource.getConnection();
+            return adapter.doGetIds(connection, fromIndex, toIndex);
+        } catch (Exception e) {
+            throw new AuditorException("Could not retrieve exchange ids", e);
+        } finally {
+            close(connection, false);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#getExchanges(java.lang.String[])
+     */
+    public Exchange[] getExchangesByIds(String[] ids) throws AuditorException {
+        Exchange[] exchanges = new Exchange[ids.length];
+        Connection connection = null;
+        try {
+            connection = dataSource.getConnection();
+            for (int row = 0; row < ids.length; row++) {
+                exchanges[row] = getExchange(adapter.doLoadData(connection, ids[row]));
+            }
+            return exchanges;
+        } catch (Exception e) {
+            throw new AuditorException("Could not retrieve exchanges", e);
+        } finally {
+            close(connection, false);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.servicemix.nmr.audit.AuditorMBean#deleteExchanges(java.lang.String[])
+     */
+    public int deleteExchangesByIds(String[] ids) throws AuditorException {
+        Connection connection = null;
+        boolean restoreAutoCommit = false;
+        try {
+            connection = dataSource.getConnection();
+            if (connection.getAutoCommit()) {
+                connection.setAutoCommit(false);
+                restoreAutoCommit = true;
+            }
+            for (int row = 0; row < ids.length; row++) {
+                adapter.doRemoveData(connection, ids[row]);
+            }
+            connection.commit();
+            return -1;
+        } catch (Exception e) {
+            throw new AuditorException("Could not delete exchanges", e);
+        } finally {
+            close(connection, restoreAutoCommit);
+        }
+    }
+    
+    protected Exchange getExchange(byte[] data) throws AuditorException {
+        try {
+            ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(data));
+            return (Exchange) is.readObject();
+        } catch (Exception e) {
+            throw new AuditorException("Unable to reconstruct exchange", e);
+        }
+    }
+    
+    public boolean isAutoStart() {
+        return autoStart;
+    }
+
+    public void setAutoStart(boolean autoStart) {
+        this.autoStart = autoStart;
+    }
+
+    private static void close(Connection connection, boolean restoreAutoCommit) {
+        if (connection != null) {
+            try {
+                if (restoreAutoCommit) {
+                    connection.setAutoCommit(true);
+                }
+                connection.close();
+            } catch (SQLException e) {
+                // Do nothing
+            }
+        }
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/package.html
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/package.html?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/package.html (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/jdbc/package.html Tue Mar 10 20:50:52 2009
@@ -0,0 +1,27 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+-->
+<html>
+<head>
+</head>
+<body>
+
+Plain JDBC auditor.
+
+</body>
+</html>

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/DefaultLuceneCallback.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/DefaultLuceneCallback.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/DefaultLuceneCallback.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/DefaultLuceneCallback.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+
+/**
+ * Default Lucene Callback implementation. Used on LuceneAuditor
+ * 
+ * @author George Gastaldi (gastaldi)
+ * @since 2.1
+ * @version $Revision: 550578 $
+ */
+public class DefaultLuceneCallback implements LuceneCallback {
+
+    private String field;
+
+    private String query;
+
+    public DefaultLuceneCallback(String field, String query) {
+        this.field = field;
+        this.query = query;
+    }
+
+    public Object doCallback(IndexSearcher is) throws IOException {
+        try {
+            QueryParser qp = new QueryParser(field, new StandardAnalyzer());
+            Query queryObj = qp.parse(query);
+            TopDocs topdocs = is.search(queryObj, Integer.MAX_VALUE);
+            int total = topdocs.totalHits;
+            String[] ids = new String[total];
+            for (int i = 0; i < total; i++) {
+                ScoreDoc d = topdocs.scoreDocs[i];
+                ids[i] = is.doc(d.doc).get("org.apache.servicemix.id");
+            }
+            return ids;
+        } catch (ParseException pe) {
+            return new String[0];
+        }
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneAuditor.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneAuditor.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneAuditor.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneAuditor.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.lucene;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.api.Message;
+import org.apache.servicemix.nmr.api.Status;
+import org.apache.servicemix.nmr.api.Type;
+import org.apache.servicemix.nmr.api.event.ExchangeListener;
+import org.apache.servicemix.nmr.audit.AbstractAuditor;
+import org.apache.servicemix.nmr.audit.AuditorException;
+import org.apache.servicemix.nmr.audit.AuditorMBean;
+import org.apache.servicemix.nmr.audit.AuditorQueryMBean;
+import org.apache.servicemix.nmr.core.util.StringSource;
+
+/**
+ * Lucene AuditorQuery implementation. It uses Lucene as the indexing mechanism
+ * for searching Exchanges and needs a delegated AuditorMBean to persist
+ * Exchanges.
+ * 
+ * The Content of messages are stored as: 
+ *  - org.apache.servicemix.in.contents
+ *  - org.apache.servicemix.out.contents, if exists
+ *  - org.apache.servicemix.fault.contents, if exists
+ * 
+ * Properties for IN Messages are stored as: 
+ *  - org.apache.servicemix.in.propertyname
+ *  - org.apache.servicemix.out.propertyname, if exists
+ *  - org.apache.servicemix.fault.propertyname, if exists
+ * 
+ * @author George Gastaldi
+ * @since 2.1
+ * @version $Revision: 550578 $
+ */
+public class LuceneAuditor extends AbstractAuditor implements AuditorQueryMBean {
+
+    private AuditorMBean delegatedAuditor;
+
+    private LuceneIndexer luceneIndexer = new LuceneIndexer();
+
+    /**
+     * @return Returns the luceneIndexer.
+     */
+    public LuceneIndexer getLuceneIndexer() {
+        return luceneIndexer;
+    }
+
+    /**
+     * @param luceneIndexer
+     *            The luceneIndexer to set.
+     */
+    public void setLuceneIndexer(LuceneIndexer luceneIndexer) {
+        this.luceneIndexer = luceneIndexer;
+    }
+
+    /**
+     * @return Returns the delegatedAuditor.
+     */
+    public AuditorMBean getDelegatedAuditor() {
+        return delegatedAuditor;
+    }
+
+    /**
+     * @param delegatedAuditor
+     *            The delegatedAuditor to set.
+     */
+    public void setDelegatedAuditor(AuditorMBean delegatedAuditor) {
+        this.delegatedAuditor = delegatedAuditor;
+    }
+
+    public int getExchangeCount() throws AuditorException {
+        return this.delegatedAuditor.getExchangeCount();
+    }
+
+    public String[] getExchangeIdsByRange(int fromIndex, int toIndex) throws AuditorException {
+        return this.delegatedAuditor.getExchangeIdsByRange(fromIndex, toIndex);
+    }
+
+    public Exchange[] getExchangesByIds(String[] ids) throws AuditorException {
+        return this.delegatedAuditor.getExchangesByIds(ids);
+    }
+
+    public int deleteExchangesByRange(int fromIndex, int toIndex) throws AuditorException {
+        // TODO: Remove ids from Lucene Index
+        return this.delegatedAuditor.deleteExchangesByRange(fromIndex, toIndex);
+    }
+
+    public int deleteExchangesByIds(String[] ids) throws AuditorException {
+        try {
+            this.luceneIndexer.remove(ids);
+        } catch (IOException io) {
+            throw new AuditorException(io);
+        }
+        return this.delegatedAuditor.deleteExchangesByIds(ids);
+    }
+
+    public void exchangeSent(Exchange exchange) {
+        try {
+            Document doc = createDocument(exchange);
+            this.luceneIndexer.add(doc, exchange.getId());
+            if (delegatedAuditor instanceof ExchangeListener) {
+                ((ExchangeListener) delegatedAuditor).exchangeSent(exchange);
+            }
+        } catch (Exception e) {
+            log.error("Error while adding to lucene", e);
+        }
+    }
+
+    public String getDescription() {
+        return "Lucene Auditor";
+    }
+
+    public String[] findExchangesIDsByStatus(Status status) throws AuditorException {
+        String field = "org.apache.servicemix.status";
+        return getExchangeIds(field, String.valueOf(status));
+    }
+
+    public String[] findExchangesIDsByMessageContent(String type, String content) throws AuditorException {
+        String field = "org.apache.servicemix." + type + ".content";
+        return getExchangeIds(field, content);
+    }
+
+    public String[] findExchangesIDsByMessageProperty(String type, 
+                                                      String property, 
+                                                      String value) throws AuditorException {
+        if (property != null && !property.startsWith("org.apache.servicemix")) {
+            property = "org.apache.servicemix." + type + ".headers." + property;
+        }
+        return getExchangeIds(property, value);
+    }
+
+    protected Document createDocument(Exchange exchange) throws AuditorException {
+        try {
+            exchange.ensureReReadable();
+            // This could be in a separated class (a LuceneDocumentProvider)
+            Document d = new Document();
+            d.add(new Field("org.apache.servicemix.id", exchange.getId(), Field.Store.YES, Field.Index.ANALYZED));
+            d.add(new Field("org.apache.servicemix.status", String.valueOf(exchange.getStatus()), Field.Store.YES, Field.Index.ANALYZED));
+
+            Type[] types = { Type.In, Type.Out, Type.Fault };
+            for (int i = 0; i < types.length; i++) {
+                Message message = exchange.getMessage(types[i], false);
+                if (message != null) {
+                    StringSource src = message.getBody(StringSource.class);
+                    d.add(new Field("org.apache.servicemix." + types[i].toString().toLowerCase() + ".content", src.getText(), Field.Store.NO, Field.Index.ANALYZED));
+                    addMessagePropertiesToDocument(message, d, types[i]);
+                }
+            }
+            return d;
+        } catch (Exception ex) {
+            throw new AuditorException("Error while creating Lucene Document", ex);
+        }
+    }
+
+    protected void addMessagePropertiesToDocument(Message message,
+                                                  Document document, 
+                                                  Type type) {
+        for (Map.Entry<String,Object> entry : message.getHeaders().entrySet()) {
+            if (entry.getValue() instanceof String) {
+                //org.apache.servicemix.out.myproperty
+                document.add(new Field("org.apache.servicemix." + type.toString().toLowerCase() + ".headers." + entry.getKey(), (String) entry.getValue(), Field.Store.NO, Field.Index.ANALYZED));
+            }
+        }
+    }
+
+    public String[] getExchangeIds(String queryContent, String field) throws AuditorException {
+        DefaultLuceneCallback dfc = new DefaultLuceneCallback(queryContent, field);
+        try {
+            return (String[]) luceneIndexer.search(dfc);
+        } catch (IOException e) {
+            throw new AuditorException("Error while getting Exchange IDs", e);
+        }
+    }
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneCallback.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneCallback.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneCallback.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneCallback.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.IndexSearcher;
+
+/**
+ * Lucene Callback Interface. Used on searching to be executed on synchronized
+ * blocks.
+ * 
+ * @author George Gastaldi
+ * @since 2.1
+ * @version $Revision: 550578 $
+ */
+public interface LuceneCallback {
+
+    /**
+     * Called by the LuceneIndexer
+     * 
+     * @param is
+     *            IndexSearcher provided by the indexer
+     * @return an object from the query
+     * @throws IOException
+     *             if an error occurs during opening/searching of the index
+     */
+    Object doCallback(IndexSearcher is) throws IOException;
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneIndexer.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneIndexer.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneIndexer.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/LuceneIndexer.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.lucene;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.lucene.analysis.SimpleAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+
+
+/**
+ * Utility class for Lucene API.
+ * @author george
+ * @since 2.1
+ * @version $Revision: 550578 $
+ */
+public class LuceneIndexer {
+    protected Directory directory;
+
+    private File segmentFile;
+
+    public LuceneIndexer() {
+    }
+
+    public Directory getDirectory() {
+        return directory;
+    }
+
+    public void setDirectory(Directory directory) {
+        this.directory = directory;
+    }
+
+    public void setDirectoryName(File directoryName) throws IOException {
+        this.segmentFile = new File(directoryName, "segments");
+        this.directory = FSDirectory.getDirectory(directoryName.toString(), !this.segmentFile.exists());
+    }
+
+    /**
+     * Drop object from Lucene index
+     */
+    protected void remove(String id) throws IOException {
+        synchronized (directory) {
+            IndexReader ir = IndexReader.open(directory);
+            try {
+                ir.deleteDocuments(new Term("org.apache.servicemix.id", id));
+            } finally {
+                ir.close();
+            }
+        }
+    }
+
+    protected void remove(String[] ids) throws IOException {
+        if (ids != null && ids.length > 0) {
+            synchronized (directory) {
+                IndexReader ir = IndexReader.open(directory);
+                try {
+                    for (int i = 0; i < ids.length; i++) {
+                        ir.deleteDocuments(new Term("org.apache.servicemix.id", ids[i]));
+                    }
+                } finally {
+                    ir.close();
+                }
+            }
+        }
+    }
+
+    /**
+     * Add object to Lucene index
+     */
+    public void add(Document lucDoc, String id) throws IOException {
+        synchronized (directory) {
+            IndexWriter writer = new IndexWriter(directory, new SimpleAnalyzer(), !segmentFile.exists());
+            try {
+                writer.addDocument(lucDoc);
+            } finally {
+                writer.close();
+            }
+        }
+    }
+
+    /**
+     * called when an existing document is updated.
+     */
+    public void update(Document lucDoc, String id) throws IOException {
+        remove(id);
+        add(lucDoc, id);
+    }
+
+    public Object search(LuceneCallback lc) throws IOException {
+        synchronized (directory) {
+            IndexReader ir = IndexReader.open(directory);
+            IndexSearcher is = new IndexSearcher(ir);
+            try {
+                return lc.doCallback(is);
+            } finally {
+                is.close();
+                ir.close();
+            }
+        }
+    }
+}
\ No newline at end of file

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/package.html
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/package.html?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/package.html (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/lucene/package.html Tue Mar 10 20:50:52 2009
@@ -0,0 +1,27 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+-->
+<html>
+<head>
+</head>
+<body>
+
+Lucene auditor query implementation.
+
+</body>
+</html>

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/package.html
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/package.html?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/package.html (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/main/java/org/apache/servicemix/nmr/audit/package.html Tue Mar 10 20:50:52 2009
@@ -0,0 +1,27 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+-->
+<html>
+<head>
+</head>
+<body>
+
+ServiceMix Auditing interfaces.
+
+</body>
+</html>

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/AbstractAuditorTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/AbstractAuditorTest.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/AbstractAuditorTest.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/AbstractAuditorTest.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,124 @@
+package org.apache.servicemix.nmr.audit;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import junit.framework.TestCase;
+import org.apache.servicemix.nmr.api.Channel;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.api.NMR;
+import org.apache.servicemix.nmr.api.Pattern;
+import org.apache.servicemix.nmr.api.Endpoint;
+import org.apache.servicemix.nmr.api.Status;
+import org.apache.servicemix.nmr.api.service.ServiceHelper;
+import org.apache.servicemix.nmr.core.ServiceMix;
+import org.apache.servicemix.nmr.core.util.StringSource;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: gnodet
+ * Date: Mar 10, 2009
+ * Time: 4:18:36 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class AbstractAuditorTest extends TestCase {
+
+    public static final String RECEIVER_ENDPOINT_NAME = "receiver";
+
+    protected NMR nmr;
+
+    @Override
+    protected void setUp() throws Exception {
+        ServiceMix smx = new ServiceMix();
+        smx.init();
+        nmr = smx;
+    }
+
+    protected void sendExchange(Object content) {
+        Channel client = nmr.createChannel();
+        Exchange exchange = client.createExchange(Pattern.InOnly);
+        exchange.setTarget(client.getNMR().getEndpointRegistry().lookup(
+                ServiceHelper.createMap(Endpoint.NAME, RECEIVER_ENDPOINT_NAME)));
+        exchange.getIn().setBody(content);
+        client.sendSync(exchange);
+
+    }
+
+    protected ReceiverEndpoint createReceiver(NMR nmr, boolean fault, boolean error) throws Exception {
+        ReceiverEndpoint receiver = new ReceiverEndpoint(fault, error);
+        nmr.getEndpointRegistry().register(receiver,
+                ServiceHelper.createMap(Endpoint.NAME, RECEIVER_ENDPOINT_NAME));
+        return receiver;
+    }
+
+    public static class ReceiverEndpoint implements Endpoint {
+
+        private final List<Exchange> exchanges = new LinkedList<Exchange>();
+        private final boolean sendFault;
+        private final boolean sendError;
+        private Map<String, Boolean> faultSent = new ConcurrentHashMap<String, Boolean>();
+        private Map<String, Boolean> errorSent = new ConcurrentHashMap<String, Boolean>();
+        private Channel channel;
+
+        public ReceiverEndpoint(boolean sendFault, boolean sendError) {
+            this.sendFault = sendFault;
+            this.sendError = sendError;
+        }
+
+        public List<Exchange> getExchanges() {
+            return exchanges;
+        }
+
+        public void setChannel(Channel channel) {
+            this.channel = channel;
+        }
+
+        public synchronized void process(Exchange exchange) {
+            synchronized (exchanges) {
+                exchanges.add(exchange.copy());
+                exchanges.notifyAll();
+            }
+            if (exchange.getStatus() == Status.Active) {
+                String key = exchange.getIn().getBody(String.class);
+                if (sendFault && key != null && !faultSent.containsKey(key)) {
+                    exchange.getFault().setBody(new StringSource("<fault/>"));
+                    channel.send(exchange);
+                    faultSent.put(key, true);
+                } else if (sendError && key != null && !errorSent.containsKey(key)) {
+                    exchange.setError(new Exception("error"));
+                    exchange.setStatus(Status.Error);
+                    channel.send(exchange);
+                    errorSent.put(key, true);
+                } else if (exchange.getPattern() == Pattern.InOut || exchange.getPattern() == Pattern.InOptionalOut) {
+                    exchange.getOut().setBody(new StringSource("<out/>"));
+                    channel.send(exchange);
+                } else {
+                    exchange.setStatus(Status.Done);
+                    channel.send(exchange);
+                }
+            }
+        }
+
+        public void assertExchangesReceived(int count, long timeout) {
+            synchronized (exchanges) {
+                long cur = System.currentTimeMillis();
+                long end = cur + timeout;
+                while (cur < end) {
+                    try {
+                        if (exchanges.size() >= count) {
+                            break;
+                        }
+                        exchanges.wait(end - cur);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    cur = System.currentTimeMillis();
+                }
+                assertTrue("expected number of messages when received: " + exchanges.size(), count <= exchanges.size());
+            }
+        }
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/FileAuditorTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/FileAuditorTest.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/FileAuditorTest.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/file/FileAuditorTest.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.file;
+
+import java.io.File;
+
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.nmr.audit.AbstractAuditorTest;
+import org.apache.servicemix.util.FileUtil;
+
+public class FileAuditorTest extends AbstractAuditorTest {
+
+    private static final File DIRECTORY = new File("target/tests/FileAuditor");
+    private final SourceTransformer transformer = new SourceTransformer();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        FileUtil.deleteFile(DIRECTORY);
+        DIRECTORY.mkdirs();
+    }
+
+    public void testFileAuditor() throws Exception {
+        ReceiverEndpoint receiver = createReceiver(nmr, false, false);
+
+        FileAuditor auditor = new FileAuditor();
+        auditor.setDirectory(DIRECTORY);
+        nmr.getListenerRegistry().register(auditor, null);
+
+        sendExchange(new StringSource("<hello>world</hello>"));
+
+        //check if the message has been audited
+        assertEquals(1, auditor.getExchangeCount());
+        
+        sendExchange(transformer.toDOMSource(new StringSource("<hello>world</hello>")));
+        
+        //check if the message has been audited
+        assertEquals(2, auditor.getExchangeCount());
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditorTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditorTest.java?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditorTest.java (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/test/java/org/apache/servicemix/nmr/audit/jdbc/JdbcAuditorTest.java Tue Mar 10 20:50:52 2009
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicemix.nmr.audit.jdbc;
+
+import java.sql.Connection;
+
+import javax.sql.DataSource;
+
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.nmr.api.Exchange;
+import org.apache.servicemix.nmr.api.Status;
+import org.apache.servicemix.nmr.audit.AbstractAuditorTest;
+import org.hsqldb.jdbc.jdbcDataSource;
+
+public class JdbcAuditorTest extends AbstractAuditorTest {
+
+    private DataSource dataSource;
+
+    private Connection connection;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        jdbcDataSource ds = new jdbcDataSource();
+        ds.setDatabase("jdbc:hsqldb:mem:aname");
+        ds.setUser("sa");
+        dataSource = ds;
+        connection = dataSource.getConnection();
+    }
+
+    protected void tearDown() throws Exception {
+        if (connection != null) {
+            connection.close();
+        }
+    }
+
+    public void testInsertUpdate() throws Exception {
+        AbstractAuditorTest.ReceiverEndpoint receiver = createReceiver(nmr, false, false);
+
+        JdbcAuditor auditor = new JdbcAuditor();
+        auditor.setDataSource(dataSource);
+        auditor.afterPropertiesSet();
+        nmr.getListenerRegistry().register(auditor, null);
+
+        sendExchange(new StringSource("<hello>world</hello>"));
+
+        int nbMessages = auditor.getExchangeCount();
+        assertEquals(1, nbMessages);
+        Exchange[] exchanges = auditor.getExchangesByRange(0, 1);
+        assertNotNull(exchanges);
+        assertEquals(1, exchanges.length);
+        assertEquals(Status.Done, exchanges[0].getStatus());
+
+        // TODO: reenable this when resendExchange is implemented
+
+//        auditor.resendExchange(exchanges[0]);
+//
+//        nbMessages = auditor.getExchangeCount();
+//        assertEquals(2, nbMessages);
+//        Exchange exchange = auditor.getExchangeByIndex(1);
+//        assertNotNull(exchange);
+//        assertEquals(Status.Done, exchange.getStatus());
+    }
+
+}

Added: servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j-tests.properties
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j-tests.properties?rev=752258&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j-tests.properties (added)
+++ servicemix/smx4/nmr/trunk/nmr/audit/src/test/resources/log4j-tests.properties Tue Mar 10 20:50:52 2009
@@ -0,0 +1,42 @@
+# 
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+#
+
+#
+# The logging properties used during tests..
+#
+log4j.rootLogger=DEBUG, out
+
+log4j.logger.org.springframework=INFO
+log4j.logger.org.apache.activemq=INFO
+log4j.logger.org.apache.activemq.spring=WARN
+log4j.logger.org.apache.activemq.store.journal=INFO
+log4j.logger.org.activeio.journal=INFO
+
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+# File appender
+log4j.appender.out=org.apache.log4j.FileAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+log4j.appender.out.file=target/servicemix-test.log
+log4j.appender.out.append=true