Wednesday, September 26, 2012

Grails, GORM, lazy loading one-to-one

I spent all yesterday evening trying to figure out a way to lazy load a one-to-one relationship. At first glace, this probably looks like an academic exercise. However, I have a very pragmatic reason for needing to lazy load a one-to-one relationship.

I have Property and PropertyDetail Domain Classes. 

For now, I am storing images in the database.

Long-term, I am going to look at using Amazon S3 for storing images, but for a personal project where I am still learning, it seems like a decent compromise.

class PropertyDetail {

    static constraints = {
        description type: 'text'
    }

    static belongsTo = [property : Property]

    String description
    byte[] imageMain
    byte[] image1
    byte[] image2
    byte[] image3
    byte[] image4
    byte[] image5
}

I am going to have a list page for Property domain class.

I definitely do not want to take the hit of pulling the PropertyDetail class, not with the images stored in the database.

I hit a wall late evening, when I discovered the following Jira Issue: GRAILS-5077 hasOne mapping is by default eager and cannot be changed to lazy.

However, this is an older JIRA issue, and I did see on the recent Grails 2.1.1 documentation information on doing lazy one-to-one. http://grails.org/doc/latest/guide/GORM.html#manyToOneAndOneToOne

My new plan is to:

  1. Try the approach documented for Grails 2.1.1.
  2. Turn on SQL logging
        datasource { 
            ... 
            logSql = true 
        } 
    

  3. If that does not work, drop back and remap this relationship as a many-to-one.

Saturday, September 15, 2012

Adventures with Grails and Spring Security

Well, I had initially started down the path of creating my own User/Role security model for a Grails App I am building at home in the evenings/weekends.

However, I gave it a little more thought and going back to the "why re-invent the wheel" philosophy of development and just started looking into leveraging Grails Spring Security Plugin.

Found this great article on quick start with Spring Security: http://sysgears.com/articles/spring-security-grails-plugin-quick-start-and-some-tips

Here's what I've done thus far:

1. Modify my BuildConfig.groovy to include Spring Security:


    plugins {
        build ":tomcat:$grailsVersion"
        compile ":spring-security-core:1.2.7.3"
        compile ":twitter-bootstrap:2.1.1"
        compile ":resources:1.1.6"
        runtime ":hibernate:$grailsVersion"
    }

2.Run s2-quickstart:

    s2-quickstart com.philiptenn.security User Role Requestmap

3. Refactored the generated Controllers LoginController and LogoutController so that they are in the com.philiptenn.security package. 

4. Customized Password algorithm to SHA-512:

grails.plugins.springsecurity.password.algorithm='SHA-512'

I feel like this is just scratching the surface. I ended up running into questions and needed to post on StackOverflow: Grails Spring Security Custom UserDetailsService (goal of email in place of username).

Monday, September 10, 2012

Technology Stack

It's late Monday evening, and I'm working on a new personal development project. 

I think I've selected my technology stack:
  • Twitter Bootstrap 2.1.1
  • Grails 2.1.0
  • MySQL 5.5
I find Grails to be rather amazing because it is, for all intents and purposes, a complete stack.  It even has a Twitter Bootstrap plug-in, as well as MySQL Connector/J plug-in, so I guess I could technically say that my technology stack is "Grails".

When working on Java / Java EE projects, I've grown so accustomed to saying "My technology stack is jQuery/JSP/Taglib/Struts/EJB3/Spring/Hibernate/Oracle". 

It feels pretty neat to say "My technology stack is Grails". 

Since I am looking at eventually hosting in a PaaS environment, I am not really concerned about details like OS and Application Server.

However, for my own development environment I am using the following:
  • Windows 7 (thought about switching to Fedora 17 KDE, decided not to take hit on installing a whole new OS).
  • Tomcat 7.0.30
I've made the mistake in working on past personal projects during nights/weekends and getting too caught up in technical details and not focused enough on building a product. 

Grails BuildConfig.groovy: dependencies vs plugins

I am configuring BuildConfig.groovy for a test/sample project.

One item I have always found a bit confusing is the question of the dependencies closure block vs the plugins closure block.

There are times where I have seen that a library could be specified in either.  Also, the version of library would be different.  

For example, the following dependencies closure is provided out of the box with Grails 2.1.0:

    dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        // runtime 'mysql:mysql-connector-java:5.1.20'
    }

Obviously, this leads me to conclude that if I need MySQL Connector/J support, all I have to do is uncomment that line.

However, I have also successfully gotten MySQL Connector/J support by doing the following (I have verified this works):


    plugins {
        compile ":mysql-connectorj:5.1.12"
        compile ":searchable:0.6.3"
        build ":tomcat:$grailsVersion"
        build ":hibernate:$grailsVersion"
        runtime ":database-migration:1.1"

    }

I found the following Nabble post from Graeme Rocher explaining the difference of plugins {} vs dependencies {} blocks

Graeme states:

plugins { } block is used declare dependencies on grails plugins found
in the portal (http://grails.org/plugins/) and built locally.

dependencies { } block is used to declare dependencies on JAR files
and third party java libraries typically found in Maven central (see
http://search.maven.org/#browse)


This made sense to me.  What it did not answer is when I am able to obtain a library via either, which is preferable, if there is a "best practices" or "recommended" approach. 

Knowing that I can get my MySQL Connector/J library from either one (I am certain I would not want to do both), I would just be curious as to which approach is better.

Wednesday, August 22, 2012

Grails, Scaffolding, GSPs

I've spent the last few evenings reading up on Grails Domain Classes and Controllers, the 'M' and 'C' portions of MVC, respectively.

I have been working through Getting Started with Grails, Second Edition by Scott Davis and Jason Rudolph

Throughout the process of working through their Racetrack sample application, I have been switching between MongoDB 2.0.6 and MySQL 5.5.25. 

In the process, I have hit some bumps in the road regarding MongoDB Issues with Grails Scaffolding that do not occur in MySQL

I posted these on StackOverflow and mentioned in LinkedIn discussions.  This has led me down the path of going so far as to trying to download a tag from GitHub for newer builds of the MongoDB Plugin for Grails (as of today 2012-08-22, 1.0.0.GA is the latest official release for this plug-in).

I've also learned a lot about MySQL in the process of setting it up, securing it on Fedora 17. 

Neat things I've learned:

Now, I'm starting to learn about the 'V' aspect of MVC in Grails.  I am digging into GSPs. 

Wednesday, August 15, 2012

MySQL on Fedora 17 and Grails

I was running into some strange behavior when writing a test Grails Application that uses MongoDB (MongoDB 2.0.6-2.fc17 installed via YUM) for storage.

Specifically, when I use scaffolding, I am unable to reorder the fields using the static constraints block.

I saw this mentioned on a post in the Nabble forum for Grails, alluding to this possibly being a problem with MongoDB.  However, I was not able to find any more information on scaffold field ordering via static constraints not working for MongoDB.

In order to run this down further, I decided to take my same test application and run it using MySQL for storage.  I haven't used MySQL for years, so it took a little to get re-acclimated.

  1. Quick check for MySQL on the Fedora 17 server:
    # yum list mysql
    Loaded plugins: langpacks, presto, refresh-packagekit
    Installed Packages
    mysql.x86_64                       5.5.25a-1.fc17                       @updates
    Available Packages
    mysql.i686                         5.5.25a-1.fc17                       updates
    

    Yay, it's already installed. Looks like it shipped with 5.5.25a-1, a specific build for FC17.

  2. Enable the Service upon startup:
    # systemctl enable mysqld.service
    

  3. Secure it:
    # mysqladmin -u root password ********
    

  4. Enable remote connections from development machine for administration.
    # mysql -u root -p mysql
    mysql> GRANT ALL PRIVILEGES ON *.* TO root@'DEV_MACHINE_HOSTNAME' IDENTIFIED BY ********;
    
    Also, I opened up port 3306 through the firewall on the FC17 server.

  5. Next, I logged in via MySQL Client and ran Create Database, Create User,  and Grant All to create a new Database for my Grails Application, create a User for this Database, and Grant all privileges to that User for the newly-created database.
  6. Finally, I changed my Grails App Plugins (removed mongodb, installed mysql-connectorj-5.1.12 and hibernate-2.1.0) and updated DataSource.groovy:
    dataSource {
        pooled = true
        driverClassName = "com.mysql.jdbc.Driver"
        dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
        username = "racetrack"
        password = "********"
    }
    hibernate {
        cache.use_second_level_cache = true
        cache.use_query_cache = true
        cache.provider_class = "net.sf.ehcache.hibernate.EhCacheProvider"
    }
    
    // environment specific settings
    environments {
        development {
          dataSource {
             dbCreate = "create-drop" // one of 'create', 'create-drop','update'
             url = "jdbc:mysql://ptenn:3306/racetrack"
          }
       }
       test {
          dataSource {
             dbCreate = "create"
             url = "jdbc:mysql://ptenn:3306/racetrack"
          }
       }
       production {
          dataSource {
             dbCreate = "update"
             url = "jdbc:mysql://ptenn:3306/racetrack"
          }
       }
    }
    

Monday, August 13, 2012

Fedora transition: SysVinit to Systemd

I installed Fedora 17 on a Linux Server (previously had been working with Fedora 14), and ran across a surprise.

Apparently, Fedora is transitioning from SysVinit to Systemd: Fedora features/systemd

I realized something was amiss when attempting to set runlevels for 2 services: sshd and mongod.

I ran the following commands:

# chkconfig sshd on
# chkconfig mongod on

and proceeded to reboot the server.

My understanding is that these commands should turn runlevels 2, 3, 4, 5 on for both sshd and mongod services.

When I restarted, I was able to verify via testing that these 2 services came up as expected.

However, when I went to run:
# chkconfig --list

These services did not appear in the list.

After doing some more research, I found the following guide: Fedora SysVinit to Systemd Cheatsheet.

Ran the new equivalent of chkconfig --list:

# ls /etc/systemd/system/*.wants

...

/etc/systemd/system/multi-user.target.wants:
abrt-ccpp.service     chronyd.service         nfs-lock.service
abrtd.service         crond.service           remote-fs.target
abrt-oops.service     cups.path               rpcbind.service
abrt-vmcore.service   irqbalance.service      rsyslog.service
acpid.service         mcelog.service          sendmail.service
arp-ethers.service    mdmonitor.service       smartd.service
atd.service           mongod.service          sm-client.service
auditd.service        multipathd.service      sshd.service
avahi-daemon.service  NetworkManager.service

...
and saw my sshd.service and mongod.service as expected.
It will take some time to get used to this new syntax for systemd ... so used to chkconfig and service.

Wednesday, August 8, 2012

Grails and MongoDB: Setup

I am attempting to create a sample Grails project that uses MongoDB for persistent store. 

I've learned a lot about Grails Plugins while trying to build a simple Grails App with MongoDB.

First stop was this blog post on MongoDB titled "Grails in the Land of MongoDB".

My blog post is based on this posting from MongoDB, with additional notes and information that I discovered while following these steps. 
The blog post "Grails in the Land of MongoDB" listed steps as follows:

Step 1: Remove the hibernate dependency from the BuildConfig.groovy file.

This wasn't as straightforward as I thought.  I am using Grails 2.1.0.  After I ran the command:

grails create-app doctor

I opened up the BuildConfig.groovy file.  It had the following plugins:

    
plugins {
        runtime ":hibernate:$grailsVersion"
        runtime ":jquery:1.7.2"
        runtime ":resources:1.1.6"

        // Uncomment these (or add new ones) to enable additional resources capabilities
        //runtime ":zipped-resources:1.0"
        //runtime ":cached-resources:1.0"
        //runtime ":yui-minify-resources:0.1.4"

        build ":tomcat:$grailsVersion"

        runtime ":database-migration:1.1"

        compile ':cache:1.0.0'
    }

I removed the entries for Hibernate and Database Migration

After making these changes, my plugins section of BuildConfig.groovy appeared as follows:

    
    plugins {
        runtime ":jquery:1.7.2"
        runtime ":resources:1.1.6"

        // Uncomment these (or add new ones) to enable additional resources capabilities
        //runtime ":zipped-resources:1.0"
        //runtime ":cached-resources:1.0"
        //runtime ":yui-minify-resources:0.1.4"

        build ":tomcat:$grailsVersion"

        compile ':cache:1.0.0'
    }

Step 2:Install the MongoDB GORM
I ran the command:

grails install-plugin mongodb

This did the following (as far as I can tell): 



  1. Added an entry to my application.properties: plugins.mongodb=1.0.0.GA
  2. Created the directory projects/doctor/plugins/mongodb-1.0.0.GA in my .grails directory.
Step 3:Edit DataSource.groovy to specify connection settings
There was a slight typo in the MongoDB blog. The port should actually be 27017.

grails { 
  mongo { 
    host = "localhost"
    port = 27017 
    username = "doctorUser"
    password="medicine"
    databaseName = "doctors"
  } 
}

Thursday, July 26, 2012

Cloud Foundry, Micro Cloud Foundry, VMX

As part of my exploration into NoSQL and MongoDB, I have been exploring CloudFoundry. 

I first learned about CloudFoundry during SpringOne 2GX 2011 last October in Chicago

We received flash drives with the Micro Cloud Foundry on it, but I was way too busy with work at the time to give it much thought. 

However, as I started looking for Cloud Hosting and PaaS that supports MongoDB, I realized that CloudFoundry supports MongoDB. 

Registered here: http://my.cloudfoundry.com/signup and received an email with my credentials.  One thing that struck me as odd was that when I signed in, I was unable to change my password from the randomly generated one.

Oh, well, I proceeded to download Micro Cloud Foundry. I also set up VMX and am able to remotely connect to CloudFoundry.

ruby 1.9.3p194 (2012-04-20) [i386-mingw32]

C:\>gem install vmc
Fetching: json_pure-1.6.7.gem (100%)
Fetching: rubyzip-0.9.9.gem (100%)
Fetching: mime-types-1.19.gem (100%)
Fetching: rest-client-1.6.7.gem (100%)
Fetching: terminal-table-1.4.5.gem (100%)
Fetching: interact-0.4.5.gem (100%)
Fetching: addressable-2.2.8.gem (100%)
Fetching: uuidtools-2.1.3.gem (100%)
Fetching: rb-readline-0.4.2.gem (100%)
Fetching: vmc-0.3.18.gem (100%)
Successfully installed json_pure-1.6.7
Successfully installed rubyzip-0.9.9
Successfully installed mime-types-1.19
Successfully installed rest-client-1.6.7
Successfully installed terminal-table-1.4.5
Successfully installed interact-0.4.5
Successfully installed addressable-2.2.8
Successfully installed uuidtools-2.1.3
Successfully installed rb-readline-0.4.2
Successfully installed vmc-0.3.18
10 gems installed
Installing ri documentation for json_pure-1.6.7...
Installing ri documentation for rubyzip-0.9.9...
Installing ri documentation for mime-types-1.19...
Installing ri documentation for rest-client-1.6.7...
Installing ri documentation for terminal-table-1.4.5...
Installing ri documentation for interact-0.4.5...
Installing ri documentation for addressable-2.2.8...
Installing ri documentation for uuidtools-2.1.3...
Installing ri documentation for rb-readline-0.4.2...
Installing ri documentation for vmc-0.3.18...
Installing RDoc documentation for json_pure-1.6.7...
Installing RDoc documentation for rubyzip-0.9.9...
Installing RDoc documentation for mime-types-1.19...
Installing RDoc documentation for rest-client-1.6.7...
Installing RDoc documentation for terminal-table-1.4.5...
Installing RDoc documentation for interact-0.4.5...
Installing RDoc documentation for addressable-2.2.8...
Installing RDoc documentation for uuidtools-2.1.3...
Installing RDoc documentation for rb-readline-0.4.2...
Installing RDoc documentation for vmc-0.3.18...

C:\>vmc
Usage: vmc [options] command [<args>] [command_options]
Try 'vmc help [command]' or 'vmc help options' for more information.


C:\>vmc target

[http://api.vcap.me]


C:\>vmc target api.cloudfoundry.com
Successfully targeted to [http://api.cloudfoundry.com]


C:\>vmc login
Attempting login to [http://api.cloudfoundry.com]
Email: ********
Password: ********
Successfully logged into [http://api.cloudfoundry.com]

Friday, July 13, 2012

NoSQL, BigTable, and data stores

I've started reading a lot about NoSQL Databases and it fascinates me, especially as a developer who has grown up in the Relational Database world (Oracle and SQL Server) and spent a lot of time optimizing queries, working on complex SQL statements, normalizing tables, inner joins, left outer joins, inline views, and all that good stuff.

Over time, I've watched the evolution from the Data Tier of the n-tiered model go from DAOs that executed JDBC to ORM (been doing a lot of Hibernate and NHibernate) to Grails/GORM (which provides a ton of create/read/update/delete methods automatically, freeing the developer from having to maintain this code). 

I have read articles about how companies that work with extremely large volumes of data like Google have developed distributed, non-relational data stores such as BigTable.  When I was playing with Google App Engine was my first exposure to BigTable, and it was a bit of culture shock for a developer who is used to the traditional RDBMS model present in most corporate environments (at least every environment I have worked in since I started in industry in 1998). 

BigTable and the problem it was created to address fascinated me.  However, I really couldn't get into Google App Engine.  At the time, it was purely Python/Django, though it has since been expanded out to include Java.  I did write several Python scripts and built a few pages in Django, but found it to be an uncomfortable fit for someone comfortable with writing Java in IntelliJ or C# in Visual Studio .NET. 

Recently I have been reading about the NoSQL movement.  I am going to pull down MongoDB and give it a try.  I was glad to read that Grails has a MondoDB plugin.