Showing posts with label GAE. Show all posts
Showing posts with label GAE. Show all posts

Tuesday, September 6, 2011

Spring Roo 1.2.0 with GWT and Google App Engine

I was first introduced to Spring Roo at Google IO 2010 and I was amazed with the product, it allowed a developer to prototype an application very quickly, building everything from the server, domain, and GWT client.  It looked awesome.

When I got home I realised that we were shown a fixed demo in that many of the features didn't really work when building on Google App Engine and Google Web Toolkit.  Not a problem as all developers know we are used to living on the cutting alpha-beta edge of software where great new features come with one huge caveat, they occasionally don't work.

That was then and this is now.  Like Sushi which I try every 6 months just to confirm that I still am not a huge fan, it doesn't taste of anything right?, I try the latest version of Spring Roo.

The Upgrade Path
Let me just say that I love SpringSource they provide a lot of excellent tools for the Java developer and the Spring Roo documentation is no exception.  The upgrade path is very easy, unpack the latest Spring Roo to a directory of your choosing, amend your $ROO_HOME variable in .profile (Mac OSx) and then re-establish the symbolic link to the roo command line.  (sudo ln -s $ROO_HOME/bin/roo.sh /usr/bin/roo)

Done and done!

The Bleeding Edge
So I tried Spring Roo 1.1.5 and it was giving me lots of errors with trying a GWT-GAE project.  It seemed as equally unreliable as I had tried with previous versions.  Let me just add if you are using a standard database such as MySQL or any of the other persistence options, I believe Spring Roo works just fine.  The problems I usually run into are related to the peculiarities of Google App Engine and how Roo handles those.

Since most of my current projects are currently in the GAE-GWT sphere and Roo advertises that it is suppose to work in this area, I decided to upgrade to the very latest Spring Roo, so I delved into the nightly builds and installed (1.2.0.BUILD-SNAPSHOT [rev 176e407]).

Go for 1.2.0 Its Much Better
After building a couple of projects with 1.2.0 I can honestly say this is the best version yet by far.  Why?  Well it appears to work this time for GWT-GAE projects.  Most of my personal work is done on Google App Engine.  This might change as I am not really liking the new billing restrictions but we will see how those actually plan out when implemented.

I typically build small projects that utilise some sort of reference between domain objects and then build a GWT project and then test it to see if it actually works.  I will deal with deployment in a different post.  What is great about Roo is that you can amend say the domain objects and the auto UI will get updated automatically.  Simply add the line : private String userName; : to your domain object, boot up Roo and it auto creates the UI amendments needed.  Pretty stunning.  I haven't yet got to work out how you prevent it from doing this should you want to improve the UI, but I am sure that will come soon.

The project I have built it is that for a taxi company to take bookings.  It includes three domain objects Contact, Booking and Journey.    A booking can have one or more contacts, and one ore more journeys.

A Spring Roo GAE GWT project that works
 Here is the contents of my Roo file, hopefully this will help you work with your project.

project com.prestige.booking

persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE --applicationId PrestigeBooking

enum type --class ~.shared.domain.ContactType
enum constant --name Booking
enum constant --name Billing
enum constant --name Passenger

entity --class ~.shared.domain.Contact  --testAutomatically 
field string --fieldName fullName --notNull
field string --fieldName email
field string --fieldName phoneNumber
field enum --fieldName contactType --type ~.shared.domain.ContactType

entity --class ~.shared.domain.Booking --testAutomatically 
field reference --type ~.shared.domain.Contact passenger

entity --class com.prestige.booking.shared.domain.Journey --testAutomatically 
field date --fieldName journeyDate --type java.util.Date 
field string --fieldName startAddress 
field string --fieldName endAddress
field string --fieldName startTime 
field reference --fieldName booking --type com.prestige.booking.shared.domain.Booking 

loggin setup --level INFO

web gwt setup


Next Steps
If you have used Roo or have done some interesting things with a Roo project please get in contact.  I have yet to explore the AddOns or detailed more information on the workflow in a Roo project that goes from prototyping to real world application.  Get in contact and lets document some Best Practices for this awesome product.

Friday, September 10, 2010

Using OpenID on GWT with Google App Engine


OpenID (TM) is the way forward for providing secure and intuitive access to your website.  The increasing proliferation of websites offering multiple methods for authentication is indicative this is a trend is here to stay.  Websites commonly contain access via Google Accounts, Facebook, Twitter, MyOpenId, and many other providers.  Not all of these use the OpenID standard but the term is likely to spread given its open source status.  Using OpenID with GWT on Google App Engine is fairly easy to implement, but has its perils which you should be aware of.  In this article we discuss the code and methods used to build a solution using the dyuproject framework.

Why not use the new developmental federated login provided by Google App Engine?

This article documents very clearly the process to implement OpenID using the GAE SDK.
Using Federated Authentication via OpenID in Google App Engine - Link

I tried this method and it works very well and is easy to implement.  However from using it I had two issues.

Firstly, and probably the most importantly, is the behavior in debug mode.  When logging in the user is directed to the GAE SDK development server login page, rather than the OpenID provider selected when authenticating.  This makes debugging of your authentication system very difficult, especially when you have to upload a new version of the application with increased logging, if you have a problem with authentication.

Secondly, if the OpenID authorization URL is incorrect, the application just sits on a blank page after trying to redirect to the authorization URL.  Now this maybe a functionality of the OpenID protocol rather than its implementation here, but the user experience was strange so I decided to abandon it.
This is an experimental feature at present so I am far from saying do not use it.  What I am saying is that if you prefer to have a similar authentication experience in debug as in live, then use the suggestions given further down.

User Interface

Many of the articles written here are concerned with the steps taken to produce the website SohoCRM, a small business, Google Apps focussed CRM system - http://sohocrm.appspot.com.  The screen shot below shows the initial implementation of OpenID.  I say initial because there are plans to improve its look, but at present in its draft form it looks like this:



As you can see the OpenID providers are split into two groups.  Those which require a username and those that do not.  The purpose for the username relates to the construction of the OpenID URL.
The OpenID URL is a value passed to the OpenID library duyproject which handles how the application redirects to the authentication page of the OpenID provider.  The RelyingParty is the application requiring access, an industry standard term worth remembering.  The URL hierarchy and construction of the login images is rendered from a HashMap containing all the OpenID providers the application currently supports:

//Doesn't require username first
insertProvider("Google","https://www.google.com/accounts/o8/id","/openid2/nascar/large/google.png");
insertProvider("Yahoo","https://me.yahoo.com","/openid2/nascar/large/yahoo.png");
insertProvider("YahooJapan","https://me.yahoo.co.jp","/openid2/nascar/large/yahoo-jp.png");
insertProvider("MyId","https://myid.net/","/openid2/nascar/large/myidnet.png");
insertProvider("Mixi","https://mixi.jp","/openid2/nascar/large/mixi_jp.png");
//Does require username
insertProvider("MyOpenId","http://username.myopenid.com/","/openid2/nascar/large/myopenid.png");
insertProvider("Flickr","http://www.flickr.com/","/openid2/nascar/large/flickr.png");
insertProvider("AOL","http://openid.aol.com/username","/openid2/nascar/large/aol.png");
insertProvider("Blogger","http://username.blogspot.com/","/openid2/nascar/large/blogger.png");
insertProvider("LiveJournal","http://username.livejournal.com/","/openid2/nascar/large/livejournal.png");
insertProvider("Verisign","http://username.pip.verisignlabs.com/","/openid2/nascar/large/verisign.png");
insertProvider("ClaimId","http://claimid.com/username","/openid2/nascar/large/claimid.png");
insertProvider("Wordpress","http://username.wordpress.com","/openid2/nascar/large/wordpress.png");

On rendering, if the login widget finds the keyword username in the URL component it renders the login image button to the bottom flow panel.  This is the one that requires the user to enter a username first.
The second parameter for the inserProvider function is the base URL needed to access the OpenID authentication screen.  This URL is passed to the duyproject by redirecting the screen to a URL of the type:

"/openid2/login?openid_identifier={providerUrl}"

Authentication Servlet
In GWT we have setup this URL pattern to map to our OpenID Authentication servlet.  In this application we have used GUICE to setup our mappings.  In our DispatchServletModule we have configured the mapping as below:

serve("/openid2/login").with(OpenIdServlet.class);

Which then maps to an object of this type:

public class OpenIdServlet extends HttpServlet {

The Authentication Process

This took a while because I was new to the OpenID protocol.  I had the typical programmers dilema where you know you are tackling a problem someone else has probably completed and published online but just need the quick heads up on how to implement.  I already has some code from GWTP Puzzlebazar's project so I quickly adapted that for my purposes.

The doGet method points to the doPost in this servlet so the code below is where this will be found.

Step 1: Establish Parameters and Logout
String openIdIdentifier = request.getParameter("openid_identifier");
if(openIdIdentifier!=null){
this.userDAO.get().logoutSessionUser();
}

The openid_identifier is an important parameter in the URL so you must make sure that this is passed.  The duyproject expects this parameter so however you construct your redirect to the servlet it is expecting this in the querystring.

Step 2: Create RelyingParty instance and attempt to authorization
RelyingParty relyingParty = RelyingParty.getInstance();
try {
  OpenIdUser openIdUser = relyingParty.discover(request);

Here an instance of the relying party is created which attempts to authorize the URL passed in.  It checks whether the user has access to this URL and populates the openIdUser with information related to its status.
After verifying the user the application then checks on how to proceed.  The duyproject covers this process very well and the javadoc here is an excellent resource on how to continue: link.  The example code given is shown below:

 OpenIdUser user = _relyingParty.discover(request);
   if(user==null)
   {                
       if(RelyingParty.isAuthResponse(request))
       {
           // authentication timeout                    
           response.sendRedirect(request.getRequestURI());
       }
       else
       {
           // set error msg if the openid_identifier is not resolved.
           if(request.getParameter(_relyingParty.getIdentifierParameter())!=null)
               request.setAttribute(OpenIdServletFilter.ERROR_MSG_ATTR, errorMsg);
           
           // new user
           request.getRequestDispatcher("/login.jsp").forward(request, response);
       }
       return;
   }
   
   if(user.isAuthenticated())
   {
       // user already authenticated
       request.getRequestDispatcher("/home.jsp").forward(request, response);
       return;
   }
   
   if(user.isAssociated() && RelyingParty.isAuthResponse(request))
   {
       // verify authentication
       if(_relyingParty.verifyAuth(user, request, response))
       {
           // authenticated                    
          // redirect to home to remove the query params instead of doing:
           // request.setAttribute("user", user); request.getRequestDispatcher("/home.jsp").forward(request, response);
           response.sendRedirect(request.getContextPath() + "/home/");
       }
       else
       {
           // failed verification
           request.getRequestDispatcher("/login.jsp").forward(request, response);
       }
       return;
   }
   
   StringBuffer url = request.getRequestURL();
   String trustRoot = url.substring(0, url.indexOf("/", 9));
   String realm = url.substring(0, url.lastIndexOf("/"));
   String returnTo = url.toString();            
   if(_relyingParty.associateAndAuthenticate(user, request, response, trustRoot, realm, returnTo))
   {
       // successful association
       return;
   } 

As you can see this handles each particular outcome of the interaction with the OpenID provider.  Providing you have supplied this example code with a good url, then the duyproject handles all the redirection and processing required to authenticate the user.  The only thing you need to do is implement above the code required to register that a user has authenticated in your application, i.e. logging in DB and creating a session variable.   This would occur after the line that reads:

if (openIdUser.isAssociated() && RelyingParty.isAuthResponse(request)) {

Attribute Exchange

The OpenIDUser object contains all the methods needed to extract any AttributeExchange information such as the Country, Language and any other attributes that are part of the AttributeExchange specification.

Do not use the email address as the unique ID!!!!!

I cannot stress this enough because this issue may arrive as you transfer from one authentication system to another.  For example say you have a current auth system which requires the user to login via their email address and a password.  Fine so far.  Now in order to keep your current data model you assume that the email address returned from the OpenID provider can be used as the key again, because you have incorrectly assumed that the OpenID provider checks to make sure that the user who registers with an email address has been verified.

STOP!!!

You cannot rely on the email address returned from the OpenID Provider because some providers allow you to specify what email address you want to return to the RelyingParty website.  Thereby changing this to another value of an account you may want access may give you a backdoor access to someones account.

The only uniqueID you can rely on from the OpenID provider is what is known as the ClaimedID (openIdUser.getClaimedId()).  This value is the authentication URL the user is allowed access to.  For example my AOL ClaimedId is: http://openid.aol.com/thinkjones

Summary

This took me a while to complete, the code not the article, because I was too caught up in thinking that I needed to write absolutely everything of the OpenID process.  Relying on the duyproject was a good move as it allowed me to just slot in my current authentication process at the appropriate point.  All I needed to do was create a good URL to pass to this component.  
When testing the project with the different OpenID providers I needed to test each URL individually because each OID Provider had slightly different requirements in their URL syntax.  Hopefully the fairly comprehensive list above will help you implement many solutions into your current web work.
I apologize if this article is a bit vague or badly written.  I have jet lag at the moment and wanted to get this article out as quickly as possible.  As usual leave questions in the comments.


Monday, July 26, 2010

Objectification is not always bad.

We are like things that make our lives easier, unless the task of completion is the glory unto itself.  When it comes to GWT and JDO, a nice layer of abstraction exists already so it is easy to develop a data model and implement it in your system.  When GAE is added into the mix, which isn't really a relational database, certain nuances make the implementation just a little more complicated and so any library which helps with this operation is warmly welcomed.  The downside is that you are building your application specifically for Google App Engine, rather than any DB which implements JDO.

Luckily, I Love Google.  Google I Heart You... And so that is where Objectify steps in.  Objectify is a layer which sits on top of your objects to provide easy, get, put, delete and query operations into your Google App Engine database.  At this stage I am just promoting and highlighting this functionality but will be soon posting examples of how to use this system.

Thursday, July 15, 2010

Soho CRM Moves to GWTP

As you are probably aware I am currently using, and dare I say recommending using the GWTP framework, as it has a lot of built in features which are very useful to the burgeoning GWT application creators.  Basically if you want to free yourself of spaghetti code and extensive boiler plate boredom, then go GWTP, or go home ;)

So I have been using the framework extensively, often asking questions in the forum and have even been invited to contribute to the project.  Therefore I started where all responsible people should, and contributed to the much loved documentation.  Since I needed a FAQ page I created the start of one.  Now after two weeks I have learned a lot, and have the start of my CRM application in Google App Engine - http://sohocrm.appspot.com.


Ok. I know it looks rough.  But believe me I have been on a learning expedition which is now starting to bare a good crop.

Wednesday, June 2, 2010

GWT and Spring Roo Has Great Potential

After messing with Spring Roo and GWT yesterday I can confirm three things:
  1. The potential of this is amazing.
  2. It isn’t quite ready.
  3. Did I mention that this might be amazing?
Spring Roo is a command shell that, as far as I can tell so far, I have a feeling I might be only scratching the surface, creates much of the boiler plate code that we get bored of creating.  By using an automated solution it allows the development of the code to increase, raises quality and allows you to develop application very quickly.
By entering a series of commands into a roo shell on the command line or in the Spring Source Tool Suite Roo Shell you can create an application configured with different databases and database providers.  Whilst developing the data structures and GUI interfaces required for them.
In order to increate my understanding of Spring Roo I am heading to the command line and following their tutorial to increase my understanding.
Here is an example script:
mkdir hello
cd hello
roo
roo> hint
roo> project --topLevelPackage com.foo
roo> persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
roo> entity --class ~.Timer --testAutomatically
roo> field string --fieldName message --notNull
roo> hint controllers
roo> controller all --package ~.web
roo> selenium test --controller ~.web.TimerController
roo> gwt setup
roo> perform tests
roo> quit

It is quite readable and quite amazing!

Tuesday, June 1, 2010

Create a GWT Contact Application in 10 easy steps.

Google GWT and Spring Source have joined forces to make it easier to develop web applications by developing a tool which creates your data models, your web gui interface and all the web-server communication code in a few easy command line statements.  This was demo’d at Google IO 2010 and I aim to replicate the steps required here, including any pitfalls to help you jump start your GWT development.

SpringSource Tool Suite (STS) Is a flavor of Eclipse that includes all the necessary functionality to get this working.  At it’s core is a Roo Project where you create project and define entities using the Roo Shell.  This allows you to quickly get a Database, GWT Front End and connectivity code build without writing a single piece of code.

The source data and graphics for this article is from this web page.  I have outlined my steps taken when completing it and any pitfalls I came across.   http://www.thescreencast.com/2010/05/how-to-gwt-roo.html

The Steps REQUIRED

Step 1 : Setup your system

Download and setup Spring Source Tool Suite using the first screencast on this page:

http://www.thescreencast.com/2010/05/how-to-gwt-roo.html

Step 2 : New Roo Project

image

Enter Project Settings and Click Next

image  

Click Finish, and Yes to Turn Weaving Service On

image

No to Restart Now

image

Step 3 : Goto Roo Shell

Ensure project is selected in Project Hierarchy

image

Setup Persistence

image

Step 4 : Create Employee Entity

image 

Step 5 : Create Employee Entity Fields

Field firstName

image

Field lastName

image

Step 6 : Create GWT – Front End

image

Step 7 : Setup Google Web tool Kit Settings

image

image

Step 8 : Enable Maven Dependency

image

Step 9 : Run Project

image

image

image

Step 10 : Goto Browser

image 

Pitfalls to watch out for

Enable Maven Dependency:  This is one of the last stages of the demo and in the screen case it appears to work instantly.  This is not the case.  You will notice Eclipse in a busy mode for a few minutes as it configures itself.

Additional Info

Video from Google IO demonstrating this feature:

Thursday, March 11, 2010

How to update eclipse to the latest GWT and GAE SDKs

This website covers all the main points but I spent ages trying to find a solution to this and following this page would have saved me a lot of time.  Click this Google page for more info

Friday, February 26, 2010

GWT Demos and Samples

I am not sure about you but the best way to learn for me is by example.  Luckily Google Web Toolkit and Google App Engine have plenty of examples to get you going. 

GWT Examples.
These are located in the GWT SDK at this path:
\gwt-2.0.0\samples\
on my machine this translates to this directory:
C:\Program Files\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.2.0.0_2.0.0.v200912062003\gwt-2.0.0\samples

GAE Examples
Similarly located here:
C:\Program Files\eclipse\plugins\com.google.appengine.eclipse.sdkbundle.1.3.0_1.3.0.v200912141120\appengine-java-sdk-1.3.0\demos