Saturday, January 27, 2018

Integration Testing first RESTful web service with Kotlin and Spring Boot

We have been building a lot of infrastructure using Kotlin and Spring Boot -- And I am loving it! I have decided to start documenting parts of it for my own reference. I also hope my rant is useful to someone else, who's trying to solve similar problems :D

In this post we will be looking at building our very first RESTful web service using Kotlin and Spring Boot and writing an integration test for it. We will be using Gradle as our build tool.

Gradle File

First important component in the puzzle is the Gradle file. Following is the complete gradle file that we will be using for this post. Notice the use of all-open plugin. This is needed so that Spring can Autowire dependencies into our Kotlin classes.


Lets create a very simple Book data class, it has got properties like title and author.

Adding a BookController, it has only one method which serves the requests from /books/search?title={title} path. This method will return the details of the books whose titles contain the searched term.

Note: The books collection is hardcoded for this example but nothing stops us from getting it from an external source, e.g. a database.

Next we need to add the application class which will expose the main method.


The fun part about Spring Boot + Kotlin is the ease of testing this service. We will test this service out in two ways

  • Testing the API in browser
  • Writing a integration test 

Browser Test
  • Boot up the server using the following command
  • If everything goes great you should see a message informing that the server is up and running.
  • Open up the browser and open the http://localhost:8080/books/search?title=Steve
  • You should see the following response in the browser

Integration Test

Spring Boot provides a convenient class TestRestTemplate to test out the REST api's. Here is an example test for testing our API

As you run the test, notice that it boots up the server, invokes the api and fires the asserts on the responses!


The toJson and fromJson methods are extension methods, they convert Objects into JSON representation and visa-a-versa. I use them all the time, they are pretty handy!

Project Structure

The best way to show this is via a screenshot.

Thats about it, we have a web service written in Kotlin using Spring Boot and we have successfully written a test for it as well!

PS: Here is the complete source code of the example used in this post

Friday, September 30, 2016

ICICI Bank and their goof-up's!

This is yet another post to highlight goof-up's made by ICICI Bank (one of the biggest banks in India).

What I wanted to get done?

My current debit card had a problem because of which it used to work in some ATM's and some ATM's refuse to accept it.  All I wanted, was to get a replacement debit card.

Goof-up 1
  • I went to the ICICI Bank branch which is almost next door to where I stay.  
  • Told them I want to get a replacement debit card
  • The bank representative took the request and assured that the card will be delivered in 10 days
  • To my surprise after a few days I received a message saying my new cheque book has been dispatched to my communication address.
  • So although I wanted a replacement debit card they decided to send me a cheque book instead :P
Goof-up 2
  • Since visiting the branch didn't seem to solve my issue, I decided to place the request for my replacement debit card using Phone Banking.
  • The lady took the request and gave me the tracking number as well.  
  • I checked with her, the address to which the card will be delivered and it was accurate
  • She assured me that the card will be delivered in 10 days.
  • After a few days, I got an SMS saying the card has been dispatched and I got the tracking details of the card as well.  The card was being dispatched from Delhi.
  • To my surprise, I found that the card was going to Ahmedabad!  
  • From Delhi why would the card go to Ahmedabad when I stay in Pune?
  • I called up the call centre to find out whats going on.  The lady said that, "from Ahmedabad it will come to Pune, don't worry".
  • To my horror when I tracked the card again (after a couple of days) it said it was delivered to someone in Ahmedabad!
  • I immediately called the call centre and they said its delivered to some ICICI Branch at Ahmedabad.  The lady said that she is marking an email and ensuring that the card gets delivered to my Pune address from Ahmedabad.
  • I was like WTF is going on!  
Goof-up 3
  • After a few days I realised that they have send the card from Ahmedabad to my old communication address @ Ankleshwar via Speed Post.
  • Obviously, I don't stay there right now, so I called the callcenter and told them about this error and asked them to recall the card immediately.
  • The lady again assured that the card won't be delivered since you are not staying at that place and will come back to one of the ICICI Bank branch.
  • This was getting tricker by the minute.  
  • After a few days another Surprise, the card was delivered to my old communication address to someone without even checking for ID Proof.
  • Wait wait there is more, even the debit card pin got delivered to the same place.
  • I was lucky that it was collected by my old neighbour but it could have very easily landed into hands of any un-trust worthy person.
  • By this time I was fed up with them and I decided to write to them about the whole episode and here is their response:
We inform you that as you are in non receipt of the debit card, you may call customer care and block the debit card through IVR and place the request for reissue of the debit card to be delivered to any of your nearest ICICI bank branch so that it gets delivered in 05 working days and you may collect it from the branch.
  •  They tell me to block the debit card number which was not delivered to me - Then how the hell would I know the number @#$@#$
  • They also asked to request a replacement debit card all over again!! - Its like, I have nothing else to do in life but to play Debit Card, Debit Card with ICICI Bank.
I fail to understand how such a big bank which is supposed to have state of the art software and facilities can operate like a bank from 1980's?

PS: All events mentioned in this post are completely real and I would recommend everyone dealing with ICICI Bank to be extremely careful with your account and its security.

Friday, July 29, 2016

Monster Math - Journey to the Android launch!

Its been a thrilling roller coster ride for all of us at Makkajai.  I remember the days when we were building our first game Monster Math Classic on iOS,

  • We had no clue of how to develop a game?
  • How to market it?
  • How to get customers etc.  
All we knew was that, we had an idea and a lot of determination to execute it :D

In November 2014 we launched Monster Math Classic our first game on iOS.  Even though this was our very first game, we still managed to get lot of love from parents, teachers and students.  They had very kind words to say about our game.  Not just that, they also gave us some very awesome feedback, which could take user engagement to the next level.  We heard our customers and we incorporated their feedback which made them even more happier.

Somewhere in October 2015 we launched two new games Monster Math and Monster Math Multiplayer which got an even better acceptance than Monster Math Classic.  All these were still iOS only games.

One question which kept on coming from our customers was: When is it getting launched on Android!

It was not as if we didn't want to launch on Android.  We wanted to, but since our game was using Cocos2d (A game engine only for iOS), we couldn't do it just by a flip of a switch.

Somewhere in March 2016, we decided we need to launch our game on all major platforms, so that more and more kids can take advantage of our solution.  We started the effort on porting Monster Math solution to Cocos2dx.

When I first started to port, it felt like a never ending task.  We had around 50K+ line of Objective C code to be ported to C++.  Just the though of doing this humongous task -- that too all alone -- gave me nightmares :D.

There were many many problems to solve before we could could even compile an APK.  But as our dear friend Mark Watney (The Martian) says:

At some point, everything's gonna go south on you... everything's going to go south and you're going to say, this is it. This is how I end. Now you can either accept that, or you can get to work. That's all it is. You just begin. You do the math. You solve one problem... and you solve the next one... and then the next. And If you solve enough problems, you get to come home!

So thats exactly what we did, we started solving one problem at a time.  First problem was how can we quickly port Objective C code to C++ with minimal effort?

Instead of manually re-writing 50K+ line of Objective C code to C++, I wrote a quick and ugly Objective C to C++ translator.  It reads and parses any Objective C file and translates code into C++.  Simple right?  This translator does not generate compilable C++ code (because that would be difficult and time consuming).  It only get 90-95% of the job done!

This one step alone saved us few months of mundane work :D

  • After the initial translation was done, I manually fixed the compilation errors.  
  • Replaced Core Data/Realm with SQLite.
  • Added memory management code, since there is no ARC to cover us.
  • Replaced various SDK's with cross-platform equivalent.
  • Where a cross-platform equivalent SDK was not available, we used platform specific code to integrate native SDK's.
After solving innumerable such small problems, on July 14 2016 (after around 4 months of starting the project) we launched Monster Math on Android!

I am very grateful to have gotten this opportunity, I learned (and unlearned :P) so many things in such a short duration.  I am super excited (and proud at the same time) to have achieved this feat.

Finally, I hope Monster Math on Android gets even more love from its users.  Keep Calm and Have Fun!

Thursday, June 30, 2016

How to enable Immsersive Full Screen mode on Android with Cocos2dx

We are executing a project to port our flagship solution Monster Math 2 from Cocos2d to Cocos2dx.  This would enable us to release the solution on variety of different platforms including Android and Windows Mobile.

During the port, I came across one simple yet interesting problem -- Need to make the game UI truly full screen.

A lot of the Android devices have software navigation buttons at the bottom of their screens.

Android System Navigation Buttons
They seem to occupy part of the screen and block some part of the game UI.  Needless to say this does not give a great experience to the end users.  A better experience would be to hide these buttons.  But hey, if they are hidden then how do users navigate to the home screen or different apps?

Ideal experience would be to hide System navigation buttons at all times, but have some gesture to bring them back for a short duration when user needs them.

Android 4.4 (API Level 19) natively supports this functionality using the flag "SYSTEM_UI_FLAG_IMMERSIVE_STICKY".  This mode is called the immersive full screen mode.  When immersive full-screen mode is enabled, game continues to receive all touch events.  The user can reveal the system bars with an inward swipe along the region where the system bars normally appear.  System bars will automatically hide again after a few moments.  Perfect isn't it!

Usually setting this flag is enough to achieve the desired functionality, however in certain edges cases we need to do some additional work.  For example if you have a text field which accepts user input, once the on screen keyboard is dismissed the system navigation bars seem to stick around and do not hide until you kill the app and open it again.

In this post we are going to see how exactly to handle all situations so that the immersive full screen mode will always stick around for the app.

How Do They Do It!

What we need to do is basically setup SystemUiVisibilityChangeListener and FocusChangeListener and hide the system status bars in the callbacks.

Here is the sample code on how to do it.
That's it.  Once you run this Activity you should see that the game launches into immersive full-screen mode and remains in that mode!

Tuesday, May 31, 2016

How to write to Google Sheet from an iOS app - Part 3

In the previous post we saw how we could extract various identifiers from the Google Form.  We will use these identifiers from the iOS app to do HTTP POST and submit information to the Google Form.

How to do HTTP POST to Google Form from iOS App

This is by far the simplest step of all.  We will be using the open source iOS library AFNetworking for doing the actual POST.
  • We first need to build a dictionary of all the POST parameters we want to submit to Google Forms using the identifiers extracted in the previous post
  • Then we need to set proper request and response serializers
  • We need to set the content type as "text/html".  Thats because Google Form will return HTML response
  • And finally we need to make the actual POST call.  AFNetwork accepts success and failure callbacks will will be called depending on whether the call succeeded or failed.
Once this is setup, test it out, on successful POST the data should be getting written to the backing Google Sheet.

Thats all folks.  We have concluded our three part series of how to write to Google Sheet from an iOS App!

Friday, April 29, 2016

How to write to Google Sheet from an iOS app - Part 2

In the previous post we saw how we could setup the Google Form to write to Google Sheet.

We will need 2 additional steps to submit information to Google Form from iOS app.

  • Extract the various identifiers (like URL, field id etc) of Google Form
  • Use the identifiers in the iOS app to do an HTTP POST to Google Form
In this post we will focus on the first step only.

Extract Identifiers From Google Form

  • All we need to do is click on the "Preview" button on our google form page.

  • It should open up our form as below

  • Right click on the form and say "Inspect".

  • If you are using Chrome brows, it should open up a panel below the page which looks something like this

  • Find a tag called "<form>" in the panel, there you should look for "action" attribute.  This attribute has a big URL as its value.  Save this URL we will to POST to this URL from our iOS app.

  • Next, Right click on the input field in your form and click "Inspect".  It should show "input" tag highlighted in the panel below.

  • We are not really interested in the input tag that the panel is showing, 
  • We need to find another input tag which is of 'type="hidden"'.  This input tag would be 8-9 lines below the input tag currently highlighted

  • Note down the value of "name" attribute on the input.  Do the same thing for other fields in the Google Form.  These keys will be used when we submit information from our iOS app to this form.

Once we have these identifiers noted we are left with one last step i.e. to do the HTTP POST from iOS app to Google Forms.  We will see how to do that in the next post.

Thursday, March 31, 2016

How to write to Google Sheet from an iOS app - Part 1

Recently we wanted to write some information to Google Sheet from our iOS app Monster Math.

There does exist an Objective C library that could directly write to the Google Sheet, but the API it exposes did look cumbersome.  What we did instead was a very simple hack.

  • We setup a Google Form with all the information we wanted to write to the Google Sheet.  
  • We then configured Google Form to write the responses to a Google Sheet.
  • This enabled us to directly submit information to Google Form using HTTP POST and responses will get written to Google Sheet automatically!
In this series I will explain how we could do the above steps.

Creating the Google Form

This is gonna be the super easy part.  
  • Login with you google account here
  • Click the big Plus icon to add a new form
  • Set the title as "My Survey".  If you want you can also add optional form description.

  • Next its time to setup questions which will act as columns in your Google Sheet
  • Lets setup two questions "Name" and "Age".
  • Enter "Name" in the text field that reads "Question"
  • Change the type of the Question from "Multiple Choice" to "Short Answer"

  • Similarly add one more question with title "Age" and of type "Short Answer".
  • After the setup your from should look like the image below.

Our Google Form is ready for use.  Now we just need to link it with a Google Sheet so that our responses get written there.

Link Google Form with a backing Google Sheet
  • Click on the "Responses" tab.
  • There you should see a green Google Sheet icon, click that.

  • It should prompt you to create a new Google Sheet with name "My Survey (Responses)", create it.

  • This should open up a Google Sheet which looks something like the image below.


Thats about it, you have successfully setup Google Forms to write its responses to Google Sheet.  You can verify the setup by clicking the preview icon on the Google Form.

It should open up the form which should look like the image below

Go ahead and submit some dummy information to test the setup.  This information should be written to the Google Sheet automatically.

Congratulation on reaching this far, the configuration part is over.  All we need to do is hook up this form from iOS app, we will cover that in the next post. 
Have some Fun!