[jboss-svn-commits] JBL Code SVN: r10857 - in labs/jbossesb/trunk/product: core/listeners/src/org/jboss/soa/esb/actions and 14 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Apr 10 13:06:54 EDT 2007


Author: derek.adams
Date: 2007-04-10 13:06:54 -0400 (Tue, 10 Apr 2007)
New Revision: 10857

Added:
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreJCRMessage.java
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/DefaultMessageURIGenerator.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/JcrMessageURIGenerator.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/MessageURIGenerator.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/URIGenerationException.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/notification/NotifyFTP.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRConnectionManager.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStoreImpl.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStorePlugin.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRNodeNames.java
   labs/jbossesb/trunk/product/install/conf/repository.xml
   labs/jbossesb/trunk/product/lib/ext/commons-io-1.3.jar
   labs/jbossesb/trunk/product/lib/ext/jackrabbit-api-1.2.1.jar
   labs/jbossesb/trunk/product/lib/ext/jackrabbit-core-1.2.1.jar
   labs/jbossesb/trunk/product/lib/ext/jackrabbit-jcr-commons-1.2.1.jar
   labs/jbossesb/trunk/product/lib/ext/jcr-1.0.jar
   labs/jbossesb/trunk/product/lib/ext/lucene-core-2.0.0.jar
Modified:
   labs/jbossesb/trunk/product/build-distr.xml
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Configuration.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Environment.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/services/persistence/MessageStore.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/db/DBMessageStoreImpl.java
   labs/jbossesb/trunk/product/core/services/src/org/jboss/soa/esb/services/persistence/MessageStoreType.java
Log:
Added JCR message store support.

Modified: labs/jbossesb/trunk/product/build-distr.xml
===================================================================
--- labs/jbossesb/trunk/product/build-distr.xml	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/build-distr.xml	2007-04-10 17:06:54 UTC (rev 10857)
@@ -87,6 +87,7 @@
             <include name="jbossesb-properties.xml"/>
             <include name="esb.juddi.properties"/>
             <include name="smooks-cdr.lst"/>
+            <include name="repository.xml"/>
          </fileset>
          <fileset dir="${installation.files.dir}/jUDDI-registry">
             <include name="juddi-ds.xml"/>
@@ -128,6 +129,10 @@
          <fileset dir="${lib.ext.dir}" includes="milyn-*.jar,opencsv-*.jar,ognl-*.jar,groovy-*.jar,commons-lang-2.1.jar"/>
          <!-- ftp -->
          <fileset dir="${lib.ext.dir}" includes="edtftpj.jar"/>
+        <!-- connection pooling -->
+        <fileset dir="${lib.ext.dir}" includes="c3p0-*.jar"/>
+        <!-- JCR repository -->
+        <fileset dir="${lib.ext.dir}" includes="jcr-*.jar,jackrabbit-*.jar,commons-io-*.jar,lucene-*.jar"/>
       </copy>
 
    </target>

Added: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreJCRMessage.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreJCRMessage.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreJCRMessage.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,45 @@
+package org.jboss.soa.esb.actions.persistence;
+
+import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.persistence.MessageStore;
+import org.jboss.soa.esb.services.persistence.MessageStoreException;
+import org.jboss.soa.esb.services.persistence.MessageStoreFactory;
+import org.jboss.soa.esb.services.persistence.MessageStoreType;
+
+/**
+ * Action that stores the incoming message to the JCR message store.
+ * 
+ * @author Derek Adams
+ */
+public class StoreJCRMessage extends AbstractActionPipelineProcessor {
+
+	/**
+	 * Constructor called by pipeline.
+	 * 
+	 * @param config
+	 */
+	public StoreJCRMessage(ConfigTree config) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#process(org.jboss.soa.esb.message.Message)
+	 */
+	public Message process(Message message) throws ActionProcessingException {
+		MessageStore store = MessageStoreFactory.getInstance().getMessageStore(MessageStoreType.JCR);
+		if (store == null) {
+			throw new ActionProcessingException(
+					"JCR message store not available. Verify that the plugin is configured.");
+		}
+		try {
+			store.addMessage(message);
+			return message;
+		} catch (MessageStoreException e) {
+			throw new ActionProcessingException(e);
+		}
+	}
+}

Added: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,40 @@
+package org.jboss.soa.esb.actions.persistence;
+
+import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.persistence.MessageStore;
+import org.jboss.soa.esb.services.persistence.MessageStoreException;
+import org.jboss.soa.esb.services.persistence.MessageStoreFactory;
+
+/**
+ * Action that stores the incoming message to the default message store.
+ * 
+ * @author Derek Adams
+ */
+public class StoreMessage extends AbstractActionPipelineProcessor {
+
+	/**
+	 * Constructor called by pipeline.
+	 * 
+	 * @param config
+	 */
+	public StoreMessage(ConfigTree config) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#process(org.jboss.soa.esb.message.Message)
+	 */
+	public Message process(Message message) throws ActionProcessingException {
+		MessageStore store = MessageStoreFactory.getInstance().getMessageStore();
+		try {
+			store.addMessage(message);
+			return message;
+		} catch (MessageStoreException e) {
+			throw new ActionProcessingException(e);
+		}
+	}
+}

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/DefaultMessageURIGenerator.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/DefaultMessageURIGenerator.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/DefaultMessageURIGenerator.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,33 @@
+package org.jboss.internal.soa.esb.message.urigen;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.UUID;
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.urigen.MessageURIGenerator;
+import org.jboss.soa.esb.message.urigen.URIGenerationException;
+
+/**
+ * Default message URI generator. Generates a UUID independent of message
+ * contents.
+ * 
+ * @author Derek Adams
+ */
+public class DefaultMessageURIGenerator implements MessageURIGenerator {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.message.urigen.MessageURIGenerator#generateMessageURI(org.jboss.soa.esb.message.Message)
+	 */
+	public URI generateMessageURI(Message message)
+			throws URIGenerationException {
+		String uuid = UUID.randomUUID().toString();
+		try {
+			return new URI("urn:jboss/esb/message/UID#" + uuid);
+		} catch (URISyntaxException e) {
+			throw new URIGenerationException(e);
+		}
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/JcrMessageURIGenerator.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/JcrMessageURIGenerator.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/internal/soa/esb/message/urigen/JcrMessageURIGenerator.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,32 @@
+package org.jboss.internal.soa.esb.message.urigen;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.UUID;
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.urigen.MessageURIGenerator;
+import org.jboss.soa.esb.message.urigen.URIGenerationException;
+
+/**
+ * Generates a message URI that can be used as a JCR node name.
+ * 
+ * @author Derek Adams
+ */
+public class JcrMessageURIGenerator implements MessageURIGenerator {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.message.urigen.MessageURIGenerator#generateMessageURI(org.jboss.soa.esb.message.Message)
+	 */
+	public URI generateMessageURI(Message message)
+			throws URIGenerationException {
+		String uuid = UUID.randomUUID().toString();
+		try {
+			return new URI(uuid);
+		} catch (URISyntaxException e) {
+			throw new URIGenerationException(e);
+		}
+	}
+}
\ No newline at end of file

Modified: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Configuration.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Configuration.java	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Configuration.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -308,6 +308,26 @@
 		String property = ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE).getProperty(Environment.MSG_STORE_DB_DATASOURCE_NAME);
 		return property;
 	}
+	
+	public static String getJcrStoreJNDIPath()
+	{
+		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE).getProperty(Environment.MSG_STORE_JCR_JNDI_PATH);
+	}
+	
+	public static String getJcrStoreUsername()
+	{
+		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE).getProperty(Environment.MSG_STORE_JCR_USERNAME);
+	}
+	
+	public static String getJcrStorePassword()
+	{
+		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE).getProperty(Environment.MSG_STORE_JCR_PASSWORD);
+	}
+	
+	public static String getJcrStoreRootNodePath()
+	{
+		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE).getProperty(Environment.MSG_STORE_JCR_ROOT_NODE_PATH);
+	}
 
 	public static String getContentBasedRouterImplementationClass()
 	{

Modified: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Environment.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Environment.java	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/common/Environment.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -121,5 +121,13 @@
 	public static final String MSG_STORE_DB_POOL_TIMEOUT_MILLIS	= "org.jboss.soa.esb.persistence.db.pool.timeout.millis";
 	public static final String MSG_STORE_DB_CONN_MANAGER		= "org.jboss.soa.esb.persistence.db.conn.manager";
 	public static final String MSG_STORE_DB_DATASOURCE_NAME		= "org.jboss.soa.esb.persistence.db.datasource.name";
+	
+	/*
+	 * JcrMessageStore Persistence Store properties.
+	 */
+	public static final String MSG_STORE_JCR_JNDI_PATH			= "org.jboss.soa.esb.persistence.jcr.jndi.path";	
+	public static final String MSG_STORE_JCR_USERNAME			= "org.jboss.soa.esb.persistence.jcr.username";	
+	public static final String MSG_STORE_JCR_PASSWORD			= "org.jboss.soa.esb.persistence.jcr.password";	
+	public static final String MSG_STORE_JCR_ROOT_NODE_PATH		= "org.jboss.soa.esb.persistence.jcr.root.node.path";	
 
 }
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/MessageURIGenerator.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/MessageURIGenerator.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/MessageURIGenerator.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,21 @@
+package org.jboss.soa.esb.message.urigen;
+
+import java.net.URI;
+
+import org.jboss.soa.esb.message.Message;
+
+/**
+ * Interface for classes that generate URIs for messages.
+ * 
+ * @author Derek Adams
+ */
+public interface MessageURIGenerator {
+
+	/**
+	 * Generate a unique URI for a message.
+	 * 
+	 * @param message
+	 * @return
+	 */
+	public URI generateMessageURI(Message message) throws URIGenerationException;
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/URIGenerationException.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/URIGenerationException.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/message/urigen/URIGenerationException.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,27 @@
+package org.jboss.soa.esb.message.urigen;
+
+/**
+ * Exception thrown when a URI can not be generated for a message.
+ * 
+ * @author Derek Adams
+ */
+public class URIGenerationException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	public URIGenerationException() {
+		super();
+	}
+
+	public URIGenerationException(String arg0, Throwable arg1) {
+		super(arg0, arg1);
+	}
+
+	public URIGenerationException(String arg0) {
+		super(arg0);
+	}
+
+	public URIGenerationException(Throwable arg0) {
+		super(arg0);
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/notification/NotifyFTP.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/notification/NotifyFTP.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/notification/NotifyFTP.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,107 @@
+package org.jboss.soa.esb.notification;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.addressing.eprs.FTPEpr;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.util.RemoteFileSystem;
+import org.jboss.soa.esb.util.RemoteFileSystemException;
+import org.jboss.soa.esb.util.RemoteFileSystemFactory;
+
+/**
+ * Sends
+ * @author <a href="mailto:rex.sheridan at sapience360.com">Rex Sheridan</a>
+ */
+public class NotifyFTP extends NotificationTarget {
+
+	private static final Logger logger = Logger.getLogger(NotifyFTP.class);
+
+	private FTPEpr epr;
+
+	private String fileName;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.notification.NotificationTarget#sendNotification(org.jboss.soa.esb.message.Message)
+	 */
+	public void sendNotification(Message message) throws NotificationException {
+		OutputStream stream = null;
+		File tmpFile = null;
+		RemoteFileSystem rfs = null;
+		try {
+			rfs = RemoteFileSystemFactory.getRemoteFileSystem(epr, true);
+			tmpFile = File.createTempFile("jbossesb-NotifyFTP", null);
+			stream = new FileOutputStream(tmpFile);
+			writeValueToStream(message, stream);
+			rfs.uploadFile(tmpFile, fileName);
+		} catch (RemoteFileSystemException e) {
+			throw new NotificationException("Could not complete FTP notification", e);
+		} catch (IOException e) {
+			throw new NotificationException("Could not complete FTP notification", e);
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					logger.error("Unable to close stream", e);
+				}
+			}
+			if (tmpFile != null) {
+				tmpFile.delete();
+			}
+			if (rfs != null) {
+				rfs.quit();
+			}
+		}
+
+	}
+
+	/**
+	 * @param value
+	 * @param stream
+	 * @throws NotificationException
+	 * @throws IOException
+	 */
+	private void writeValueToStream(Message message, OutputStream stream)
+			throws NotificationException, IOException {
+		IOUtils.write(message.getBody().getContents(), stream);
+		stream.flush();
+		stream.close();
+	}
+
+	/**
+	 * @return the epr
+	 */
+	public FTPEpr getEpr() {
+		return epr;
+	}
+
+	/**
+	 * @param epr
+	 *            the epr to set
+	 */
+	public void setEpr(FTPEpr epr) {
+		this.epr = epr;
+	}
+
+	/**
+	 * @return the fileName
+	 */
+	public String getFileName() {
+		return fileName;
+	}
+
+	/**
+	 * @param fileName
+	 *            the fileName to set
+	 */
+	public void setFileName(String fileName) {
+		this.fileName = fileName;
+	}
+}
\ No newline at end of file

Modified: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/services/persistence/MessageStore.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/services/persistence/MessageStore.java	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/services/persistence/MessageStore.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -25,11 +25,30 @@
 import java.util.Map;
 
 import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.urigen.MessageURIGenerator;
 
 public interface MessageStore
 {
+	/**
+	 * Get the implementation-specific message URI generator.
+	 * @return the generator
+	 */
+	public MessageURIGenerator getMessageURIGenerator();
+	
+	/**
+	 * Add a message to the store.
+	 * @param message the message to store
+	 * @return the URI of the generated message
+	 * @throws MessageStoreException
+	 */
 	public URI addMessage (Message message) throws MessageStoreException;
 
+	/**
+	 * Get a message from the store by URI.
+	 * @param uid the unique message id
+	 * @return the message
+	 * @throws MessageStoreException
+	 */
 	public Message getMessage (URI uid) throws MessageStoreException;
 	
 	public void setUndelivered(URI uid) throws MessageStoreException;

Modified: labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/db/DBMessageStoreImpl.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/db/DBMessageStoreImpl.java	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/db/DBMessageStoreImpl.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -30,12 +30,13 @@
 import java.sql.Statement;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.UUID;
 
 import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.message.urigen.DefaultMessageURIGenerator;
 import org.jboss.internal.soa.esb.persistence.manager.ConnectionManager;
 import org.jboss.internal.soa.esb.thirdparty.Base64;
 import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.urigen.MessageURIGenerator;
 import org.jboss.soa.esb.persistence.manager.ConnectionManagerException;
 import org.jboss.soa.esb.persistence.manager.ConnectionManagerFactory;
 import org.jboss.soa.esb.services.persistence.MessageStore;
@@ -53,6 +54,8 @@
 	protected ResultSet rs = null;
 
 	protected PreparedStatement ps = null;
+	
+	protected MessageURIGenerator uriGenerator = new DefaultMessageURIGenerator();
 
 	public DBMessageStoreImpl()
 	{
@@ -65,6 +68,13 @@
 		
 	}
 
+	/* (non-Javadoc)
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#getMessageURIGenerator()
+	 */
+	public MessageURIGenerator getMessageURIGenerator() {
+		return uriGenerator;
+	}
+
 	/**
 	 * add's a @Message to the database persistence store
 	 * will set the 'delivered' flag to TRUE by default - assuming that the @Message has been delivered
@@ -79,7 +89,7 @@
 		{
 			conn = mgr.getConnection();
 
-			uid = new URI("urn:jboss/esb/message/UID#" + UUID.randomUUID().toString());
+			uid = uriGenerator.generateMessageURI(message);
 
 			String messageString = Base64.encodeObject(Util.serialize(message));
 

Added: labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRConnectionManager.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRConnectionManager.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRConnectionManager.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,146 @@
+package org.jboss.internal.soa.esb.persistence.format.jcr;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.core.TransientRepository;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.jboss.soa.esb.common.Configuration;
+import org.jboss.soa.esb.helpers.NamingContext;
+import org.jboss.system.server.ServerConfig;
+import org.jboss.system.server.ServerConfigLocator;
+
+/**
+ * Manages connections to a JSR 170 content repository.
+ * 
+ * @author Derek Adams
+ */
+public class JCRConnectionManager {
+
+	/** Singleton instance */
+	private static JCRConnectionManager instance;
+
+	/** Repository instance */
+	private Repository repository;
+
+	/** Repository session */
+	private Session session;
+
+	/**
+	 * Singleton constructor.
+	 */
+	private JCRConnectionManager() {
+	}
+
+	/**
+	 * Get the singleton manager instance.
+	 * 
+	 * @return
+	 */
+	public static JCRConnectionManager getInstance() {
+		if (instance == null) {
+			instance = new JCRConnectionManager();
+		}
+		return instance;
+	}
+
+	/**
+	 * Initialize the repository.
+	 * 
+	 * @param config
+	 * @param home
+	 * @return
+	 * @throws RepositoryException
+	 */
+	protected Repository initRepository(File config, File home) throws RepositoryException {
+		RepositoryConfig rconfig = RepositoryConfig.create(config.getPath(), home.getPath());
+		try {
+			return new TransientRepository(rconfig);
+		} catch (IOException e) {
+			throw new RepositoryException(e);
+		}
+	}
+
+	/**
+	 * Get the repository instance.
+	 * 
+	 * @return
+	 */
+	protected Repository getRepository() throws RepositoryException {
+		if (repository == null) {
+			// If JNDI path specified, load the repository from JNDI.
+			if (!StringUtils.isEmpty(Configuration.getJcrStoreJNDIPath())) {
+				Properties environment = new Properties();
+				environment.setProperty(Context.PROVIDER_URL, Configuration.getJndiServerURL());
+				environment.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+						Configuration.getJndiServerContextFactory());
+				environment.setProperty(Context.URL_PKG_PREFIXES,
+						Configuration.getJndiServerPkgPrefix());
+				Context context = NamingContext.getServerContext(environment);
+				try {
+					repository = (Repository) context.lookup(Configuration.getJcrStoreJNDIPath());
+				} catch (NamingException e) {
+					throw new RepositoryException(e);
+				}
+			}
+			// If no JNDI path is specified, init the repository with default
+			// settings based on the respository.xml in the conf directory.
+			else {
+				try {
+					ClassLoader loader = Thread.currentThread().getContextClassLoader();
+					URL url = loader.getResource("repository.xml");
+					URI uri = new URI(url.toString());
+					File repositoryConfig = new File(uri);
+					ServerConfig config = ServerConfigLocator.locate();
+					File dataDir = config.getServerDataDir();
+					File repositoryFolder = new File(dataDir, "repository");
+					repository = initRepository(repositoryConfig, repositoryFolder);
+				} catch (URISyntaxException e) {
+					throw new RepositoryException(e);
+				}
+			}
+		}
+		return repository;
+	}
+
+	/**
+	 * Open a session on the repository.
+	 * 
+	 * @return
+	 * @throws RepositoryException
+	 */
+	public Session newRepositorySession() throws RepositoryException {
+		String username = Configuration.getJcrStoreUsername();
+		String password = Configuration.getJcrStorePassword();
+		if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
+			throw new RepositoryException(
+					"JCR username and password must be specified in configuration.");
+		}
+		return getRepository().login(new SimpleCredentials(username, password.toCharArray()));
+	}
+
+	/**
+	 * Get the existing repository session or create a new one.
+	 * 
+	 * @return
+	 * @throws RepositoryException
+	 */
+	public Session getSharedSession() throws RepositoryException {
+		if (session == null) {
+			session = newRepositorySession();
+		}
+		return session;
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStoreImpl.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStoreImpl.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStoreImpl.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,225 @@
+package org.jboss.internal.soa.esb.persistence.format.jcr;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.message.urigen.JcrMessageURIGenerator;
+import org.jboss.soa.esb.common.Configuration;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.urigen.MessageURIGenerator;
+import org.jboss.soa.esb.message.urigen.URIGenerationException;
+import org.jboss.soa.esb.services.persistence.MessageStore;
+import org.jboss.soa.esb.services.persistence.MessageStoreException;
+
+/**
+ * Message store that persists messages to a JSR 170 content repository.
+ * 
+ * @author Derek Adams
+ */
+public class JCRMessageStoreImpl implements MessageStore {
+
+	/** Static logger instance */
+	private static Logger LOGGER = Logger.getLogger(JCRMessageStoreImpl.class);
+	
+	/** Generator for JCR-specific message URIs */
+	protected MessageURIGenerator uriGenerator = new JcrMessageURIGenerator();
+
+	/** Root node under which JCR messages are stored (lazy-loaded) */
+	protected Node messageStoreRootNode;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#addMessage(org.jboss.soa.esb.message.Message)
+	 */
+	public URI addMessage(Message message) throws MessageStoreException {
+		try {
+			Session session = JCRConnectionManager.getInstance().newRepositorySession();
+			Node root = getMessageStoreRootNode(session);
+			URI uid = saveMessage(root, message);
+			session.save();
+			return uid;
+		} catch (RepositoryException e) {
+			throw new MessageStoreException(e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#getMessage(java.net.URI)
+	 */
+	public Message getMessage(URI uri) throws MessageStoreException {
+		try {
+			Session session = JCRConnectionManager.getInstance().newRepositorySession();
+			Node root = getMessageStoreRootNode(session);
+			return loadMessage(root, uri);
+		} catch (RepositoryException e) {
+			throw new MessageStoreException(e);
+		}
+	}
+
+	/**
+	 * Save a message to the content repository.
+	 * 
+	 * @param message
+	 * @return
+	 * @throws RepositoryException
+	 */
+	protected URI saveMessage(Node root, Message message) throws RepositoryException {
+		try {
+			URI messageURI = uriGenerator.generateMessageURI(message);
+			Node messageNode = root.addNode(messageURI.toString());
+			Node bodyNode = messageNode.addNode(JCRNodeNames.BODY_NODE_NAME);
+			if (message.getBody().getContents() != null) {
+				ByteArrayInputStream stream = new ByteArrayInputStream(
+						message.getBody().getContents());
+				bodyNode.setProperty(JCRNodeNames.BODY_CONTENT_PROP_NAME, stream);
+			}
+			if (LOGGER.isInfoEnabled()) {
+				LOGGER.info("Saved node to content repository:");
+				dumpNodeToLog(messageNode);
+			}
+			return messageURI;
+		} catch (URIGenerationException e) {
+			throw new RepositoryException(e);
+		}
+	}
+
+	/**
+	 * Load a message from the content repository.
+	 * 
+	 * @param root
+	 * @param uri
+	 * @return
+	 * @throws RepositoryException
+	 */
+	protected Message loadMessage(Node root, URI uri) throws RepositoryException {
+		try {
+			Node messageNode = root.getNode(uri.toString());
+			Node bodyNode = messageNode.getNode(JCRNodeNames.BODY_NODE_NAME);
+			Property bodyContents = bodyNode.getProperty(JCRNodeNames.BODY_CONTENT_PROP_NAME);
+			Message message = MessageFactory.getInstance().getMessage();
+			if (bodyContents != null) {
+				byte[] contentBytes = IOUtils.toByteArray(bodyContents.getStream());
+				message.getBody().setContents(contentBytes);
+			}
+			if (LOGGER.isInfoEnabled()) {
+				LOGGER.info("Loaded node from content repository:");
+				dumpNodeToLog(messageNode);
+			}
+			return message;
+		} catch (IOException e) {
+			throw new RepositoryException(e);
+		}
+	}
+
+	/**
+	 * Dumps the contents of a JCR node to the logger.
+	 * 
+	 * @param node
+	 * @throws RepositoryException
+	 */
+	protected void dumpNodeToLog(Node node) throws RepositoryException {
+		LOGGER.info(node.getPath());
+		if (node.getName().equals("jcr:system")) {
+			return;
+		}
+
+		// Display all node properties.
+		PropertyIterator properties = node.getProperties();
+		while (properties.hasNext()) {
+			Property property = properties.nextProperty();
+			if (property.getDefinition().isMultiple()) {
+				Value[] values = property.getValues();
+				for (int i = 0; i < values.length; i++) {
+					LOGGER.info(property.getPath() + " = " + values[i].getString());
+				}
+			} else {
+				LOGGER.info(property.getPath() + " = " + property.getString());
+			}
+		}
+
+		// Recurse into subnodes.
+		NodeIterator nodes = node.getNodes();
+		while (nodes.hasNext()) {
+			dumpNodeToLog(nodes.nextNode());
+		}
+	}
+
+	/**
+	 * Get the root node under which messages are stored. Create the root path
+	 * if needed.
+	 * 
+	 * @param session
+	 * @return
+	 * @throws RepositoryException
+	 */
+	protected Node getMessageStoreRootNode(Session session) throws RepositoryException {
+		if (messageStoreRootNode == null) {
+			if (StringUtils.isEmpty(Configuration.getJcrStoreRootNodePath())) {
+				throw new RepositoryException("JCR root node path not specified in configuration.");
+			}
+			Node current = session.getRootNode();
+			String[] nodeNames = Configuration.getJcrStoreRootNodePath().split("/");
+			for (String nodeName : nodeNames) {
+				try {
+					current = current.getNode(nodeName);
+				} catch (PathNotFoundException e) {
+					current = current.addNode(nodeName);
+				}
+			}
+			session.save();
+			messageStoreRootNode = current;
+		}
+		return messageStoreRootNode;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#getMessageURIGenerator()
+	 */
+	public MessageURIGenerator getMessageURIGenerator() {
+		return uriGenerator;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#getUndeliveredMessages()
+	 */
+	public Map<URI, Message> getUndeliveredMessages() throws MessageStoreException {
+		return new HashMap<URI, Message>();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#setDelivered(java.net.URI)
+	 */
+	public void setDelivered(URI uid) throws MessageStoreException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.services.persistence.MessageStore#setUndelivered(java.net.URI)
+	 */
+	public void setUndelivered(URI uid) throws MessageStoreException {
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStorePlugin.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStorePlugin.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRMessageStorePlugin.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,34 @@
+package org.jboss.internal.soa.esb.persistence.format.jcr;
+
+import java.net.URI;
+
+import org.jboss.internal.soa.esb.persistence.format.MessageStorePlugin;
+import org.jboss.soa.esb.services.persistence.MessageStore;
+import org.jboss.soa.esb.services.persistence.MessageStoreType;
+
+/**
+ * Plugin that returns a message store capable of storing messages in a JCR
+ * repository.
+ * 
+ * @author Derek Adams
+ */
+public class JCRMessageStorePlugin implements MessageStorePlugin {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.internal.soa.esb.persistence.format.MessageStorePlugin#getMessageStore()
+	 */
+	public MessageStore getMessageStore() {
+		return new JCRMessageStoreImpl();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.internal.soa.esb.persistence.format.MessageStorePlugin#getType()
+	 */
+	public URI getType() {
+		return MessageStoreType.JCR;
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRNodeNames.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRNodeNames.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/internal/soa/esb/persistence/format/jcr/JCRNodeNames.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,18 @@
+package org.jboss.internal.soa.esb.persistence.format.jcr;
+
+/**
+ * Constants for JCR message store node names.
+ * 
+ * @author Derek Adams
+ */
+public interface JCRNodeNames {
+
+	/** Constant for the body node name */
+	public static final String BODY_NODE_NAME = "Body";
+
+	/** Constant for the body content property name */
+	public static final String BODY_CONTENT_PROP_NAME = "Content";
+
+	/** Constant for the properties JCR node name */
+	public static final String PROPERTIES_NODE_NAME = "Properties";
+}
\ No newline at end of file

Modified: labs/jbossesb/trunk/product/core/services/src/org/jboss/soa/esb/services/persistence/MessageStoreType.java
===================================================================
--- labs/jbossesb/trunk/product/core/services/src/org/jboss/soa/esb/services/persistence/MessageStoreType.java	2007-04-10 17:02:36 UTC (rev 10856)
+++ labs/jbossesb/trunk/product/core/services/src/org/jboss/soa/esb/services/persistence/MessageStoreType.java	2007-04-10 17:06:54 UTC (rev 10857)
@@ -35,7 +35,9 @@
 	 * DO NOT reorder this list. New types may be added as required.
 	 */
 	
-	public static URI DATABASE = null;	
+	public static URI DATABASE = null;
+	
+	public static URI JCR = null;
 
 	public static URI DEFAULT_TYPE = null;
 	
@@ -43,7 +45,8 @@
 	{
 		try
 		{
-			DATABASE = new URI("urn:jboss/esb/persistence/type/DATABASE");	
+			DATABASE = new URI("urn:jboss/esb/persistence/type/DATABASE");
+			JCR = new URI("urn:jboss/esb/persistence/type/JCR");	
 			
 			DEFAULT_TYPE = DATABASE;
 		}

Added: labs/jbossesb/trunk/product/install/conf/repository.xml
===================================================================
--- labs/jbossesb/trunk/product/install/conf/repository.xml	                        (rev 0)
+++ labs/jbossesb/trunk/product/install/conf/repository.xml	2007-04-10 17:06:54 UTC (rev 10857)
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+   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.
+  -->
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.2//EN"
+                            "http://jackrabbit.apache.org/dtd/repository-1.2.dtd">
+<Repository>
+    <!--
+    virtual file system where the repository stores global state
+    (e.g. registered namespaces, custom node types, etc.)
+    -->
+    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+	<param name="path" value="${rep.home}/repository"/>
+    </FileSystem>
+
+    <!--
+        security configuration
+    -->
+    <Security appName="Jackrabbit">
+        <!--
+            access manager:
+            class: FQN of class implementing the AccessManager interface
+        -->
+        <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+            <!-- <param name="config" value="${rep.home}/access.xml"/> -->
+        </AccessManager>
+
+        <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
+           <!-- anonymous user name ('anonymous' is the default value) -->
+           <param name="anonymousId" value="anonymous"/>
+        </LoginModule>
+    </Security>
+
+    <!--
+    location of workspaces root directory and name of default workspace
+    -->
+    <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
+    <!--
+    workspace configuration template:
+    used to create the initial workspace if there's no workspace yet
+    -->
+    <Workspace name="${wsp.name}">
+	<!--
+	virtual file system of the workspace:
+	class: FQN of class implementing FileSystem interface
+        -->
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+            <param name="path" value="${wsp.home}"/>
+	</FileSystem>
+	<!--
+	persistence of the workspace:
+	class: FQN of class implementing PersistenceManager interface
+        -->
+	<PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
+	<!--
+	Search index and the file system it uses.
+        -->
+	<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+  		<param name="path" value="${wsp.home}/index"/>
+	</SearchIndex>
+    </Workspace>
+
+    <!--
+    Configures the versioning
+    -->
+    <Versioning rootPath="${rep.home}/version">
+	<!--
+	Configures the filesystem to use for versioning for the respective
+	persistence manager
+        -->
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+            <param name="path" value="${rep.home}/version"/>
+        </FileSystem>
+
+	<!--
+	Configures the persistence manager to be used for persisting version state.
+	Please note that the current versioning implementation is based on
+	a 'normal' persistence manager, but this could change in future
+	implementations.
+        -->
+	<PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
+
+    </Versioning>
+
+
+    <!--
+        Search index for content that is shared repository wide
+        (/jcr:system tree, contains mainly versions)
+        
+        The same parameters are supported as in the search index configuration
+        inside the workspace definition element.
+        
+        This element is optional. If omitted, the /jcr:system tree will not be
+        indexed and no results will be returned for that tree!
+    -->
+    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+        <param name="path" value="${rep.home}/repository/index"/>
+    </SearchIndex>
+</Repository>

Added: labs/jbossesb/trunk/product/lib/ext/commons-io-1.3.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/commons-io-1.3.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/trunk/product/lib/ext/jackrabbit-api-1.2.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/jackrabbit-api-1.2.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/trunk/product/lib/ext/jackrabbit-core-1.2.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/jackrabbit-core-1.2.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/trunk/product/lib/ext/jackrabbit-jcr-commons-1.2.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/jackrabbit-jcr-commons-1.2.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/trunk/product/lib/ext/jcr-1.0.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/jcr-1.0.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/trunk/product/lib/ext/lucene-core-2.0.0.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/trunk/product/lib/ext/lucene-core-2.0.0.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the jboss-svn-commits mailing list