Sunday, February 19, 2006

Good AOP discussion on The Server Side

There's a really interesting thread on The Server Side, for anyone interested in AOP and wondering where they might want to use the technology. The original article discusses some the many myths and realities around AOP, also interesting reading. I particularly liked the comment by Bela Ban about how AOP is used in JBossCache, it's a good example of how tool developers are using AOP to create maintainable code in a very abstracted system. On the flip side, about a quarter of the way down there's a good stab at the highly confusing terminology involved with AOP. Very timely for me, because I had a heck of time talking through this with Judith Dinowitz this week, and one of the points I tried to make was that the biggest stumbling block for anyone getting into AOP is probably going to be the terminology. In practice, I think using AOP can be far simpler than in sounds, especially when used with an IoC container like ColdSpring, or Spring for Java. Sometimes I wonder if technologies in Java are purposefully discussed in a very confusing manner, just to keep the faint of hart at bay so the 'gurus' can closely guard their precious secrets. Yet another reason why I like ColdFusion so much, where even very advanced concepts can be discussed in human terms!

Sunday, February 12, 2006

Introducing auto-magic Remoting with ColdSpring

This is kind of a mix between some features that have been available in the ColdSpring BER and some new additions to the AOP framework. Not only is this a kick ass new feature, but it’s also a collaborative effort of Kurt, Dave, and myself, with lots of input from Paul Kenney and Sean Corfield. So kudos goes out to everyone involved! Here’s a general overview of what auto-magic remoting means. Let’s say you have a service component registered with ColdSpring, which does some database access for some piece of a web app. What if we want to take a few of the methods of that service and make them available as remote methods for a flex app, or a web service. Wouldn’t it be nice to simply add a component to the ColdSpring config file that has a list of methods you would like to expose, that will automatically configure itself to your service component, expose those methods as remote, taking care of the CFC to AS object translation for you? How about if you could also simply plug in a security through AOP as well, and pretty much write no additional code at all. Well, that’s exactly what ColdSpring Remoting is all about! So let’s see how we can do this in practice. We’ll start simply, with the configuration of a remote facade, or proxy (it’s sort of a little of both) for a service component, then we’ll add the CFC to AS object translation and finish up with some security. Here’s our service, it’s from the klondike records application available in the BER, in the examples folder.

<!-- catalog service -->
<bean id="catalogService" class="net.klondike.component.CatalogService">
    <property name="catalogDAO">
        <ref bean="catalogDAO" />
    </property>
    <property name="catalogGateway">
        <ref bean="catalogGateway" />
    </property>
</bean>


I won’t go into the code for the components, but this service has methods for listing, searching, adding and updating records (as in vinyl, not tables). I would like to create a remote façade to expose the ‘list’ methods, which would be any methods starting with ‘get’. So I’ll configure a RemoteFactoryBean which creates a proxy, writes it to disk at a specified location (so that the ColdFusion flashGateway can find it) and I’ll tell it which methods to include, which will have ‘remote’ access. Here’s the config:

<!-- a remote service bean -->
<bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean">
    <property name="target">
        <ref bean="catalogService" />
    </property>
    <property name="serviceName">
        <value>RemoteCatalogService</value>
    </property>
    <property name="absolutePath">
        <value>/usr/local/cf7/htdocs/klondike/machii/remoting/</value>
    </property>
    <property name="remoteMethodNames">
        <value>get*</value>
    </property>
</bean>


I set the target to the service cfc I already configured, I give this remote service a name and an absolute path (I could also have used the property ‘relativePath’, meaning webroot relative) where I want the RemoteFactoryBean to create the service, and I give it a pattern to match methods on, so in this case all methods that begin with ‘get’ are included as remote methods. That’s it! When ColdSpring starts up, I can ask it to create the service (I’ll get into that part later) and I’m done! No code written at all! This new remote service will now be available at www.yourdomain.com/klondike/machii/remoting/RemoteCatalogService, ready to go. Pretty slick, huh?

OK, so a few things to point out before I move on. We are using AOP under the hood, so what you are creating is very similar to a proxy object, and it uses the same mechanism for method interception. So what does that mean? Well for one thing, adding translation to and from AS objects to CFCs is a matter of adding a type of around advice configured specifically for remoting. Of course this component is provided by ColdSpring, and the RemoteFactoryBean knows how to configure it for you, all you have to do is properly configure a flashUtilityService and give it to the RemoteFactoryBean. Here’s how we set that up:

<!-- A ColdSpring provided component that inconjunction with flashUtilityService can map ActionScript objects to CFCs. -->
<bean id="flashMappings" class="coldspring.remoting.flash.flashMappings">
    <constructor-arg name="mappings">
    <!-- Here we use a "list" element to pass in an array of structures to the constructor -->
    <list>
        <map>
            <entry key="cfcType">
                <value>net.klondike.component.Record</value>
            </entry>
            <entry key="asType">
                <value>RecordVO</value
            </entry>
        </map>
    </list>
    </constructor-arg>
</bean>

<!-- A service object which can be used by a remote facade to convert CFCs to ActionScript classes and visa versa -->
<bean id="flashUtilityService" class="coldspring.remoting.flash.flashUtilityService">
    <property name="flashMappings">
        <ref bean="flashMappings"/>
    </property>
</bean>


I’ve defined a ColdSpring flashMappings object with the cfcType and asType to translate between. You provide a list of mappings, each one is defined as a map with a key for the CFC and AS types to translate between. Next I simply define the flashUtilityService and provide the mappings object. So now I just give this service to the RemoteProxyBean defined above. Now the config will look like this, all I have added is the property ‘flashUtilityService’:

<bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean">
    <property name="target">
        <ref bean="catalogService" />
    </property>
    <property name="serviceName">
        <value>RemoteCatalogService</value>
    </property>
    <property name="absolutePath">
        <value>/usr/local/cf7/htdocs/klondike/machii/remoting/</value>
    </property>
    <!-- add the new flashUtilityService -->
    <property name="flashUtilityService">
        <ref bean="flashUtilityService" />
    </property>
    <property name="remoteMethodNames">
        <value>get*</value>
    </property>
</bean>


Now my remote service will do all the translation between AS objects and CFCs for me, viola! So what if I want to add a little security to this service, or some logging? As I said before, we are using AOP; RemoteProxyBean actually extends ProxyFactoryBean, and can be configured with any method interceptors or advisors as well. So adding logging and security is pretty much a breeze. I’m not going to go through setting up those advisors, you can read over my first and second AOP tutorials, but here’s how I add them to the remote service:

<bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean">
    <property name="target">
        <ref bean="catalogService" />
    </property>
    <property name="serviceName">
        <value>RemoteCatalogService</value>
    </property>
    <property name="absolutePath">
        <value>/usr/local/cf7/htdocs/klondike/machii/remoting/</value>
    </property>
    <property name="flashUtilityService">
        <ref bean="flashUtilityService" />
    </property>
    <!-- add the logging and security advisors --
    <property name="interceptorNames">
        <list>
        <value>loggingAdvisor</value>
        <value>securityAdvisor</value>
        </list>
    </property>
    <property name="remoteMethodNames">
        <value>get*</value>
    </property>
</bean>


There you go! I added the logging and security advisors in the same way as if I was setting up a normal AOP proxy bean, and that’s it. I now have a pretty sophisticated remote service, with type translation, logging and a security framework all built in, and I didn’t write a speck of code, all I did was rewire existing components from my application. Now that’s cool!

Now all that we need to do is ask ColdSpring to actually create the remote service. There’s a couple of ways you can do this. If you call getBean(‘remoteCatalogService’) on the factory, that will follow the same principles as when using any factory with ColdSpring, and create the service. However, the RemoteFactoryBean has some useful methods for managing remote services, so you may want to retrieve the factory itself from ColdSpring. You can do this by calling getBean(‘&remoteCatalogService’) on the bean factory. This will return an instance of the factory itself and you can then call factory.createRemoteProxy() to create the service, factory.destroyRemoteProxy() to remove it, and factory.isConstructed() to see if the service is ‘alive’. I have some creative uses of the RemoteProxyBean api that I’m looking forward to showing at cf.Objective, so I’ll see you there, and happy remoting!

Thursday, February 09, 2006

cf.Objective sessions announced!

It’s 6:45 in the morning and I just got the cf.Objective session schedule and it looks so good I just have to tell the world immediately! I have to say that I am very impressed with the way this conference is turning out. Jared has put some extremely hard work into this thing, and it’s really paying off. From what I understand he’s been doing pretty much all of the coordinating by himself, he really deserves all the accolades he can get. But let’s get to the conference, shall we, my nose is getting too brown for comfort here! This is going to be a much more advanced leaning conference that other cf conferences that I have been to, that’s for sure, with a definite lean towards enterprise level application engineering. We have Software Engineering, Advanced Enterprise Engineering, and I’m really happy to see, Enterprise Server Tuning as session tracks, and pretty much every session in each track looks great. I particularly like the very timely mashup of Hal Helms speaking about Duck Typing, followed by yours truly speaking about AOP. We should cover a wide range of typing issues there, I have no idea if we will end up on opposite sides of the fence or not! Matt Woodward is doing OOP for nOObz, S Isaac Daeley on SQL Abstraction, Kevin Schmidt on SMS Gateways, it just goes on and on. I just can not imagine missing this conference if you have any interest in advanced coldfusion at all! So get out and register! NOW!