Dec 21, 2011

Failing Gracefully

No, this is not about how to design/build software which fails gracefully. This is a short commentary on my recent Did Not Finish (DNF) on the 300 Km Kolar Gold Fields (KGF) Brevet ride. 


For those not familiar with what a Brevet ride is: it is a self supported non competitive time bound bike ride. The 300 Km KGF Brevet ride would take us across 3 states and we had to cover 313 Km in 20 hours at an average speed of over 15 Kmph. I had previously done a 300 Km Brevet ride so was quite confident of completing this as well. 


But what a crazy ride it ended up to be. The ride started at 6.00 AM from MG Road metro station. It was great riding in the fog all the way up to Hoskote where we turned right towards Malur. This is where the state highways and village roads started. In addition to this had a consistent wind resistance for most of the ride. The weather was good and while there were bad stretches of roads, the tree cover on both sides of the road provided protection from the Sun. Rode through nice stretches but was always under the gun to keep moving - was averaging right around 15 Kmph including the breaks. Took only short breaks to eat and stretch. 


Reached Pernambut @ 3.00 PM but missed the SBI ATM which was the second control point. Went back in search of this and lost precious 30 minutes. Checked in to the control station just in the nick of time - had covered 143 Km in 9.5 hours. Reached Vaniambadi toll booth around 6.00 PM - had covered 182 Km in 12 hours. Took a rest break here and saw 7-8 riders pass by. While I was happy that I was not way behind the others till this point, I was worried about what lay ahead. I was averaging 15 Kmph at this point and the remaining 131 Km ride would be in cold, dark and include a tough 50 Km climbing ride from Krishnagiri to Hosur. This is where I decided to not ride in the dark but take a bus back to Bangalore from Krishnagiri instead. Reached Bargur around 8.00 PM and had dinner here. Thought I would try and get a bus right from here and waited for 30 minutes to get a bus but no luck. Again got into bike gear and rode to Krishnagiri and requested/argued with the conductors to take me & the bike to Bangalore. Thankfully had luck on the second try itself and after securing the bike on the top, deposited myself on an empty seat for a cold uncomfortable drive back to Bangalore. Reached at 00.30, got the bike down and rode home to reach around 1.20 to end a day of painful riding.


Fellow rider Parag later learnt about my DNF and enquired if I was okay. Informed him that I was okay but decided to quit as I did not want to ride in the night. My idea of a good bike ride is where you get to enjoy the ride and not just burn the Kms. Honestly I was in a pretty bad mood riding through the nice villages. Did not even exchange pleasantries with the village folks which I usually do on a ride. I guess no more Brevet rides for me... but hey! you never know :-). 


Couple of tech highlights of the ride:


Map My Ride: I developed an application using which a rider could mark one's location on a ride and anyone could track the progress of riders. I could not use the app very well as my iPhone did not seem to work very well but Devaraj marked his position throughout the ride - Thanks for checking out the app Devaraj. My thought now is that this app is better used by tourers and not in time bound events as time is of the essence in these rides and geolocation + marking location takes some time - I did end up wasting quite a bit of my time trying to locate myself and mark my location. You can check out the app here: Map My Ride. Suggestions for enhancements are welcome. 
Map My Ride - Mark Location Screen
Rider Progress - Devaraj & Shashi's Updates
Solar Charging Garmin: I had purchased a Solar Monkey solar charger on a recent trip to London but had never used it till now. I used this charger on this ride and am happy to report that my Garmin Forerunner 305, which usually runs out of battery in 13-14 hours, survived the entire ride - home to home - around 18 hours and still had some juice left in it. I think I can get it to work even more effectively if I am able to position the solar panel well. Check out the setup below. 
Solar Monkey & Solar Nut charging my Garmin Forerunner 305

The power of Community Development

Over the past few months the cloudspokes.com site was rebuilt on Heroku and Database.com. Code contributed by developers across 8 countries over 22 challenges was used to rebuild the site. Proud to say that I have been a part of this journey. Read more on the Cloudspokes Blog

Dec 6, 2011

Bangalore to Chennai Ride

It's been a while since I did much of regular cycling. Since Aug 2011, couple of overseas travels, unseasonal and (often unpredictable) Bangalore rains, the time I have been spending lately learning and using cool and exciting cloud technologies and finally plain laziness have kept me off the bike. So much so that it started showing on the waistline as well. 


So when my parents and few other relatives decided to visit my cousin in Chennai, I figured why not ride to Chennai and return in bus along with them. Chennai appeared to be a good choice as I would be riding with loaded panniers and the route did not have many climbs. Thus the plan was born. 


The total distance to be covered was around 342 Km. My gameplan was as follows: 

  • Ride with minimal breaks
  • Start the ride early in the morning and end by early evening
  • Take rest during mid day when the Sun is at its scorching best
  • Ride as much as possible on Day 1 so that I reach Chennai early on Day 2 and spend more time with family. Vellore was the planned target for Day 1. 

Packed my two pannier bags as follows: 
  • Bag 1 - change of clothes at end of Day 1, fresh riding clothes for Day 2, two tubes and puncture kit. 
  • Bag 2 - Extra 1 litre bottle of water, 1/2 litre bottle of orange juice, sandwiches (packed by wife in the morning), air pump, tools, gatorade, torch, wet wipes, almonds and raisins. 
Day 1 - Saturday, 3/Dec/2011
Started from home at around 3.30 AM. Before long passed silk board and then stayed on the service lane all the way till past Electronic city. Stopped at the A2B before Krishnagiri at around 7.00 AM with the Garmin indicating 71 Km. Had a couple of sandwiches and a coffee and re started the ride around 7.30 AM. Saw Chiddu and Parag on the other side of the road returning from their Krishnagiri ride. Could wave and shout out only to Parag as Chiddu had passed me before I could react. We gave each other a thumbs up and moved on in our respective directions. Quite an uneventful ride till around 11.00 AM when the Sun started getting intense. The breeze which was against me was actually quite welcome due to the cooling effect. Passed by a town called Ambur which I later came to know is famous for leather and shoe works. Saw lots of small and large factories dealing with leather and shoes. Also passed by a small coir establishment - Could see some of the processing from road. It's a wonder how every part of the coconut plant is utilized in some form or other. I wanted to break for lunch only after completing half the distance to Chennai and also at a place where I could take some rest during the peak afternoon. Found a temple on the road side which had a resting area. Decided to take a break here for lunch. The Garmin showed 171 Km and the time was 12.25 PM. Washed up, had the remaining sandwiches and slept for some time after securing the bike. Left from here around 2.00 PM for the final leg of travel for the day. While the Sun still fell hot at 2.00 PM, post 3.00 PM, the heat was not that intense and was quite comfortable. Reached Vellore around 4.30 PM but decided to continue onto the next town Ranipet as there was still daylight and I was feeling strong. Reached Ranipet around 5.30 PM and found a hotel right at the edge of the town. The hotel was not so great and actually quite shady but I figured "will just be sleeping here and it is right on the highway" and so decided to stay there. Washed up, went out and had some food, got some water & bananas for next day. Got back to the hotel and after cleaning the bike and setting the alarm for the next day, went to sleep early at 9.00 PM. 

Day 2 - Sunday, 4/Dec/2011
Woke up around 3.45 AM and quickly got ready and hit the road at 4.18 AM. Was riding in a new area in dark so though I was using two sets of front and rear lights, was waiting for the dawn. The hints of daylight started around 5.45 AM but since the fog was rolling in, saw the first glimpse of Sun only around 7.00 AM. After passing Sriperumbudur, got off the main highway and took inside roads to head towards the Airport. I had another 30 odd Kms to cover. The roads were bad in stretches. Passed a glass recycling area - had never seen so much broken glass in one place. Crossed a stream of water on foot carrying the bike - contemplated removing my shoes but since it was only a short stretch to the destination I just walked through the water. Since it was a Sunday and feast day, saw several places selling pig meat - in fact at one place saw a whole pig head next to the meat - wow! Pretty soon I could see planes making their approach to landing - I was close to the destination. Covered the last few Kms quickly and with some directions from a traffic policeman arrived at my cousin's home in Nanganallur. Was received warmly by her family and thus ended my ride to Chennai. 

Some Gyan
While the whole ride was quite uneventful - no punctures or breakdowns, no accidents or altercations, no wrong turns, no running out of water - the ride itself made me come to a few conclusions:
  • While it may sound like a cliché, it is true that the longest of journeys begin with that first step or in this case the first pedal. Till the time I came out of my home on Saturday morning, I was not sure whether I would start or no. But I just told myself "Lets go for it. You can always stop and return.". 
  • While touring, don't aim for speed and higher gears. Keep at lower gears and keep going. I was myself surprised that though I rode for long stretches in 2 x 3, 2 x 4 & 2 x 5 combinations, I still had an overall riding average of over 20 Kmph. 
  • Be prepared - food, drink and tools. Though I didn't have to use the tools, it was calming to know I had the tools to do basic fixes and puncture repair if I needed to. I always made sure I had a reserve of water with me and would stop to buy water before I ran out of it. 
  • It is difficult to keep riding on and on. On this route, the pedalling is not difficult as it is a fairly flat route with the few uphills being only the ramps to bypass the towns and cross the occasional stream and railway tracks. The catch is how do you motivate yourself to keep going. I just kept at it visualizing the bed at the end of the day, the nice food I would have at the end of the day and the get together with the family members after so many days. Visualizing a nice end or a goal is always a good motivation to keep you going - whether it is cycling or something you are aiming for in life. I have myself found this technique work for me many a time. 
Statistics
  • Day 1 - 238 Km - 11 Hours 20 Minutes riding time, 14 Hours elapsed time
  • Day 2 - 105 Km - 5 Hours 30 Minutes riding time, 6 Hours 10 Minutes elapsed time
  • Intake:
    • Food - 6 2-slice Potato sandwiches, 7 Bananas, 1 Orange, 3 Idlis, 1 Vada, handful of almonds and raisins
    • Fluids - 6 Litres of water, 1 small coke, 1/2 litre orange juice and 6 packs of Gatorade 
I did not take too many pictures on this trip to not lose time but here are a few. Not sure how many of you have seen this type of grasshoppers. They used to be a regular sight in U.P. where I grew up but haven't seen any here in Karnataka, Andhra or Maharashtra. 



Oct 3, 2011

Google+ to Salesforce Chatter Integration

This article describes my entry to the cloudspokes.com Google+ to Salesforce Chatter integration challenge. It covers using OAuth2 to connect to Google+ from Salesforce Apex, making call to the Google+ API to retrieve the Google+ posts to be posted to Chatter and then posting them to Chatter. 

Requirements

Though the title says Google+ to Salesforce Chatter integration, the integration is initiated in reverse. From Salesforce end, we should be able to pull the user's Google+ posts targeted to be sent to the user's Chatter account using a specific hashtag (#ch). 

The Moving Parts
  1. Google OAuth2 - Authentication and Authorization to Google+ APIs. 
  2. Google+ API - Provides access to the user's Google+ posts. 
  3. JSON Parser by Ron Hess - Is used to parse the JSON returned by the Google OAuth2 for server-side web applications and the Google+ APIs. 
  4. Visualforce page and it's controller - Implements the integration logic and allows the user to fetch his Google+ posts and insert the same to Salesforce Chatter. 
Setting Up Google APIs Access
  • Navigate to Goole APIs Console. Create a new project, e.g. API Project. 
  • Navigate to Services tab of Google APIs Console and turn on the Google+ API service. 
  • Navigate to API Access tab of Google APIs Console. Click on Create an OAuth 2.0 client ID
  • Enter 'G+ Chatter Integration' in product name field. This information will be shown to users when your application requests access to their private data using your new client ID. Click Next. 
  • Select Web Application on the next screen. Click on more options link next to Authorized Redirect URIs and enter https:///apex/GooglePlusToChatter in Authorized Redirect URIs text box and https:// in Authorized JavaScript Origins text box. Replace  with your salesforce instance url. Click on Create client ID. Note the client ID and Client Secret. These will be required to setup the Apex connectivity to Google+ in later steps. 
  • See the pictures below for visuals of the above steps. 

Picture 1 - Initiate creation of client ID

    Picture 2 - Create Client ID Step 1
    Picture 3 - Create Client ID Step 2
Picture 4 - View of newly created Client ID
Google+ APIs
Google+ APIs were made available in Sep 2011. The initial set provides read access only. 


The three APIs provided in the initial set are: 

  • People:get - Get a person's profile - https://www.googleapis.com/plus/v1/people/{userId}
  • Activities:list - List all of the activities in the specified collection for a particular user. We will be using this API for our purpose - https://www.googleapis.com/plus/v1/people/{userId}/activities/{collection}
  • Activities: get - Get an activity - https://www.googleapis.com/plus/v1/activities/{activityId}

The userId referred to in the first two bullets above is not the google id used to login. It is an id which uniquely identifies each resource in Google+. You can find your userId by going to your google+ profile. The numeric text following plus.google.com/ is your userId. The picture below shows my Google+ profile with my userId enclosed in the blue rectangle. 
Picture 5 - Getting userId from Google+ profile
The Process
The overall integration works in the following manner: 
  1. The application passes the client id, redirect URI and requested scope of access to Google OAuth2 URL. 
  2. If the user is not logged into Google, user is presented with the authentication screen. Once the user logs in, the user is presented with a screen to authorize your application to access your data. If the user were already logged into Google, only the authorization screen is presented. 
  3. If the user declines to authorize the access, Google returns an access denied message. 
  4. If the user authorizes the access, Google returns and authorization code to the application. 
  5. The application then passes the code, client id, client secret and redirect URI to the Google OAuth2 token URL. 
  6. Google responds with an access token and a refresh token. 
  7. The application uses the access token and the Google userId to send an HTTP get request to Google+ activities list URL. 
  8. Google+ responds with the last 20 Google+ posts in JSON format. 
  9. Application uses JSONObject.cls to parse the response and find all Google+ posts with hashtag #ch which have not been posted to Chatter. 
  10. Application posts selected Google+ posts to Chatter as user's current status. 

Implementation Details


Integration Settings: The following data elements need to be stored in force.com Custom Settings: Google_Plus_to_Chatter_Settings__c under name 'MySettings':
  • Client ID
  • Client Secret
  • Google Plus User
  • Last Published
Picture 6 - Storing integration settings in Custom Settings
Constants used in the integration  
INTEGRATION_SETTINGS_KEY = 'MySettings';  
GOOGLE_OAUTH_URL_CODE = 'https://accounts.google.com/o/oauth2/auth';  
GOOGLE_OAUTH_URL_TOKEN = 'https://accounts.google.com/o/oauth2/token';  
GOOGLE_API_ACCESS_SCOPE = 'https://www.googleapis.com/auth/plus.me';  
GOOGLE_PLUS_REDIRECT_URI_SUFFIX = '/apex/GooglePlusToChatter';  
GOOGLE_PLUS_POSTINGS_URL = 'https://www.googleapis.com/plus/v1/people/';  

URL to Retrieve Authorization Code
 String url = GOOGLE_OAUTH_URL_CODE  
  + '?client_id=' + integrationSettings.Client_Id__c  
  + '&redirect_uri=' + getInstance() + GOOGLE_PLUS_REDIRECT_URI_SUFFIX   
  + '&scope=' + GOOGLE_API_ACCESS_SCOPE  
  + '&response_type=code'; //Retrieving code  


Code to Retrieve Access Token
 //Using the code, client_id and client_secret, get the access token.   
 HttpRequest req = new HttpRequest();  
 req.setEndpoint(GOOGLE_OAUTH_URL_TOKEN);  
 String postData = 'code=' + EncodingUtil.urlEncode(code, 'UTF-8');  
 postData = postData + '&client_id=' + EncodingUtil.urlEncode(integrationSettings.Client_Id__c, 'UTF-8');  
 postData = postData + '&client_secret=' + EncodingUtil.urlEncode(integrationSettings.Client_Secret__c, 'UTF-8');  
 postData = postData + '&redirect_uri=' + EncodingUtil.urlEncode(getInstance() + GOOGLE_PLUS_REDIRECT_URI_SUFFIX, 'UTF-8');  
 postData = postData + '&grant_type=' + EncodingUtil.urlEncode('authorization_code', 'UTF-8');  

Code to Invoke Google+ API to get Activities
 HttpRequest req = new HttpRequest();  
 req.setEndpoint(GOOGLE_PLUS_POSTINGS_URL   
  + integrationSettings.Google_Plus_User__c   
  + '/activities/public'   
  + '?access_token=' + EncodingUtil.urlEncode(accessToken, 'UTF-8'));  
        req.setMethod('GET');  

Code to parse JSON returned by Google
 String json = res.getBody().replace('\n', '');  
 JSONObject j = new JSONObject( json );  
 totalPostsRetrieved = j.getValue('items').values.size();  
 //Iterate through the post and select the chatter posts  
 for (Integer i = 0; i < totalPostsRetrieved; i++) {  
      //Use this post only if the post timestamp is after the last published timestamp and  
      //if it contains the #ch hashtag  
      datetime googlePlusPostTimestamp = convertGoogleTimestampToDatetime(j.getValue('items').values[i].obj.getString('published'));  
      String googlePlusPost = j.getValue('items').values[i].obj.getValue('object').obj.getString('content');  
      if (googlePlusPostTimestamp > integrationSettings.Last_Published__c && googlePlusPost.contains('#ch')) {  
           postsForChatter.add(googlePlusPost);  
      }  
 }  
 chatterPosts = postsForChatter.size();  
 //Update last published timestamp  
 integrationSettings.Last_Published__c = publishedDatetime;  
 try {  
   upsert(integrationSettings);  
 } catch(System.DMLException e) {  
   ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Error updating last published timestamp: ' + e);  
   ApexPages.addMessage(pageMsg);  
 }  


Code to Post to Chatter
 //On first time page load, 'code' parameter is not set.   
 //'code' parameter is set by Google OAuth 2 on redirection back to this page.    
 if (parms.containsKey('code')) {  
   String accessToken = getAccessToken(parms.get('code'));  
   if (accessToken != null) {       
     List<String> postsForChatter = getGooglePlusPostsForChatter(accessToken);     
     for (String post : postsForChatter) {  
         User user = [select id, CurrentStatus from User where id = :UserInfo.getUserId()];  
         user.CurrentStatus = post;  
         update user;  
     }     
   }  
 }  


Application In Action
Picture 7 - Google+ Before posting new entry
Picture 8 - Chatter Before posting new entry
Picture 9 - Page to invoke Chatter integration

Picture 10 - Added New Post on Google+
Picture 11 - Google Authorization Challenge
Picture 12 - Shows 1 post to Chatter and updated Last Published Date

Picture 13 - Shows Google+ post made to Chatter
Improvement Areas
The following enhancements to this integration are possible:

  1. JSON Parser gives too many scripts exception if the number of posts retrieved is high. This needs to be addressed. 
  2. The retrieval of posts can be automated via a scheduled job. 
  3. The code currently requests new access tokens each time. It does not reuse existing token and on failure retrieve a new access token using refresh token. This can be implemented to make the code more in line with the Google OAuth2 design. 

References

I would appreciate feedback from the readers. I will be posting a short video of the application in action in a few days. For additional information and actual code, please get in touch with me.

      Sep 15, 2011

      Flying in the Cloud

      The last six weeks has been a whirlwind tour of new technology platforms on the cloud. Salesforce, Google Analytics, MailChimp, Amazon SES & Heroku... whew! 

      In the process learnt Salesforce configuration & setup, Apex and visualforce basics, attended Dreamforce 2011 conference @ San Francisco and got my Salesforce developer certification at the conference. Made three crowdsourcing challenge submissions on cloudspokes.com and won one so far. The empowerment of developing on the cloud based platforms as opposed to traditional environments feels good.

      The Dreamforce conference is the first large technology conference I attended in over three years. The energy at the conference was just plain awesome. The learning and exposure to salesforce and related technologies appeared to be better than similar technology conferences.
      The day before the start of Dreamforce 2011 @ Moscone Center
      The last day of the conference - still busy!

      As more and more cloud platforms are made available, the development community needs to understand the nuances of development on the cloud. Things which come to mind are responsive & stable internet connection, platform enforced limitations, platform integration capabilities, source code management, continuous integration, enforced testing and error handling. Add to this the socialization of enterprise applications and mobile client platforms outnumbering the traditional browser based clients, we have at our hands a heady concoction of technologies sure to challenge and satisfy even the geekiest of us all. In summary, I feel transported back 10 years. The difference: Java then and Cloud now.

      So let's Fly in the Clouds - चलो बादलों में उडें| 

      Dec 29, 2010

      The TfN Saga

      I figured I could write a brief writeup for each TfN day but internet availability and the tired body at the end of each day prevented me from writing on any of the days except the first one. So here is the consolidated update. 


      First off, the overall statistics - 825 Km over 8 days as follows:

      1. Day 1: Bangalore (Koramangala) to Kollegal - 151 Km
      2. Day 2: Kollegal to Bandipur - 156 Km
      3. Day 3: Bandipur to Ooty - 90 Km
      4. Day 4: Rest at Ooty
      5. Day 5: Ooty to Wayanad (Kalapetta) - 141 Km
      6. Day 6: Kalapetta loop - 75 Km
      7. Day 7: Kalapetta to Gonikoppal - 130 Km
      8. Day 8: Gonikoppal to Mysore outskirts - 82 Km
      Full route map with each day colour coded

      Day1: Today we rode from Bangalore to Kollegal. Fairly well known territory till Malavalli. No surprises on this day. Slightly bad to good roads. Here is Mark and me at the start point. 

      Day2: Today we rode from Kollegal to Bandipur. Again mostly flat good roads. Took breaks for coconut water otherwise mostly rode non stop. At the end of the day we had to cross a bit of the Bandipur forest before we got into Country Club Bandipur. The resort is great and is in a fantastic location. Good food and great ambience. Would love to go there with family some day. 

      Day3: Today was the day of the climb. We started early around 7.10 AM. My aim was to complete the climb by 2.00 PM. I was quite apprehensive about the climb considering the long painful Yercaud climb in September. But today was different - we were riding only 30 Km before the climb unlike the 200 Km we did from Bangalore to Salem before the Yercaud climb. 

      Started the ride strong and reached the first support station (SS1) after Gudalur town, a distance of 37 Km in exactly 2 hours. I had done 7 Km of climb already. My strategy from here on was to take it easy, enjoy the scenery and reach the subsequent support stations without any breaks. Reached SS2, 12.2 Km from SS1, in 1 Hr 28 Minutes. After a short break to replenish fluid supplies, took off for SS2. Same strategy again and it was easier going as the gradient was less steep than between SS1 & SS2. Reached SS3, 14.5 Km from SS2, in 1 Hr 12 Minutes. Had lunch here and left for the final leg of the ride. Covered the remaining 26 Km in a decent 2 Hours. Reached Ooty town around 3.00 PM. The overall climb was much less strenuous than the Yercaud climb. Enjoyed every bit of it. Would love to do this again. 

      My family including wife, kids, parents and brother's family were coming to Ooty by bus to be with me over the weekend. Met with them at the bus stand, got them checked in at the Club Mahindra Derby Green resort and then got over to YWCA where the TfNers were staying. Freshened up and waited for the evening's Christmas celebrations and dinner. 

      No ride pictures today as concentrated on riding. Hoping to post some pictures once we get the official photographer's set of pictures. Here are some pictures of the family and Christmas celebrations. 



      Day4: Today was the rest day. Spent time with the family. Had a relaxed breakfast followed by some table tennis, carrom and TV. Walked to Barista for a nice coffee and a light sandwich lunch. Ended the day with a solid dinner and walked back to YWCA. 










      Day5: Today we rode from Ooty to Kalapetta. It was raining in the morning so the start was delayed to 9.00 AM. The descent had to be taken slow. We rode in slight drizzle, fog and clouds. Fantastic weather for cycling. It all cleared by the time we reached the foot of the hills and it became quite warm by the time we reached the first support station past Gudalur. After this it was beautiful scenery - one tea estate after another all the way to Kalapetta. The icing on the cake was the wonderful Green Gates hotel where we stayed at in Kalapetta - would recommend this hotel to anyone visiting Wayanad region. 


      Day6: Today we did a loop around the Wayanad region. Pretty much a forgettable day with bad roads and not so good scenery. Most of the folks took a wrong turn right outside the hotel as guided by the hotel guard. The faster guys on the road bikes went so far ahead in the wrong direction that they decided to continue in the wrong direction as the roads were good and they could get some nice riding under their belts. Few of these guys went up to Calicut, a good 70 Km away, had their lunch at the Taj and then returned. I just took the planned loop and returned to the hotel around 2.00 PM, had my lunch, a brief nap and then a nice full body Kerala massage in the evening. Had a light dinner early evening and retired for the day. We were told that Day7 held a surprise for all of us. 

      Day7: Today we rode from Kalapetta to Gonikoppal. The day ended up being the toughest day of the whole tour. Check out the altitude profile for the day. 
      We were dropping close to 2000 feet over less than 15 Km and then climbing close to 2750 feet over less than 20 Km. 

      Reached the first support station just before the steep descent. Received strict instructions to go slow and be aware of the road repairs going on. Within 500 metres of the support station the descent started. I was amazed at the gradient and the steep drop at the edge of the road. At one point I saw several people standing at the edge of the road and watching down the slope. I was concentrating on handling the bike and I moved on. Came to know later on that a 3 wheeler carrying gas cylinders had went over at that point and the driver had died. I did get some pictures of the roads and scenery at this point... check them out. 

      Once we got done with the descent, we passed through some very lovely sleepy villages of Kerala. Saw coconut oil extraction and rubber tree farms for the first time in my life. Unfortunately no pictures again as I was worried about the upcoming steep climb. But the silver lining here was that the roads were good. Crossed bridge on a river and entered from Kerala to Karnataka and the climb started with the well laid smooth roads. The going was tough as it was hot afternoon. The respite was the forest cover. Unlike Ooty climb, where we could see the tall mountain we had to climb, here it always felt we had reached the top as we could see the trees at the top right next to us. The climb was linear as opposed to a circular. Started running out of water too. Around half way to the top I caught up with Manju and Deenanath and we three decided to stay together for the rest of the way. This is the only stretch on the entire tour where I had to take help from the mobile support - got the much needed water and juice from them at couple of points. It took close to 2.5 hours to complete the 23 Km climb. Along the way I saw many butterflies on the bushes. Check out the pictures. 

      Getting water from mobile support 
      After the climb came up to the last support station for the day at probably the best location of all the support stations so far. Check it out. 


      It felt great to complete this climb. Had a couple of Kerala parottas with egg curry - the egg curry was almost like Thai green curry - terrific. After this break started on the final leg of of the day to Gonikoppal. Shankar joined me here and he quipped "we have come from tea land to coffee land"; we were in Coorg. We rode together for the last 18 Km of bad roads to reach the hotel at Gonikoppal. The dinner at the hotel was the worst food I had on the entire tour. 
      Fooling around on Rishi's Pinarello
      Day8: The final day of the tour; rode from Gonikoppal to outskirts of Mysore. A short 82 Km ride. The first 38 Km of road was through forest area; saw a work elephant and a few deer. The next 37 Km on the Madikeri - Mysore highway - beautiful road but hot weather. Got some respite after having a coconut water at the 23 Km mark. Vishnu and I rode together from here on. Took another small break to have a coke and reached hotel Heritage Shelters on the Mysore - KRS road; our final destination and end of the tour. A bunch of folks were already there packing their bikes. Did a bike salute and got our pictures taken. Packed our bikes, freshened up, had lunch and waited for the rest of the folks to come in for our bus journey to Bangalore. 
      The Celebratory Bike Salute
      The Support Team - Awesome Team!!
      The buses left for Bangalore at 4.30 PM. After a brief halt for snack and tea/coffee at Maddur we reached outskirts of Bangalore around 7.00 PM. It took another 1.5 hours to pass through the peak hour traffic to reach the bus terminus. Took another 45 minutes to get my bike off the truck and unpack it. Bid adieu to the fellow riders and support team and started the ride back home. Reached home at 10.00 PM thus bringing to an end the unforgettable Tour of Nilgiris 2010. 


      It's been a great year of getting started with bicycling all over. Thanks to Rohan Kini from whom I bought my Cannondale Quick 5; a terrific all round bike. Thanks to my BBCH, CAM and GGI buddies for all the learning and support. Have lost 10 Kgs this year and am feeling great. 


      Next year is the year of Brevet and one long (2 weeks+) yet unplanned tour. Bicycling rocks! See you all on the road.