Wednesday, September 22, 2010

Chariot Solutions Fall Events

Here are a couple of events that I'd recommend considering...

Continuous Integration for the Enterprise - Tuesday, October 12, 2010

Mobile Application Development Series - Tuesday, November 9th, 2010

Cheers!

Tuesday, August 3, 2010

PGP Encryption with Mule ESB

Recently I encounter an encryption problem in Mule ESB that surprised me...I could not figure out how to encrypt a message?!?!  I wasn't able to find an example on how PGP "encryption" should be configured even after numerous google and mule forum searches.  I was getting a little concerned that the PGP support in mule may be for decryption only.  The PGP Security documentation shows how to setup a security filter to decrypt messages but no example for encrypting (that may change soon...more on that later).  I finally posted a question on the mule forum and got some help from the community.

First of all, I should of been looking at the transformers in mule to perform encryption...duh!  I was so focused on trying to get the security filter to encrypt messages that I forgot about transformers...I know it's hard to image :)  I found out the there is an <encrypt-transformer> and was a little embarrassed that I didn't find it before.  So, I configured the <encrypt-transformer> to use the <pgp:keybased-encryption-strategy> just like I did for the security filter per the PGP Security documentation.  I thought "wow, that was easy", ran my configuration and got a NullPointerException. :(

I could see in the stacktrace that the problem was in the KeyBasedEncryptionStrategy, which was surprising because I was referencing the same <pgp:keybased-encryption-strategy> configuration in the security filter and that was working fine.  Then after taking a closer look at the security filter configuration I noticed that I was missing a reference to the credentialsAccessor.  The problem I was faced with is how to configured the <encrypt-transformer> to use the credentialsAccessor I was using?  Spring to the rescue!  The solution is quite simple.  Basically, all I had to do was inject the credentialsAccessor into the KeyBasedEncryptionStrategy.  To do that I had to configure a new spring bean (id="keyBEStrategy" below) and inject my keyManager and credentialsAccessor.  The nice thing about this solution is that the <encrypt-transformer> can still be used as is with just referencing the newly created strategy (i.e., strategy-ref="keyBEStrategy").  Here's an example configuration:

<?xml version="1.0"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:spring="http://www.springframework.org/schema/beans"
  xmlns:file="http://www.mulesource.org/schema/mule/file/2.2"
  xmlns:pgp="http://www.mulesource.org/schema/mule/pgp/2.2"
  xmlns:stdio="http://www.mulesource.org/schema/mule/stdio/2.2"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.mulesource.org/schema/mule/core/2.2
       http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
    http://www.mulesource.org/schema/mule/file/2.2
       http://www.mulesource.org/schema/mule/file/2.2/mule-file.xsd
    http://www.mulesource.org/schema/mule/pgp/2.2
       http://www.mulesource.org/schema/mule/pgp/2.2/mule-pgp.xsd
    http://www.mulesource.org/schema/mule/stdio/2.2
       http://www.mulesource.org/schema/mule/stdio/2.2/mule-stdio.xsd">

   <file:connector name="fileConnector" pollingFrequency="10000" streaming="false" autoDelete="true">
       <file:expression-filename-parser/>
   </file:connector>
 
  <spring:bean id="pgpKeyManager" class="org.mule.module.pgp.PGPKeyRingImpl" init-method="initialise">
      <spring:property name="publicKeyRingFileName" value="<path to public keyring>/pubring.gpg"/>
      <spring:property name="secretKeyRingFileName" value="<path to private keyring>/secring.gpg"/>
      <!-- secretAliasId is the public key -->
      <spring:property name="secretAliasId" value="<public key id"/>
      <spring:property name="secretPassphrase" value="<password>"/>
  </spring:bean>
 
  <spring:bean id="keyBEStrategy" class="org.mule.module.pgp.KeyBasedEncryptionStrategy"
    init-method="initialise">
    <spring:property name="keyManager" ref="pgpKeyManager"/>
    <spring:property name="credentialsAccessor" ref="credentialAccessor"/>
  </spring:bean>
 
  <pgp:security-manager>
      <pgp:security-provider name="pgpSecurityProvider" keyManager-ref="pgpKeyManager"/>
      <pgp:keybased-encryption-strategy name="keyBasedEncryptionStrategy"
        keyManager-ref="pgpKeyManager"/>
  </pgp:security-manager>

  <spring:bean id="credentialAccessor" class="org.mule.module.pgp.FakeCredentialAccessor"/>

  <model name="fileInboundModel">
    <service name="fileInboundService">
      <inbound>
        <file:inbound-endpoint connector-ref="fileConnector"
                 path="./in">
                
                 <pgp:security-filter strategyName="keyBasedEncryptionStrategy"
                                      signRequired="true"
                                      credentialsAccessor-ref="credentialAccessor"
                                      keyManager-ref="pgpKeyManager"/>
                                     
        </file:inbound-endpoint>
      </inbound>
      <echo-component/>
      <outbound>
        <pass-through-router>
          <file:outbound-endpoint connector-ref="fileConnector" path="./encrypted"
            outputPattern="#[header:originalFilename]-#[function:datestamp].gpg">
            <encrypt-transformer name="pgpEncrypt" strategy-ref="keyBEStrategy"/>
          </file:outbound-endpoint>
        </pass-through-router>     
      </outbound>
    </service>
  </model>

</mule>

This workaround is pretty clean.  MuleSoft is going to review the solution and possibly update their documentation accordingly.

Cheers!

Friday, July 23, 2010

Sending outbound SMTP messages through Gmail with Mule ESB

I'm currently working on a Managed File Transfer (MFT) proof-of-concept for a client using Mule ESB Enterprise.  One of the requirements I had to address is the ability to send SMTP email messages when a particular connector failed, i.e. SFTP connection failed.  I thought to myself, that's a reasonable request and something that is probably straightforward to do in Mule ESB.  Well, if you look at the Mule configuration it is straightforward however, getting to that point using Gmail took some work...so I thought I'd share :)

What you need...
  • Mule ESB (I'm using Mule ESB Enterprise Version: 2.2.5 Build: 16813 along with Mule Management Console support, i.e. mmc-agent-2.2.5.jar) *
  • A test Gmail account
* - if you plan on running the same version I am then there is a patch that needs to be applied to the mmc-agent-2.2.5.jar.  See JIRA issue MULE-4970.

Mule Configuration...
<?xml version="1.0"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:file="http://www.mulesource.org/schema/mule/file/2.2"
  xmlns:smtp="http://www.mulesource.org/schema/mule/smtp/2.2"
  xmlns:email="http://www.mulesource.org/schema/mule/email/2.2"
  xsi:schemaLocation="http://www.mulesource.org/schema/mule/core/2.2
    http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
    http://www.mulesource.org/schema/mule/file/2.2
    http://www.mulesource.org/schema/mule/file/2.2/mule-file.xsd
    http://www.mulesource.org/schema/mule/smtp/2.2
    http://www.mulesource.org/schema/mule/smtp/2.2/mule-smtp.xsd
    http://www.mulesource.org/schema/mule/email/2.2 
    http://www.mulesource.org/schema/mule/email/2.2/mule-email.xsd">

  <description>Test configuration to send SMTP email through Gmail.</description>

  <!-- Configure some properties to work with GMail's SMTP -->
  <smtp:gmail-connector name="emailConnector" />

  <model name="processInboundFileModel">
    <service name="processInboundFileService">
      <inbound>
        <file:inbound-endpoint
                 path="./remoteFS">
        </file:inbound-endpoint>
      </inbound>
    
      <echo-component/>
    
      <outbound>
        <pass-through-router>
          <smtp:outbound-endpoint
            connector-ref="emailConnector"
            host="smtp.gmail.com"
            port="587"
            user="
<account name>%40gmail.com"
            password="
<password>"
            to="
<email addresses>"
            from="
<account name>@gmail.com"
            subject="Test email message"/>
        </pass-through-router>
      </outbound>
    </service>
  </model>
</mule>


As indicated, the Mule configuration is very straightforward.  You can get most of the information you need from the Mule SMTP Transport documentation except for what Gmail port to use and most importantly the gmail-connector information.  That tripped me up for a while until I came across a Mule JIRA issue where someone refer to the configuration in the bookstore example for sending email through Gmail.  I still haven't found much information on this connector and what it's doing but it does work and you need to use in order to connect to Gmail.

One other thing that is documented however maybe overlooked is that you need to replace the "@" symbol in the "user" attribute with the URL escape code of "%40".

Cheers!