Thursday, June 25, 2015

Wirebox: Creating a Transient Object in a Service

Today I had the need to create a transient object outside of the normal places Wirebox lives in a Coldbox application (handlers, interceptors, etc).  I come from a ColdSpring background, so I never used CS to handle any of my transients, but I wanted to see how Wirebox handled this so I could keep my object creation centralized.

There are several ways to handle creating a transient object in a ColdFusion service.  The easiest is to use createObject() or create a new object using the new keyword right where you need it like this:

var myObj = createObject("component", "");
var myObj - new Object();

Another option is to have your service hand you a new object by defining a load() method:

public myObjectType function load () {
  return createObject("component", "");

The above method works best when using something like CF ORM, where you would specify an optional id parameter and use entityLoadByPK() and return a persistent object.  Overkill for what I need here (no persistence in this application).

What I ended up doing to keep my objects coming from a single source (Wirebox) was to inject Wirebox into my service and use the getInstance() method to hand me a transient instance of my object:


component accessors="true" {
  property name="wb" inject="wirebox";
  function myFunc () {
    var myObj = getWB().getInstance("myObject");

I figure doing it this way makes it much easier as I am presently moving around packages, so defining them once in Wirebox means I don't have to perform a search and replace once the packages settle - I just fix the path in the Wirebox configuration and all objects are updated when the application is reloaded.

Note that this works well for transient objects, but remember for singletons you would just inject them into a property in your service tier.

Tuesday, June 23, 2015

Maildev for Local Development

Recently at work I was tasked with finding a fake SMTP server that would capture emails for review for environments preceding Production. This is especially useful when you are importing production data for testing across environments and ensuring that your customers don't get test emails.  It's something we have all coded around with complex environment configurations in the past, and it offers a much simpler solution.

I looked around at quite a few solutions and most ended up being Windows service based. Being on a Mac they were less than useful, and given that my requirements included the need to move the configuration across multiple environments which are shared by a team of developers, those fell short as none included a web interface for reviewing emails. They all seemed to favor a desktop GUI which could not be viewed without logging in to each server for viewing.

Enter Maildev. Maildev is actively maintained and looks like it has been around for almost year now (probably longer, I'm just going by github commits).

There are a few ways to install, but I installed via npm.  It couldn't be simpler:

  1. Download and install NodeJS/NPM, unless you already have them (as you should!)
  2. Install Maildev using npm (npm install -g maildev).  You'll need to sudo for Mac/Linux.
  3. Start maildev by typing maildev
Pretty straightforward stuff.  Maildev starts on port 1025 by default.  The web interface is available at port 1080.  Maildev will listen on all IPs by default (  These are easy to configure using the command line options -s, -w, and --ip.

Installing this across environments permits you to capture emails on each specific environment, and binding Maildev instances to various IPs allows you to isolate email on a per application basis.  If you are on windows you can always install Maildev as a service using nssm.  On Linux you'd use a combination of forever (maybe) and upstart or chkconfig or whatever your flavor permits.  Let's face it, you're on Linux.  You'll figure it out.

Maildev also has some nice features like testing your emails in various viewports and viewing headers and attachments.

For my purposes using ACF or Railo, the mail config was moved to the app configuration and switches across environments using Ant filter tasks triggered by Jenkins.  I'm sure whatever language you are using has a similar simple configuration option to simplify the task.

Kudos to Dan Farrelly for creating such a useful development tool.