On Perl and Poetry

I first learnt of Perl in the late 90′s. Sometime around ’98 or ’99. Fresh on the heels of BASIC, I was yearning to try out something new when I heard of Perl. I heard it’s what the Internet ran on and it had an almost mythical air to it that made me want to learn it. If you wanted to build dynamic web sites at that time, you had few options, and Perl, Apache and UNIX was the workhorse. I wanted to build dynamic web sites so what I had to do was pretty clear. There was a new fangled thing called Java, but no way was it ever going to catch up to the dominance that Perl had over the Internet. Or so people thought.

Perl was the undisputed king of Internet 1.0. The language, with it’s knack for text processing coupled with it’s highly expressive syntax was ideal for building dynamic web sites. I saw how entwined Perl was in the UNIX sub-culture and how naturally it fit in, and together with Apache/mod_perl how it was poised to reign over the Internet for years to come. I then drifted into the world of enterprise Java and progressed from the monstrosity that was J2EE to the present day JEE, which has since redeemed itself and paid for it’s early sins, and when I came back several years have passed and Perl has been relegated to the position that new kids considered old and dead. However, nothing could be further from the truth.

In the often misunderstood syntax of Perl by those new to the language, who claim it to be cryptic or arcane, there’s an elegance and a beauty that is not always present in other languages and I find that I enjoy hacking on a Perl script more than chipping away at the Java mega-structures. It’s expressiveness and how you can mold the code to fit your pattern of thought by the many variations and permutations the language syntax offers plays a large part in this sense of aesthetic. There’s something about the language that’s reminiscent of a Bach fugue and poetry. I certainly do not feel the same way about Python, although Ruby comes a little close.

I don’t think I will ever stop coding Perl, and Perl 6 has a number of interesting language elements that I hope someday I will get to see, possible running on a GNU/HURD. Now wouldn’t that be a sight to behold?

To beacon, or not to beacon

The more I look into Bluetooth LE and beacon technology, the more I’m convinced that we’ve stumbled upon something very interesting and, even, *ahem* disruptive. I’m a bit reluctant to use the word “disruptive” as it has lost some of its meaning due to gross overuse, but I believe it describes the technology well. The wireless technology has being around for over a decade, but is now coming to the foreground specially on the micro-location front, which is showing a lot of promise. On another note, building a beacon using a Raspberry Pi seemed like an interesting project until I discovered that Bluetooth 4 USB modules are virtually non-existent in Sri Lanka. 

The PayPal beacon is a wonderful example of this at work. It’s very exciting to think about the possibilities that this could unleash. PayPal’s hands-free payments is completely re-defining the payment experience in a very novel way. It gets even more interesting when companies start carving out their own territories around this, as evidenced by Apple’s patent filings. My disgust for patents and the associated territorial pissing which in my opinion hinders innovation, is best left for another post.

 

2013, a retrospective

It has been an interesting year in ways that I did not anticipate. Looking back, I’d like to recount a few things so that I don’t forget the experiences that have dramatically altered my worldview, hopefully for the better. I’d like to remember these fleeting moments, as they’re too precious to be lost. Here they are, in no particular order.

  • It feels good to walk for the first time without support after an extended period on a hospital bed. The first unsure steps, like a child, are both exhilarating and scary. The slow steps, the deep breaths, and victory. The blessings of human mobility.
  • The seconds before general anesthesia. Unsure about what’s going to happen. Succumbing to the uncertainty. General sense of well being, even though NOT. Numbness traveling up the leg, starting at the fingertips. Fluttering of eyelids, coldness, and out.
  • Waking up thinking “Made It”, on more than one occasion. Colorful and vivid morphine-induced dreams.
  • Drinking water. Never did it taste so good. Thinking “why I didn’t I enjoy this more?”
  • Feeling satisfied and carefree when the last drain tube is out. Going for another walk without the chains and shackles this time, beaming and happy.
  • Taking bad news with a “crap, in a bit of a pickle”. Wishing there weren’t so many people around me. Thankful there weren’t some people around me.
  • Taking good news with a “hmm, that’s great”. Thinking “what’s next”, and where to go for lunch.
  • Waiting expectantly for the visiting hours and seeing Wathsala walk in at the strike of the clock. All is well.
  • Sleeping to the sound of a waterfall. My neighbor’s snoring and sleep-talk required me to explore this option. It worked out well.
  • Sleeping in my own bed and thinking how low-tech it is. The light streaming through an open window and a gentle breeze. It’s 11am on a Tuesday and I’m in bed and not at work.
  • Being breathless after a trip across the room.
  • Doing breathing exercises using a contraption that made me want to keep bettering myself to impress the nurses. Wathsala knew what was going on and was in silent support of it. Or so I presume.
  • The real beauty of loving and caring human beings. Honestly, there’s no bigger service than nursing someone to health.
  • Observing the activities of the Vietnamese drug lord and his two mistresses in an adjoining bed. His hefian mannerisms and attire intrigued the hell out of me. Didn’t see him after he was wheeled out for surgery. I figured he requested for a different bed. Wonder why.
  • Reading “Ape Gama” by Martin Wickramasinghe after many many years and thinking, “that is just beautiful”.
  • Visits from old friends.
  • Wearing the sarong like a boss. Proudly brandishing the national attire on the many trips abroad and vowing to stick with it for good. More “why I didn’t do this before?”.
  • Walking into the hospital like I owned the place. Being recognized. Probably as the guy who visits Mount Elizabeth wearing a sarong. Proud to be that guy.
  • Visits to the temple. More, “why didn’t I do this before?”
  • Hearing about those who were praying for my recovery from other people. Some who I had not even met, until just today.
  • Feeling grateful for my A team of Poh-Koh-Tan for pulling me out of a mess.
  • Dr. Liang banging his head on the table when he found out I was flying out the next day. He wanted more time to work with the “interesting case”. I granted him his wish.
  • Hearing old voices on the phone unexpectedly.
  • Hearing the sound of the crows outside the General Hospital in the morning. Inspiration shows up in unexpected places.
  • Being sick of soup. To this day.
  • Stories of talking dogs and cats and elaborate back-stories for doing what they did.
  • Shaking my cousins hand in the recovery room as I drifted in and out of sleep.
  • Waiting for the first rays of sunlight after a sleepless night.
  • Experiencing pain, and knowing it will pass. And it did.
  • Phone calls from my friends, following my every step of the way and helping me on.

It’s been an interesting year and I hope 2014 would be an interesting one too, and if all goes according to plan, it will. Stay tuned.

Software Freedom Day 2013 @ Virtusa

This last week, the fine folk at the Virtusa Open Source SIG organized an event to celebrate the Software Freedom Day where my good friends Mifan and Suchetha made keynotes. Also in attendance was Arunan, so it was a re-union of sorts with some old friends. It’s been a while since I have participated in anything open source / free software, and it was great to see the old flame is still alive at Virtusa, and I hope it helps in shaping their worldviews and brings as much purpose to them as it did to me more than 10 years ago.

The last SFD I attended was in 2008. I blogged about it here with some photos available in my surprisingly-still-around flickr account. It was in Chinatown in Boston and I drove up from Pennsylvania, mostly to get my mind off things. It was there that I purchased a copy of “Free Software, Free Society”, a collection of essays by Richard Stallman. Five years later, I picked up the dusty book from my shelf and re-read the GNU manifesto, to get my mind back to the core principles.

 Image

Source: http://www.flickr.com/photos/aweeraman/sets/72157600555500824/

It was there, as I was flipping through the pages, that I saw RMS in a whole new light. His uncompromising tenacity in the face of control and oppression and unfaltering stance on ethics and morality of freedom. He is a true freedom fighter. His message sometimes gets lost in all the pandemonium we go through daily but the spirit of the freedom he preached is very much alive every time we believe that knowledge should be free and that everybody should have access to it. I hope this message continues to inspire folks for years to come.

Google App Engine + APNS

Earlier this month, Google App Engine released support for outbound sockets and I figured that a Saturday spent mucking around with AppEngine to see if I could get it to work with APNS would be time well spent. In the sandboxed world of GAE, lack out outbound socket support meant that it was not possible to communicate with external services by opening a socket, which is what the Apple Push Notification Service (APNS) required. So for a long time, it was not possible to use the AppEngine to build an APNS provider, but now you can. Services like Urban Airship expose this capability in a way that can be consumed through a RESTful service, which works with GAE using UrlFetch, but the focus of this post is to communicate with APNS directly. There are some caveats though. Billing needs to be enabled, although the free tier should be sufficient for playing around, and there’s also the matter of the daily quota.

Here’s a whirlwind tour of getting yourself up and running on APNS with Google AppEngine.

1 – Fun with certificates and keys

Apple makes the job of working with APNS quite a fun and intellectually stimulating experience, if you have nothing else to do on a Saturday. You may also notice a couple of new gray hairs once you’re done, but at the same time, there is an elegance to the architecture that must be acknowledged, even though its painful to setup.

Generate a new certificate signing request
Fire up the mac Keychain Access tool and request a certificate from a certificate authority.
Request a certificate from a CA
In the resulting dialog, enter your email address an identifiable string in the common name field. Also, select the “Saved to disk” option, since we need to upload it later to the provisioning portal.
Certificate assistant
Once you’re done with this, you should have a Certificate Signing Request (CSR) in your file system.

Create a new App Id
Now head over to the Apple developer site, log in with your developer credentials and navigate to the iOS Dev Center, where you should see a link to “Certificates, Identifiers and Profiles” as shown below.
iOS Developer Program
First, create a new App Id, by navigating to that section:
New App Id
In, the add screen, enter any description and select the “Push Notifications” check box:
Push notifications
Also, in the bundle ID section, remember to include an explicit fully qualified bundle Id in the reverse domain notation, as wild-cards are not supported for push notifications:
Bundle Id

Create a new push certificate
Now, navigate to the certificates section, and create a new one. During creation, select the combo box as indicated below:
Development certificate
Next, select the app Id created earlier and when prompted, upload the Certificate Signing Request created earlier. If all goes well, the certificate will be generated. Download this certificate, and double click it to open it in the KeyChain tool. You would see the private key with the common name that you entered earlier when you expand the certificate. Remember to note that the certificate name is prefixed with “Apple Development IOS Push Services”. Select both the certificate and the key, right click and “Export 2 items”. It will prompt you to enter the KeyChain password and will generate a .p12 file that you will need later to configure the server side provider.

Generate a provisioning profile
The last step in this process is to generate a provisioning profile so that you can deploy the app on to the device. In the devices section of the portal, create a new device and enter the 40-character device Id you get from iTunes or the Xcode Organizer. Head over to the Provisioning Profiles section and create a new profile. Remember to select “iOS App Development as shown below:
Provisioning profile
In the next screens, select the App Id, device and certificate created in the previous steps to create the provisioning profile. Download the profile and drag it onto the profiles section of the Xcode organizer.

Now the painful part is done. Time to do some real work.

2 – Create the web service

A pre-requisite for this tutorial is Google App Engine, and getting a service up and running on it. If you haven’t done that before, follow the steps outlined in the getting started page and it should give you a good idea on how to work on this platform. It comes with good Eclipse integration so it should be a snap to get setup.

The framework I’ve used for APNS is java-apns which provides a simple API to APNS. Here’s all of the code I used to build out the simple service, this could be done in a simple servlet or a RESTful service on a JAX-RS implementation like Jersey for example:


InputStream inputStream = context
.getResourceAsStream("/WEB-INF/ApnsDevelopment.p12");

ApnsService service = APNS.newService()
.withCert(inputStream, "password").withSandboxDestination()
.withNoErrorDetection().build();

String payload = APNS.newPayload().alertBody(message).badge(1).build();

ApnsNotification notification = service.push(token, payload);

A couple of things to note, the .p12 file exported from the Keychain needs to be included in the war file (preferably in the WEB-INF directory to prevent public access) and password protected at export time. Also, it’s important to add the “withNoErrorDetection()” method as shown above as it would otherwise try to spawn threads to detect errors and would not run in the GAE environment since thread creation is restricted. The input into this web service is a 40-character token that is received from the device, and the message that is to be sent.

At this point, the server side work is done. Let’s move over to the client.

3 – Create the iOS client

For the purpose of demonstration and testing, I’ve created a simple single view application with the bundle ID specified in the provisioning profile.

The key methods you would need to implement in the AppDelegate would be:

-application:didFinishLaunchingWithOptions:
-application:didRegisterForRemoteNotificationsWithDeviceToken
-application:didFailToRegisterForRemoteNotificationsWithError
-application:didReceiveRemoteNotification

1) -application:didFinishLaunchingWithOptions:
This method gets invoked when the application finishes launching either directly or when launched through a push notification. In the case of the latter, the details of the push notification are passed in through a dictionary object so that it can be dealt with. Here’s the code to register for push notification alerts:

[[ UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];

2) -application:didRegisterForRemoteNotificationsWithDeviceToken
This method gets invoked with the device token received from APNS. This token uniquely identifies the device and is not the same as the UDID. The token needs to be sent to the web service so that it can pass it on to the APNS and have messages sent back to this device. This token includes some special characters and spaces which needs to be removed as shown below:

NSString *token = [ deviceToken description ];
token = [ token stringByTrimmingCharactersInSet:[ NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [ token stringByReplacingOccurrencesOfString:@" " withString:@"" ];

3) -application:didFailToRegisterForRemoteNotificationsWithError
This method gets invoked if there’s some error in registering for remote notifications which causes the push token to be not available for the app.

4) -application:didReceiveRemoteNotification
This method can be used to trap an incoming message while in the app, and take some action. In this case it just shows it in an alert view.

UIAlertView *alertView = [[ UIAlertView alloc ] initWithTitle:@"Push Alert" message:userInfo[@"aps"][@"alert"] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[ alertView show ];

To test this capability, I’ve built a test app that takes input text from a text field and sends it to the web service created in GAE. The resulting push notification is trapped and displayed in an alert view as shown in the sample code above.

Voila

Finally, a couple of things to keep in mind when developing apps that use push notifications:

  • It’s inherently unreliable, do not use it for transferring any critical information
  • While the transport is secured through TLS, it’s still advisable not to use APNS for company confidential information
  • Do not store your certificates in an accessible location on the web server. Password protect it for additional security
  • Store the device tokens safely on the server side, or users will be very upset if its compromised
  • It’s a good practice not to update information in the push notification handler code, since it may trigger updates without the user’s knowledge

That’s all for now. Enjoy!