Thursday, October 7, 2010

Grails Image Processing with the ImageTools Plugin

I recently had a requirement on my side project to add some simple image processing.  I had previously used the ImageTools plugin, but that seems to have falled into a bit of disrepair.  I had a multistep process to get this going, and I figured I'd share it.

According to the git repository, the last checkin on version 1.0.4 was way back in January 2010.  Grabbing the plugin using the standard grails install-plugin as documented on the plugin documentation page just doesn't cut it.  When attempting to use the documentation, you get a message that tells you
unable to resolve class ImageTool @ line xxx, column xxx. def imageTool = new ImageTool();
This is troubling, as that is the only class included in the plugin.  Fortunately I found this comment on a closed (???) issue on github:
So, to solve this I had to run a git clone on this source tree and then follow the instruction at the link below to create my own version of this plugin with correct package.
So it would seem that you need to grab the source, then create a plugin.  This is not as easy as you might think.  First of all, you might not have git installed.  Follow the instructions here to 'git git'.  Next, you need to grab the code.  From the command prompt in the directory you want the code, run the following command:

git clone http://github.com/ricardojmendez/grails-imagetools.git

Now you have the code.  Even though it's a plugin, you have to tell grails it's a plugin, by running the grails create-plugin command.  Now you have a zip file that you can install in your project, using the standard grails install-plugin command.

From there you can follow the instructions.  The import statement is recognized, and we can get finally get down to actually writing the controller code:

import org.grails.plugins.imagetools.*

...

//the controller method we submit to
def myProfileSave = {

...

uploadPhoto( file, user )

...

}

def uploadPhoto( upfile, user ) {

 if(upfile.empty) {
  flash.message = 'File cannot be empty'
  redirect( action: 'myProfile' )
 }

 def imageTool = new ImageTool()

 imageTool.load( upfile.getBytes() )

 // Crops it to a square
 imageTool.square()
 
        //make the new squared image the image to operate on 
 imageTool.swapSource()
  
 // Reduces the image size
 imageTool.thumbnail( 125 )

 def fileBase = grailsApplication.config.imageLocation
 def fullPath = "${fileBase}/user/photo"
        File fullPFile = new File( fullPath )

 if ( !fullPFile.exists() ) {
  fullPFile.mkdirs()
 }
  
 def filePath = "${fullPath}/user_${user.id}_125.jpg"

 File toMake = new File( filePath )

 if ( !toMake.exists() ) {
  toMake.createNewFile()
 }
  
 // Saves the result
 imageTool.writeResult( filePath, "JPEG" )
}

Once you get the plugin working, it's a breeze, as you can see!  It's a great, simple wrapper around the nasty and complicated JAI library.

Some Tips:

1) You'll probably want to increase your heap size if you are running with a default or small heap.  This requires a bit of memory.
2) Remember to specify a multi-part form.  A good explanation of this can be found in the grails documentation.
3) Profit!

Saturday, July 31, 2010

July!

Let's talk about family.  My grandparents are 94 and 92, and still going.  They live by themselves.  They take care of themselves.  They sometimes complain about how badly they are doing, but I can name multiple couples one third of their age who aren't doing as well as they are!  My grandfather has good days and bad, and my grandmother has short-term memory issues, but really all in all, they are both really still rocking.  I talked to them today for half an hour, and afterwards, I was hit smack in the face with one of those 'wow am I blessed to have these people in my life' moments.  They have been married now for more than SEVENTY years.  They are amazing people who have been a part of so much, and who have so many amazing stories.  They are 'unconditional love machines', who just amaze me with their capacity to be proud of and kind to their family.  They are so positive, so caring, and so full of love.  It's really quite refreshing.


Thanks Grandma and Granddaddy for being an inspiration.  We all love you a ton!

Friday, July 2, 2010

UberConf, Days 2+3

After a great day one, we were looking forward to another great, long day, and we weren't disappointed.

Scala for Java Programmers - Day 2 started with a fun Scala workshop by Venkat Subramaniam that spanned two sessions.  This was extremely hands-on, and very worthwhile.  I learned enough about a language I have had interest in for a while to get started on my own, and got a nice little dose of Computer Science and compiler fun too.  My only complaint here was that we spent too much time using closures and Scala syntax craziness to write code in one, perl-ish, unreadable line.  We should have used the time writing 'terse' obfuscated code playing more with Scala parallel programming.  Actors are nifty, and it's amazing how clearly you can express complicated multi-threaded program flow.  If I had access to this goodness, I can think of one project I did at Blackboard that could have been written in half the time, in 1/5 the LOC, and in a much more readable and intuitive way.  Hindsight is 20/20, I suppose, but man that made me burn a bit.

Emergent Design - After lunch, we attended Neal Ford's talk on emergent design.  This was a good talk, mostly because Neal Ford is a good speaker, but I wouldn't say this was anything new.  No big design up front, test first, don't solve problems that don't yet exist, as this leads to heaps of code debt.

Stability Antipatterns - This was a workshop by Michael Nygard about common antipatterns you see as it relates to stability - this was more on the operations and integration level than at the code level, and had a fair amount of good tips for things to remember - mostly how to keep your application from dying because there is an external resource that you don't control that is failing.  Some of the horror stories he shared were hilarious, and some you could totally see happening to you (if they hadn't already).  Good session.  Good reminder of things to consider that often fall by the wayside.

On to Day 3, which was kind of disappointing.

Implementing Domain-Driven Design - I was excited about this one because DDD is one of those things you always hear about, but never really get.  After the session, I still didn't really get what the big deal was - drive the design of your application by the real-world domain.  Seems pretty simple to me.  What wasn't simple was the 100 slides of UML class diagrams the presenter used to demonstrate DDD.  Yikes, not that awesome.

SOLR - A Case Study - This was an interesting enough presentation, as Solr is something that we are evaluating.  I learned enough to know that we didn't really need to do this right away, but not much more.  It wasn't really a case study.  What I would have liked was either, Solr real-world example, or Migrating from Lucene to Solr, but alas we didn't really get either.  It was still a good presentation though, just not what I was looking for.

Android Mobile Development - Gah!  Fail!  This could have been a great way to close things out, but the presenter instead did the presentation completely out of order, gave nobody any opportunities to code, and was just generally all over the place.  I was at least able to use the time to make my way through some of the Android tutorials that Google provides.  Man what a bummer.

Monday, June 21, 2010

Uberconf Impressions, Day 1


Last week a group of us from eCollege attended the Uberconf presentation here in the Denver area.  I figured I'd post a few impressions:

First off - the venue - the Westin in Westminster, CO.  Nice place.  Really awesome food whether you are a vegetarian or a carnivore.  Free drinks all day.  Decent coffee, although the cups were oddly small.  One note to the Westin - people operate better at temperatures higher than 58 degrees.  It was FREAKING COLD in there.

Now on the conference organization.  This was one of the best flows of any conference I've attended.  There weren't too many people working the conference, and it still went well.  Easy registration process, good marketing materials (4GB USB stick - not bad), and two t-shirts I would be super embarrassed about wearing.  Easy to figure out what sessions were coming up and where they were going to be.  One minor nit - it's a developer conference, which means laptops - next time, get more power strips in the rooms, at least for the workshops.

And, finally the important stuff - the sessions (day 1):

Patterns of Modular Architecture - This was not quite what I had hoped.  I was looking for patterns, and instead got a fairly basic explanation of how to make your dependencies fairly one-way and isolated.  Neat I guess?  A decent refresher, but definitely nothing earth-shattering, and the most interesting part was OSGI, which the presenter covered for literally two minutes at the end of the presentation.  It did look promising, though.

Common Antipatterns and how to Avoid Them - This was well presented, but it was still a little light.  Good reminders on some common sense things NOT to do, and some reasonably interesting stuff out there - that this presentation was really hitting home with some of the attendees scared me - some of these were things that just shouldn't be happening now, and they obviously still are!

Architect for Scale - This was a good session - lots of 'things you should be doing when you get to this size/load'.  There were a fair amount of good notes about what was not enough, what was too much, and how to move up without huge disruptions

Automated Deployment with Maven - This was a huge win.  It was a discussion about how to use Maven plugins to streamline and automate the numerous steps that go into releasing a module of code.  With maven, it involves updating poms, branching, integrating, labeling, etc, and many manual steps.  With some of the tips in the presentation, I was able to make a releasable unit this morning in about 10 minutes with the help of some maven doc.  Why were we not doing this!?!?  Oh well - awesome.  Worth the price of the registration itself.

Architecture - Non-functional Requirements - This was more of a 'what goes into architecture' talk, than something specifically about non-functionals, but very interesting nonetheless.  As someone who is headed down that path, it validated much of what I think architecture is about.  There was some great back and forth in this presentation from the presenter of this session and the presenter of the earlier Antipattern session.

Tuesday, June 1, 2010

Grails Wizardry: Mocking all your web services with Grails

Background

At work, we are using EC2 to run capacity tests on our environment, which would normally be pretty trivial, but we are a big SAAS shop with tons and tons of endpoints internally.  Without setting up EVERYTHING in the cloud, we can't really run our tests...or can we?  We would love to use Amazon VPC for EC2, but it requires a fair amount of intervention from your network team.  That will be a great alternative down the road - being able to point back into the internal network to access machines rather than deploying them in the cloud.  So, plan b - Using grails, I was able to mock every single .NET service that our application talks to in about three hours.  Here are the details:

We use SOAP services that return some XML, I simply used Fiddler to see what responses are sent back over the wire for each service, and I was ready to rock.  There are two main pieces to the puzzle:

MarkupBuilders


Generating XML is almost too easy in Groovy.  Using the instructions here, I was able to write some code that spits out some xml based on info passed in.  For instance this sample Grails controller will take a login and company and return an XML document with a user id and company id:


import groovy.xml.MarkupBuilder

class UserController {

  /**
  * /MyService/users/getuser?login=myuser&company=mycompany
  */
  def returnUser = {

        def user = params.login
        def comp = params.company

        def writer = new StringWriter()
        def xml = getXMLBuilder( writer )

        xml.'user'('xmlns:xsi': getNsXsi(), 'xmlns:xsd': getXsd(), 'xmlns': getXmlNs() ) {
          userId( "${comp }@${user}" )
          compId( "${comp}@compId" )
        }

        render( text: writer.toString(), contentType:"text/xml", encoding:"UTF-8" )
  }

  def getXMLBuilder( StringWriter writer ) {

        writer.append(  "" )

        return new MarkupBuilder( writer )
  }

  def getNsXsi() {
        return "http://www.w3.org/2001/XMLSchema-instance"
  }

  def getXsd() {
        return "http://www.w3.org/2001/XMLSchema"
  }

  def getXmlNs() {
        return "http://yourcompany.com/UserStuff/2009/11/01"
  }
}


Now that you have defined your controller, you need to make it so your application can make its normal request to the url it has configured but still get to your controller.  That's where the URLMappings.groovy class comes in:

UrlMappings

The UrlMappings file already exists by default when creating a project.  This file is built to map external urls to your controllers - you can use it to create nice shiny RESTful URLs, or just to do some utilitarian mappings for backwards compatibility, etc.  Obviously not every project's requirements map to the grails conventions on how urls map to controllers.  To add access to your controller from a different url, you just need to add the following snippet - this will allow Grails to map your request from something like

/MyService/users/getuser?login=me&company=acme

to

/user?login=me&company=acme 


    "/MyService/users/getuser" {
          controller = "user"
          action = "returnUser"
    }


More information can be found at this link.

At this point, you have a service running that will return the valid XML for your service, and will respond to a call at a URL that doesn't actually match.  Now you can rinse and repeat for each service that you need to mock out.  Happy Grailing!

Wednesday, April 28, 2010

PowerMock - Mocking Statics - Supplemental Documentation

I have recently suffered through a bit of pain working with PowerMock.  It seemed extremely promising, as it sits on top of EasyMock, which we use for mock objects in our unit tests (it also works with Mockito, apparently), and promises to give you the tools to mock those pesky static calls that kill testability.  I had a few issues getting started, and they centered around jUnit 3.

PowerMock with jUnit 3

All the examples and documentation seem to be based on jUnit 4. This page has great examples on how to run your static mocking tests when running on jUnit 4, but how to do it on jUnit 3??  An extremely simple example of how to do this in jUnit 4 is here:


@RunWith(PowerMockRunner.class)
public class AwesomeTest {

  @PrepareForTest(StaticClass.class)
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    //test some stuff!
  }
}


To accomplish the same thing in jUnit 3, without the annotation support, you can do this:



public class MyPowerMockSuite extends PowerMockSuite {

  public static TestSuite suite() throws Exception {
  
    return new PowerMockSuite(AwesomeTest.class);
  }
 
  public static void main(String[] args) throws Exception {
  
    junit.textui.TestRunner.run( suite() );
  }  
}

public class AwesomeTest {

  @PrepareForTest(StaticClass.class)
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    //test some stuff!
  }
}



PowerMock and Multiple Classes

To mock methods from multiple classes, you will need to amend the '@PrepareForTest' annotation, just passing a string array like so:



public class MyPowerMockSuite extends PowerMockSuite {

  public static TestSuite suite() throws Exception {
  
    return new PowerMockSuite(AwesomeTest.class);
  }
 
  public static void main(String[] args) throws Exception {
  
    junit.textui.TestRunner.run( suite() );
  }  
}

public class AwesomeTest {

  @PrepareForTest({StaticClass.class,StaticClassier.class})
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    PowerMock.mockStatic(StaticClassier.class);

    expect( StaticClassier.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClassier.class );

    //test some stuff!
  }
}


Gotchas

PowerMock 1.3.7 only works with EasyMock 2.5.2, which we have had some issues with.  I had to move back to PowerMock 1.2.5 to use EasyMock 2.4.  I didn't find a lot of issues with using this version, though we had some odd calls that were required where it told me not to stub a return when the method returned something, or where I had to stub out calls that didn't seem like they should be required.  With a simple static method that didn't really call many other static methods, it seems to work like a charm.

Wednesday, April 14, 2010

How Five Guys Got Big...by being Awesome

About once a month when I was young (late 80s into the 90s), my dad and I went to this ratty little burger shop to get the most delicious burgers and out of this world fries at a place called 'Five Guys'.  The people were always friendly, and the order was always perfect.  It was no frills but they promised delicious burgers and fries, and it's what they delivered, without exception.

Fast forward to today, and Five Guys is EVERYWHERE.  It's growing in leaps and bounds - they even have them here in Colorado, with 400 to come in California!  Read the story in Inc. Magazine about how they got here.  You can really learn a lot from the way this business is run.

In an age when we understand that eating burgers and fries is not good for you, if you are going to do it, don't do it at McDonald's.  Go get something worth splurging on.