m i k e b r e v o o r t

life technology cycling etc

m i k e  b r e v o o r t header image 1

Definitive Guide to Grails, Second Edition

January 21st, 2009 · No Comments

Today I received my pre-ordered copy of the Definitive Guide to Grails, Second Edition. This is the first book I’ve ever pre-ordered on from Amazon. The book seems to be a total rewrite of the first edition and is much thicker as well.

Grails has changed significantly since 0.4 (the version the first edition was based); the new book is based on Grails 1.1 that ’s scheduled to be released of beta within a number or weeks. I’m knee deep in a project now that’s using Grails 1.1 beta2 so this book is very timely!

Though I haven’t read much of the book yet the first thing I noticed was testing is address throughout the entire book, generally near the end of each chapter, demonstrating how to test the features covered in each chapter.  This is fantastic!  Also, I read the chapter on URL Mapping (since my new application relies heavily on custom URL Mappings and I’ve battled through several Grails 1.1 beta bugs) and the material was comprehensive.  So my early impression of this book is very good; it appears to be very thorough and a significant contribution to the Grails community that was much needed. Excellent work Graeme and Jeff.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ No CommentsTags: Grails

Making Relative URLs Absolute with Groovy

December 21st, 2008 · Comments Off

I’m working on a project where I am using Grails as a content delivery layer for an XML based content management system.  The content management system has the ability to publish XHTML content with inline links and images; however the inline img and a tags reference the content as relative paths.  I need the links to internal pages to be absolute from the server root (ie /sub/content.html rather than sub/content.html) and I am hosting all static content like images at Amazon S3 so I need the image links to be absolute to a different DNS name (ie http://media.mywebsite.com/images/image.jpg rather than images/image.jpg).

Instead of implementing some hacks in the CMS itself, I opted to do the transformation in Grails as the content was rendered allowing greater flexibility.  I created a taglib for rendering the XHTML block that does a Groovy replaceAll with regular expressions.  The tag gets called like this: <g:processXHTML content=”${content.mainBody.text()}”/> .  My GSP has reference to a content variable that is an XMLSlurped xml document with a mainBody tag.  Here is the code for the tag:

/**
 * Given XHTML content will return the same content with any relative a tag hrefs prefixed with a /
 * and any relative images prefixed with the mediaURL
 */

def processIngeniuxXHTML = {attrs ->
  def content = attrs.content
  def rootURL = grailsApplication.config.mediaURL

  if (content) {
    // first look for links within the content that are relative URLS and prefix with a slash so they are
    // resolved from the root rather than the current context
    def regex = /(< \s*a\s+[^>]*href\s*=\s*[\"'])(?!http)([^\"'>]+)[\"'>]/
    def replace = { fullMatch, a, b ->
      if (b[0] != "/"){
        // for some reason it's not outputing the closing quote so I added it at then end explicitly
        "${a}/${b}\""
      } else
        "${fullMatch}"
    }

    content = content.replaceAll(regex, replace)

    // second if there are any images referenced with relative URLs, prefix with the DNS for the S3 bucket
    regex = /(< \s*img\s+[^>]*src\s*=\s*[\"'])(?!http)([^\"'>]+)[\"'>]/
    replace = { fullMatch, a, b ->
      if (b[0] != "/"){
        // for some reason it's not outputing the closing quote so I added it at then end explicitly
        "${a}${rootURL}/${b}\""
      } else
        "${fullMatch}"
    }

    out < < content.replaceAll(regex, replace)
  }
}

And here are the test conditions to demonstrate what’s expected:

void testProcessXHTML() {
  ContentUtilTagLib tl = new ContentUtilTagLib()

  def i = """<div><a href="Explore/test"/>"""
  def o = """<div><a href="/Explore/test"/></div>"""

  tl.processXHTML(content: i)
  assertEquals o, out.toString()
  out.getBuffer().setLength(0)

  i = """<div><a alt="blah" href="Explore/test"/></div>"""
  o = """<div><a alt="blah" href="/Explore/test"/></div>"""

  tl.processXHTML(content: i)
  assertEquals o, out.toString()
  out.getBuffer().setLength(0)

  i = """<div><a href="Explore/test"/><img width="100" src="myImage/a.jpg"/></div>"""
  o = """<div><a href="/Explore/test"/><img width="100" src="http://stub/myImage/a.jpg"/></div>"""

  tl.processXHTML(content: i)
  assertEquals o, out.toString()
  out.getBuffer().setLength(0)

  i = """<div><a href="/Explore/test"/></div>"""
  o = """<div><a href="/Explore/test"/></div>"""

  tl.processXHTML(content: i)
  assertEquals o, out.toString()
  out.getBuffer().setLength(0)

  i = """<div><a href="http://Explore/test"/><img width="100" src="http://anotherhost/myImage/a.jpg"/></div>"""
  o = """<div><a href="http://Explore/test"/><img width="100" src="http://anotherhost/myImage/a.jpg"/></div>"""

  tl.processXHTML(content: i)
  assertEquals o, out.toString()
  out.getBuffer().setLength(0)

}

More related to this project to come…

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

Comments OffTags: Grails · Technology · code

NFJS Rocky Mountain Software Symposium Debrief

November 17th, 2008 · No Comments

This weekend I attended the NFJS Rocky Mountain Software Symposium in Lone Tree, CO.  It was hard to pass up a NFJS conference that’s 15 minutes from home.  Overall the sessions were excellent.  There wasn’t a single session I attended that sucked or was a waste of time, a first for any conference I’ve attended.  I seemed to gravitate toward sessions by Ken Sipe and Stu Halloway followed by Groovy and Grails presentations by Jeff Brown and Scott Davis.

I gleaned several consistent overarching themes at the conference:

  • Java is essentially Dead (Stu Halloway leading this sentiment)
  • BUT the JVM is alive and well.  In fact the JVM has transitioned from a write once run Java anywhere runtime to a dynamic platform for many languages (Groovy, JRudy, Scala, Clojure, Javascript, etc…. oh yeah and Java)
  • Not doing Test Driven Development is basically irresponsible, especially with the explosion of dynamic languages
  • Not doing Continuous Integration is basically irresponsible

I learned the Jeff Brown has developed and is about to announce a new Hudson plugin for building Grails projects in Hudson, a big and welcome improvement on specifying new ant targets, using the shell script option or whatever.  Jeff also echoed much of what has already been said about the recent Spring Source acquisition of G2:

  • Deeper integration between Grails and Sprint MVC
  • The Groovy Spring bean builder will be moved into Spring
  • And of course there will be closer collaboration between the Groovy, Grails, and Spring development teams, though the team will remain distinct.

I’m super excited about Git though Matt McCullough urged me to take a look at Mercurial

Anyway, fantastic event and kudos to No Fluff Just Stuff.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ No CommentsTags: Grails · Technology

Rocky Mountain Software Symposium

November 14th, 2008 · 1 Comment

This weekend I’m attending the NFJS Rocky Mountain Software Symposium.  Today I attended a few really good sessions specifically Java Memory, Performance and the Garbage Collector presented by Ken Sipe and a very enthusiastic Groovy Metaprogramming tour by Scott Davis.  Though I’ve been using Groovy for quite a while, primarily inconjuction with Grails, Scott’s presentation really helped fill some gaps for me.   Ken’s presentation on JVM memory managemant was a great primer.  I’m looking forward to profiling a few of the Grails apps I’m working on vith VisualVM to see how I can optimize New vs Old space as well as preset the PermGen space to speed up Grails start-up.

I’m looking forward to the coming two days of sessions though I REALLY could have used a weekend.  At least the conference is 15 minutes from home.  I’ll post my thoughts/reactions to the other session this weekend.

After a nudging from Ken during his presentation to ‘increase your digital footprint’ and Cannon-Brookes return to blogging (congrats on your recent position on the Gartner Magic Quadrant for Social Software - well deserved…) I’m renewing my commitment to start blogging again and this time more focused on my “work” life, choosing to use Facebook for sharing personal updates.

Congrats to G2 for the Spring Source aquisition and the release today of Grails 1.0.4.  And I just saw that the Groovy/Grails Experience has been scheduled for February 2009… in Denver!

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 1 CommentTags: Grails · Technology

Active Directory Authentication Part II

September 27th, 2008 · 3 Comments

This is a long overdue follow-up to my Active Directory Authentication post. I had all the best intentions of quickly following this post up with a second post so this is long overdue. It’s been just over a year though so there are lots of cobwebs so this is going to be a stream of consciousness dump…

First, there are two books that I found indespensible and the best resources I could find for detailed information about integrating with Active Directory and Windows security. The LogonUser and SSPI approach I mentioned in my first post a year ago originated from these books.

In an effort to just get some follow-up out there since I tend to get regular inquiries about my original post, Here’s a zip file of some sanitized code that includes the code for LogonUser, SSPI and a few other classes I used.
In the end I settled on LogonUser which seemed to give the best overall performance in a very decentralized, many sub-domain environment. There were also less anomalies as well. When using SSPI I found that if typical authentication took 140ms, some calls were taking 60.140s and 120.140s in one or two domains. This was rare and most likely a result of some sort of timeout and retry or fallback to another domain controller. I was not able to identify the root cause.

One side note regarding the LogonUse API. When the authentication type is set to “LOGON32 LOGON NETWORK” the LastLogon and LastLogonTimeStamp attributes on the domain controllers are not updated when authentication occurs. If you have any logic that relies on these attributes (For example if you to run a script against AD to check for user account inactivity), change the authentication type to “LOGON32 LOGON INTERACTIVE” to have these attributes updated as expected.

Lastly to test the differences between the three authentication types, I created a method to log detailed information about each authentication attempt including: elapsed time, samAccountName, domain, authentication result, user ip, domain server authenticated against (if I could figure it out), authentication web server. Without going into too much detail, I logged this info into a row in a database table on each attempt (this also inherently created a great resource for security auditing). This way I could query the data very easily to roll-up statistics based on which domain, what server, the IP subnet of the user, particular users, etc. Key to this though was to avoid any additional latency on the authentication request or a database dependency on the success of the authentication request, I created a BlockingQueue that waited for a log message to be placed on the queue and inserted it into the database. This happened out of band in another thread and if there was some failure, the queue would just continue to grow until the problem was resolved. This was very effective in measuring the performance of these different authentication methods.

Feel free to comment with any questions, I’ll do my best to recollect.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 3 CommentsTags: Technology · code

Still Breathing

September 26th, 2008 · 1 Comment

Yep, still here… baby #3 is less than a month out, Luke’s birthday was today, family is awesome.

Work is getting busy; after laying low for several months I’m looking forward to get into some new stuff. In the coming months I plan to blog about some of what I’m doing with Grails, Flex and possibly Alfresco.

For Lance Armstrong and fixed gear fans, check this out: http://www.mashsf.com/

More soon…

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 1 CommentTags: Personal

Back in the Saddle… Again

July 27th, 2008 · 1 Comment

It’s been a busy summer already. My riding fell off completely as we went through the whole buy/sell/move process and then my entire family came to stay for a weeks. It was a really good to see everyone, but now we’re ramping up for Jeanie’s Family’s ‘Wild West’ reunion next weekend.

I finally put together a string of good rides the last three days, spending about 8 hours on the bike. I got my cross bike back in action and road some of the local trails at Query Mesa and Memmen Ridge. The Memmen ridge stuff was just cut last weekend and though it is short (2 - 2.5mi total), it’s going to be a real treat in riding distance from the house.

Here’s my cross bike with ugly saddle courtesy of Marc many years ago (Joseph gets credit for the courtesy hold):

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 1 CommentTags: Uncategorized

1991 - One Let it Ride

June 27th, 2008 · 2 Comments

I hooked up the old VCR to the computer today and started going through some old tapes. This clip is from around 1991 and was part of a video that Marc and I created. Man those glasses were huuuugh!



Mike - One Let it Ride (circa 1991ish) from mbrevoort on Vimeo.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 2 CommentsTags: Cycling · Personal

Amazing Feats of Human Strength

June 13th, 2008 · No Comments

Good luck to Chris and Dave as they depart at noon local time from Banff for the Great Divide Race! Dave is trying to be the first to finish on a fixed gear mountain bike and Chris is shooting to break the single speed record (22 days and 3hrs). Now most times when it comes to events like this I figure if I was focused and could dedicate the time to prepare, I’d have a shot. Not so much with the GDR. 2,490 miles and over 200,000 ft of climbing all self supported… this sort of thing ain’t my bag, baby.

You can follow Chris’ progress here and the coolest is you can track his near-live location!

Anyone still looking for a Father’s day gift, may I suggest a donation and an e-card from St Jude Children’s Research Hospital?

God speed Chris and Dave…

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ No CommentsTags: Cycling

Lunch Run

June 9th, 2008 · 2 Comments

Getting settled in the new house. I got out for a lunch time ride today. This is a view from the new trail at the Ryolite Park across from my house; Pikes Peak in the background. Beautiful day…

View from Ryolite Park

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Furl
  • DZone

→ 2 CommentsTags: Cycling · Personal