Skip to content

Mule 3.0 Restful Webservice

Mule 3.0 was recently released. Restful web services are now fully supported. You can hot deploy the application now. It is much easier to deploy an application. Unfortunately, as I write this, the documentation is not yet up to date.  The configuration for a restful web service has changed.

The configuration file looks like the following:

mule-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.0/mule.xsd">
    <model name="smsSample">
        <simple-service name="MyService" address="http://localhost:63081/" component-class="com.jasonrowland.example.MyServiceClass" type="jax-rs" />
    </model>
</mule>

The class to implement this service looks like this:

package com.jasonrowland.example;

import javax.ws.rs.*;

@Path("/myroot")
public class MyServiceClass {

    @GET
    @Produces("application/json")
    @Path("/myfunc/{myvar}")
    public MyResponse myfunc(
        @PathParam("myvar") String myvar,
        @FormParam("keyword") String keyword) {

        MyResponse r = new MyResponse();

        if ("fail".equalsIgnoreCase(keyword)) {
            r.setCode(1);
            r.setText("fail is a reserved keyword");
        } else {
            r.setCode(0);
            r.setText("SUCCESS");
        }
        return r;
    }
}

The MyResponse object needs to have an attribute set on it for this to work.

package com.jasonrowland.example;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class SmsResponse {
    // code
    public int getCode() {
        return this.code;
    }
    public void setCode(int value) {
        this.code = value;
    }

    // text
    public String getText() {
        return this.text;
    }
    public void setText(String value) {
        this.text = value;
    }

    private int code;
    private String text;
}

You simply put all your files in a folder under the mule/apps directory. The directory structure looks like this:

MULEHOME/apps/YOURAPP/
                     /mule-config.xml
                     /lib/
                         /yourapp.jar
                         /log4j.jar
                         /anyotherdependency.jar

To run your application in mule, simply type:

mule -app YOURAPP

To hot deploy your application, update your files and type:

touch YOURAPP/mule-config.xml

Amazon vs Rackspace for Blender

I am comparing Amazon and Rackspace to host some of my servers.  I’d like them to render my blender files as well as be a web server for blenderfarmers.com.  So, I have created the smallest possible server on both services.  They are roughly comparable in cost for their smallest instances.  Rackspace is $0.015/hour for their smallest server and Amazon costs $0.02/hour.

Rackspace

I first tried Rackspace because I already have an account there.  I setup Ubuntu 64bit and installed the 2.49b 64bit version of Blender.  I downloaded the test.blend file from http://www.eofw.org/bench/ and executed it with the following command:

/usr/local/blender/2.49b/blender -b test.blend -o //test. -F PNG -t 0 -f 1

It returned in 47 seconds.

I then ran the 2.5.3 beta version of blender with the same command and it returned in 18 seconds but exited with Segmentation fault.  I can reproduce that segmentation fault on my Mac with the same version of Blender.

Amazon EC2

I then created Amazon’s micro on-demand server.  I only had Fedora as a choice from the prepackaged ones.  There are over 5000 pre-built images from the public though I didn’t see Ubunto v 10.  Also, the micro version only allows 32 bit computers.  The nice thing about Fedora is that I installed a headless blender by simply typing:

yum blender

It installed 2.48.  It took 17 minutes and 10 seconds to render that same frame!  What in the world!  I’m not sure why it takes so long on the Amazon server compared to the Rackspace server, but Rackspace is cheaper AND faster for rendering frames in Blender.

blenderfarmers.com

My brother Doug went to Full Sail film school and has recently gotten me into the hobby of making shorts in our fun time (www.simplemindedstudios.com).  Currently, we are making a short using my children as the actors.  We don’t have access to very many interesting places to film so we decided to create most of the sets in the computer.   He likes to experiment mixing 3d graphics in live action movies.  We are really at the beginner stage of learning how to make it look good.  If it weren’t my own children starring in the movie, I might even think they look laughably bad.  Not only is it challenging to make it look good artistically, it is challenging on the technical side as well.

The reason it is challenging on the technical side is that it takes a LOT of computer horse power to render usable video footage for any sizable project.  Due to the work-flow, you sometimes have to render a scene several times to get it right.  Just last night, we finally got to take a look at a render and we noticed a flickering problem in our render.  When you render a single frame, you don’t notice because each individual frame looks “correct”.  It isn’t until you string all the frames together to make a video that you can notice the subtle changes in the intensities of the light.  Also, when you are animating characters, you can’t really know what they look like until you do the render because the preview capability isn’t smooth.

Let me try and explain the magnitude of the problem that I am trying to solve.  For every second of a movie, there are 24 frames.  So, for a 15 minute movie, we will need to do a final render on 21,600 frames.  Let’s assume that it takes us 5 attempts at rendering to get a scene right.  that brings the number of frames we need to render to 108,000 frames.  Now, on my brother’s dual core iMac, it takes about 10 minutes to render a single frame.  If we were to render this entire movie on his computer, it would take 1,080,000 minutes to render.  That is 750 days 24/7, non-stop, rendering.  This is where the interesting challenge comes in.

The solution is to get a LOT of CPUs attacking the problem.  You can solve it by buying bigger beefier machines.  I purchased a new iMac i7 with true quad core processing that shows the OS that it has 8 CPUs.  The new machine enables us to render a frame 4 times faster.  I also built a PC with similar specs so we can have two machines rendering frames 24/7.  So just buying a much faster machine brought the time required for our movie down to three months.  This is good, but not good enough.  That’s where a render farm comes in.

A render farm is simply a lot of computers working together on a single movie sequence or even a single image.  There is typically a controlling computer that manages all the renders.  It tells each computer which scene and frame to render and then assembles all those images back together into a movie scene.  When a computer gets done with one frame, it asks that computer which frame it should render next.  So, you submit your animation to one computer, and that computer distributes the workload to everyone else.  When it is done, you go back to that same computer and see your results.  This is how Pixar gets things done but they have thousands of computers.

I’ve done a lot of looking for a render farm solution that I can use with Blender (the free 3d package we use).  There are quite a few solutions I looked at:  Farmer Joe, Dr. Queue, Res Power, renderfarm.fi, BURP, vSwarm.  None of these were appealing to me for various reasons.  Some only supported computers on a common network, others didn’t support creating your own farm if you have lots of machines.  The community ones, you are at the mercy of getting render time, so it could be hours before the computers even begin working on your render.  I need a sort of hybrid where you can use your own computers, your friends computers, and even rent servers if you are approaching a deadline.  I have several good machines not really doing anything useful right now.  I also have several machines that don’t have much usage during the day.  All of my machines could work on rendering scenes at night.  These machines run Windows, Mac, and Linux, so I need it to be cross-platform.  I also have friends that would be willing to render frames for me too.    The conclusion I reached is that I need/want to build my own render farm.

Since I need the client to run on the big 3 OS, I decided it was a perfect opportunity to enhance my skills with Ruby.  Not only can I build the server in Ruby on Rails, I can build a native looking client using Ruby with wxRuby.

I want to give back to the OS community that I’ve taken so much from.  I am going to use this project to contribute to the Ruby community by hopefully being able to work on wxRuby by either coding bug fixes or perhaps writing tutorials.  I also want to give back to the Blender community by making my render farming code open source so anyone can run their own server.

I secured the domain blenderfarmers.com for this project.

Ruby ‘here document’

Ruby has a cool feature that allows you to embed a document inside your source code.  This is known as a ‘here document’.  The traditional way of defining a string is to assign a variable as follows:

def myfunc
  mystring = "Here's a great quote: \n\n\"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.\"\n\n - Declaration of independence.\n"
end

The here document feature allows for syntax like the following:

def myfun
  mystring = <<MYDELIMITOR
Here's a great quote: 

"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness." 

- Declaration of independence.

MYDELIMITOR
end

The MYDELIMITOR can be anything that you want, just make sure that it won’t exist in your “here document” text. Also, the MYDELIMITOR must be the first token on a new line unless you use the following syntax:

mystring = <<-MYDELIMITOR

If you use that syntax, then you can indent it. Important to note that your string will have all line breaks and indentations. So, if you have nested code, it might look a little ugly but it sure is nice to not have to escape everything.

Compiling wxruby on Snow Leopard

I am trying to compile wxruby on Snow Leopard.  I am running into issues because wxwidgets 2.8 which wxruby 2.0.1 is based upon only compiles in 32bit mode.  I can compile wxwidgets 2.8.11 using 32 bit mode.  When I try to compile wxruby, I get errors.  I’m not quite sure what I need to do to resolve this yet.  Once (If) I do, I’ll update this post.

compile wxMac

# Download, compile, install the 2.8.11 version of wxMac
mkdir osx-build
cd osx-build
arch_flags="-arch i386"
../configure  CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags" --enable-universal_binary --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdk --with-macosx-version-min=10.4 --disable-shared --enable-unicode --enable-static --disable-debug --enable-catch_segvs --enable-graphics_ctx --enable-mediactrl --with-opengl --with-libjpeg=builtin --with-libpng=builtin --with-libtiff=builtin --with-expat=builtin --enable-gui --enable-xrc --enable-mdi --enable-gif --enable-pcx --enable-iff --enable-pnm --enable-xpm --with-macosx-sdk=/Developer/SDKs/MacOSX10.6.sdk --with-macosx-version-min=10.6
make
sudo make install

compile SWIG

# Download, compile, install SWIG 1.3.38
cd /usr/local/swig-1.3.38
sudo ./configure --disable-ccache #--disable-ccache is because I do not have yodl2man installed
sudo make
sudo make install

compile wxruby

# Downloaded the trunk versin of wxRuby
svn checkout svn://rubyforge.org/var/svn/wxruby
cd wxruby/trunk
rake

Error!

# ---------------- ERROR
I get the following error:
lipo: can't figure out the architecture type of: /var/folders/pI/pIyyNf1MGiaa6DODFaul2U+++TI/-Tmp-//ccmdge2D.out
lipo: can't open input file: /var/folders/pI/pIyyNf1MGiaa6DODFaul2U+++TI/-Tmp-//ccsraXTA.out (No such file or directory)
rake aborted!
Command failed with status (1): [g++ -c  -I/usr/local/lib/wx/include/mac-un...]

SSH and Amazon Cloud

While trying to login to an Amazon cloud server from my Mac, with the following command:

ssh -i register.pem username@myamazonserver.amazonaws.com

I got this error message:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'tmn_register.pem' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: tmn_register.pem
Permission denied (publickey).

Apparently, the permissions on the filesystem for the key file that was given to me were too secure.  I changed the permissions to disallow all access except me and all was well.

chmod 600 register.pem

Mac Application Bundle

So, I packaged up my native looking Mac application in my own Application Bundle.  It was super simple to do.

An application bundle is nothing more than a folder that has been renamed with the extension “.app” and conforms to a certain directory structure.  The directory structure looks like this:

/Contents/
/Contents/Info.plist
/Contents/MacOS/
/Contents/Resources/
/Contents/youricon.icns

The important piece is Info.plist.  It tells the system what to call your bundle and where the executable is located.

<plist version="1.0">
<dict>
  <key>CFBundleExecutable</key>
  <string>test.rb</string>
  <key>CFBundleGetInfoString</key>
  <string>Test</string>
  <key>CFBundleIconFile</key>
  <string>test.icns</string>
  <key>CFBundleIdentifier</key>
  <string>test</string>
  <key>CFBundleName</key>
  <string>Test Name</string>
</dict>
</plist>

Your application should go in MacOS.  I put my ruby script in the MacOS directory and it could not longer load my resources that were right next to it in that directory.  If I hard code the path to be an absolute path based on where the app is bundled (/Users/jasonxrowland/myapp.app/Contents/MacOS) it works.  I have a feeling, I need to call a Mac specific API to get the resource bundle path.  I’ll figure that out later…

I created the icon using the Icon Composer application included with the Mac.

JAVA_HOME on MacOSX

edit your ~/.profile (or ~/.bash_profile if you are using that instead) and add the following

export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home

Native Looking Mac App with Ruby

Ruby is really popular to make websites because of Rails, but I want to write a native looking application using Ruby.  I’ve discovered wxruby which is a really cool cross platform GUI library for use with Ruby.  It is built on wxWidgets which is a C++ library for making cross platform GUIs that appear native because they are built on the underlying native libraries of each platform (linux, OSX, and Windows).  Right now, I’m interested in Mac, but I plan on testing this on Windows and Linux too.

Installation

wxWidgets

You have to download the source and compile it yourself for Snow Leopard.  This means, you need to install the developer toolset that comes with your Snow Leopard DVD.  Just install everything, hard drives are cheap.  I don’t know if you have to actually run “./configure”, “make” or not.  My guess is you don’t, but I did.  Snow Leopard has some special challenges and you have to do the following:

$ set arch_flags="-arch x86_64"
$ ./configure CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags"
$ make

DialogBlocks

After you download, Open the DMG image and copy the contents to wherever you want.  I copied mine to /Developer/Applications.  When you run this for the first time, it asks you to select the location of wxWidgets.

wxruby

The latest stable version is 2.0.1.  If you try to install wxruby through gems, it will install 1.9.3.  I don’t know what’s different between the two, but 2.0.1 is a year old so I want to use it.

wx_sugar

$ gem install wx_sugar

Ruby

You should already have a version of Ruby installed.  I list it here because the latest version as I write this is 1.9.2.  Unfortunately, one of the tools we will use to generate ruby classes does not support 1.9.2.  If you really want to use 1.9.2, you can follow the directions here.  I haven’t tried it so I don’t know if it will work or not.  I just switched to mine to the system version “rvm  –default system”

Making a simple app

There is a great tutorial on the wxruby website.  It shows you how all these tools work together to create an application. I created my frame using DialogBlocks.  I created my ruby file using xrcise.  I completed the tutorial.  Now if you forget that wxruby is 32bit only and you just try to run the app, you may see an error like this:

/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle: dlopen(/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle, 9): no suitable image found.  Did find: (LoadError)
/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle: no matching architecture in universal wrapper - /Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wx.rb:12
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:36:in `require'
from main.rb:3

To run the app, you need to run ruby in 32 bit mode like this:

env arch -i386 ruby -rubygems main.rb

Here is the screen shot of my app running on a mac.

Homebrew

I am currently trying out a new package management system called Homebrew.  I am not really sure how it’s any better than MacPorts yet.  I think the only thing I know is that you aren’t forced to download multiple versions of a package if you don’t need to.

http://mxcl.github.com/homebrew/