Saturday, April 9, 2016

Call custom methods on Android app using a real device

Android developers have the benefit of testing on a device emulator which provides just about anything you need when developing. However, when QA is testing your Android app on a real device, they may need to override or customize certain functionality in order to test certain features. In this post I'm going to show you how you can create a way to call methods in your Android apps using the Android Debug Bridge(adb).

The problem

 Obviously you want your QA guys to test the real app as much as possible without having to mock up anything. Sometimes this is not possible and you need to dummy up some data or mock something to imitate the real world environment. For my specific use case I had an app that had to verify the phone number of the device. To do this we had to send a verification code via sms to the device and I have a custom SMS BroadcastReceiver that would intercept it and send the message back to the server to verify the device. Our QA device doesn't have a sim card so the device used for testing couldn't receive incoming texts. There was also one other use case that I'll mention later.

 After searching the internet long and hard I couldn't find anywhere that showed how to send a fake sms to a real device. There are several options for sending to an emulator but not for a real device. There are several apps that do fake SMS messaging but they somehow bypass the normal SMS functioning. I tried several but my SMS handling code never got invoked. So I had to figure out another way to get the device registered so that QA could test the app.

As a side note, our app did not allow the user to input the code. The app intercepted the SMS message and did it for them. If the app allowed the user to input the code, this would not have been an issue. Even so, this is still a useful method so don't get caught up in my use case details.


What is a BroadcastReceiver?

A BroadcastReceiver is a component that allows you to receive system events and events you want your app to fire. There's a good blog post about that here if you want to read more.

 For our app I developed an SMSBroadcastReceiver that registered to listen for all SMS messages and basically did the following:
  1. Parse out the registration code from the SmsMessage
  2. Send the code to our server for verification
  3. Save a boolean in user preferences indicating verification was successful
  4. Broadcast to the RegistrationActivity that registration was successful so the screen would refresh and allow the user to have access to the app

The solution

So I thought I could tackle this problem another way. I would create a "back door". I know, this sounds horrible from a security perspective but for this case it seemed pretty harmless and the user of the back door would have to have the verification code and a lot of knowledge about our app to use it. Also you can protect it with a hard coded username/password that will get obfuscated with progaurd if you wish.

 The Android Debug Bridge(adb) tool allows you to broadcast intents and send key-value pairs along with it. So all you have to do is register a QABroadcastReceiver to listen for custom intents. This BroadcastReceiver can pick out any data that you send to it via adb. Bam! We have a solution. I created one that allowed special commands to be sent that it would recognize. So if I broadcast a com.mycompany.android.SMS_CODE intent, and put a code=123 string in the intent, then the BroadcastReceiver would do everything the regular SMSBroadcastReceiver did without having to send the SMS.

Let's take a look at some code so you can see this in action!

Create the QABroadcastReceiver class

This class is simply going to show a Toast message that we send to it to prove that our method works.


Registering in the AndroidManifest.xml file

You can name the intent filter whatever you would like. In fact you can create multiple intent filters and use them like command names in your BroadcastReceiver. Or you can just use one intent filter and embed the commands as key-value pairs. It's really up to you.



That's all of the android code that we'll have to write. The rest is getting adb to broadcast a message that our BroadcastReceiver will...you guessed it, RECEIVE!

Setting up adb to broadcast messages to your app

If you have the Android sdk installed then the adb.exe is located in the sdk/platform-tools folder. You can download adb by itself but I haven't tested that download so try at your own risk. On windows I would recommend creating an environment variable for %ANDROID_HOME% pointing to your Android sdk location and editing the path variable to include %ANDROID_HOME%/platform-tools. That way you should be able to pull up a command line and type "adb" without the quotes and see that it starts the adb command line tool.

The adb command to invoke our BroadcastReceiver and log the message "Hello" is the following:

adb shell am broadcast -a com.mycompany.android.intent.QA_MESSAGE --es message Hello

Now that you have hooked in to your app on a real device you can pretty much invoke whatever you would like. You just have to create the custom functionality in your QABroadcastReceiver.

Other use cases

You can do lots with this. Another use case was that we had an auto-refresh on one screen, where if the last refresh time was more than 1 hour ago, we would auto refresh the data. For QA this is a pain! So I added functionality to set this to x seconds so that QA could set it to whatever they liked and not have to wait a whole hour to test.

A word of warning

Don't go too far with this though. You don't want your app that QA uses to be very different in functionality from production. Use this as a last resort and evaluate the risk of missing a potential bug by using this. Also depending on the nature of your app this may be too risky from a security standpoint so just use common sense.

Summary

So in this post we created a custom BroadcastReceiver to do our bidding on a real device! Once you have this in place you can can build custom functions to override pretty much anything in your app. I hope this helps someone in the future. Please leave comments and let me know what you think.

Thanks for reading!

Tuesday, March 22, 2016

Supporting Multi-tenancy with Spring AMQP

In this post I'm going to discuss how you can publish messages to RabbitMQ via Spring AMQP to different vhosts with a single ConnectionFactory.

Lets say you have the need for a single application to send messages to multiple vhosts. You might use this method to support securely sending messages to multiple clients, each one with a different username/password. With Spring AMQP the way in which you connect to a vhost is by creating a ConnectionFactory which is an interface with the main implementation being a CachingConnectionFactory. The problem is that this will only allow you to connect to a single vhost. Luckily ConnectionFactory is just an interface and as of spring-amqp 1.3 there is now an implementation that allows you to "route" to other connection factories via an abstract class called AbstractRoutingConnectionFactory which uses a Map of connection factories. One implementation is SimpleRoutingConnectionFactory which uses a thread bound context to determine the key to the Map.

So we need an Event class to encapsulate our message, and a Service for sending it. Let's do that here:

As you can see from the above code we have created our event interface and an implementation and also a service with an implementation. The service is responsible for binding and unbinding the thread bound context to the clientId for proper routing of the message. The rest is just standard spring-amqp code to send the message via the RabbitTemplate.convertAndSend method. The next missing link is the Spring configuration to glue all of this stuff together. Let's do that next!

In the above code we have a Spring configuration that wires up the MyEventService with a RabbitTemplate that is configured with our SimpleRoutingConnectionFactory. Please note that I have not included any auto configuration of Queues or Transaction management here because that's outside the scope of what I'm trying to cover here. Finally all we have to do is obtain a MyEventService from the Spring ApplicationContext and send a message.

In the above program we obtain the MyEventService from the ApplicationContext and send an event that gets routed to each client. All the magic is in the SimpleRoutingConnectionFactory.

Possible Improvements
One limitation to this solution is that you have to know the vhost connection information at the time the application is started. So if you get a new client, you will have to at worst make a code change and at least bounce the server. The way I have overcome this is by extending the SimpleRoutingConnectionFactory and creating an implementation that creates connection factories at run time based on a Clients database table. I will create another post in the future about how to do this.

Summary
In this post we created a generic MyEvent class that holds information about the event message and how to route it.We also created a MyEventService that handles sending that event to the configured RabbitTemplate. We also configured our RabbitTemplate to support multiple vhosts to support a multi tenant architecture. I hope this gives you an idea about how to implement such a solution in your applications.

Please feel free to leave questions or comments below. Thanks for reading!

Monday, March 21, 2016

Automatically login developers in a Wicket Application

When developing an application it's time consuming to have to login every time you start up the app to test a new feature. In this post I'm going to show you how you can set Java system properties to automatically log you in to a Wicket Application.

Wicket allows you to customize how authentication works via the IAuthenticationStrategy interface. I have created an implementation that reads a user and password system property and logs you in only if the Application is in development mode.

The nice thing here is that it's not enabling a "magical" username and password back door. The credentials you specify MUST be valid credentials and the application must be in development mode so there is no risk of you creating a security hole by using this.

To configure your application to use this you must set this as your authentication strategy in your Application.init method(which is stated in the javadoc of the code snippet). It should look like this:
getSecuritySettings().setAuthenticationStrategy(new DeveloperAutologinAuthenticationStrategy());

If you are using eclipse then it's easy to specify these in your run configuration. Below I have included a screenshot of what mine looks like. Notice the yellow highlighted area.

Now when you start your app and navigate to the home page you will be automatically logged in!

Enforcing Semantic Versioning in your Maven project with japicmp

I'm a big fan of Semantic Versioning. Recently I have been working on breaking our monolithic web applications into smaller "plugins". The first step in such an endeavor is creating an API between the main application and your plugins. My concern in doing that was that it is very easy to break compatibility and roll out a change that crashes the app or causes some feature to crash. After all semantic versioning is just a convention. I needed a tool to enforce the convention. japicmp to the rescue!

Basically you configure the plugin to point to an artifact that represents your API level. It compares the binary compatibility between your project and that one to ensure you have not broken compatibility.

Here are a couple of quick tests I did to make sure this would do what I wanted. Keep in mind that the API version is 1.0.0 and my current project version is 1.0.0-SNAPSHOT unless otherwise specified.
  1. I added an argument to a method in a public interface. I expected it to break since this would certainly break compatibility. You should increase your MAJOR version number if you are going to do this.
  2. I increased my MAJOR version and retested #1. The build succeeded.
  3. I added a method to a public interface and it broke the build. I should increase my MINOR version if I'm going to make this change.
  4. I increased my MINOR version and retested #3. The build succeeded.
  5. I changed the internal implementation of a concrete class and the build succeeded.
At this point I was pretty convinced. I know there are many more scenarios to test but this is a good start and it seems pretty promising. Here's the plugin configuration I used in my pom file.

I should mention there are other alternatives out there. Although this one is the only one that passed my "sniff" test and my actual tests. I'll list the other ones I looked at here and why I didn't choose them. I think as Software Engineers it's always important for us to look at several options when possible and choose which one fits our needs best.

http://www.mojohaus.org/clirr-maven-plugin/
This one is really flexible but it's not set up specifically for Semantic Versioning. I wasn't able to configure it to pass my tests above but it might be possible.

https://github.com/jeluard/semantic-versioning
This one is really straight forward and is actually not a plugin itself. It is a couple of rules that can be configured in the maven enforcer plugin. I didn't test this one because at the top of the README it states that it is dormant and actually suggests we look at japicmp.

Here's the link to the maven documentation for japicmp. You should definitely check it out if you are wanting to enforce Semantic Versioning in your projects.