AWS SNS and Slack Integration

Slack is an awesome tool. Rich set of integrations with AWS and popular APIs make IFTT use cases a breeze. I had recently integrated our JIRA installation to slack for production release notifications to create a timeline of releases plus prodops tasks.

Looking at AWS Lambda today i thought of integrating our production alerts into our Slack prodops channel. Amazon SNS has an HTTP payload that is not compatible with the Slack Webhooks so i needed a transformer in between.

Here is the node.js and AWS Lambda hello world. Select AWS Lamba function as a subscription in the SNS Topic and you are good to go.

Look Ma, no servers.

console.log('Loading function');
var https = require('https');
var async = require('async');

exports.handler = function(event, context) {
	event.Records.forEach(function(record) {
		var notification = record.Sns
		var postData = "payload=" + JSON.stringify({ 
				"text" : notification.TopicArn + ":" + notification.Subject +":" + notification.Timestamp + notification.Message
			});

		var options = {
			host: 'hooks.slack.com',
			path: 'SLACK API PATH',
			port: '443',
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded',
				'Content-Length': postData.length
			}
		};
		async.waterfall([
			function(next) {
				var req = https.get(options, function(res) {
					next(res);
				}).on('error', function(e) {
					console.log("Got error: ", e);
					next(e);
				});
				req.write(postData);
				req.end();
			},
			function completed(d) {
				console.log(d);
				context.succeed(event.MessageId);
			}
		]);
	});
};

Flying a S107G with your android

I recently bought a S107G RC Copter for my daughter :-). I would say this is an incredible piece of work, super stable and robust. These are the best spent 20$.

I had plans to fly the copter outside then i realized that it was an IR controlled copter so it can flown indoors only. So what next.. Lets try to write an app which can fly the copter. Doing some research led me to this blog on decoding the IR protocol for S107G. It is very interesting how the protocols are reverse engineered (worried about keyless entry to your car now).

I do not have an IR transmitter for arduino so i had to use my S5 for this.

After struggling for a weekend i was able to understand the blog , how IR works and write my first Android app. App is able to control the copter but i am guessing that the phone is not realtime enough to sustain the IR transmission (or my code is buggy). Sometimes copter does not respond to the app, it loses throttle as well( so it is best to use the supplied controller). This POC is just for fun and keeping your mind of work during the weekends.

AWS IAM : Too complicated for your own good

AWS IAM Framework is very flexible and extensible. But it defeats the purpose when you cannot figure out what permissions are required for an operations role like deployment using Beanstalk.

AWS introduced managed policies to ease the pain. “AWSElasticBeanstalkFullAccess” seems like you are giving beanstalk access to an ops guy but behind the scene you give all access and make him/her a power user.

{
    "Statement": [
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

A Facebook and Google App Engine mashup app

It was Friday evening, eve of Cricket World Cup 2011, all the news channels are picking up their favorites for the next match. It is then that i thought of “Paul the Octpus” (may his soul rest in peace) and his predictions. So i took upon the task to build a Facebook app using Google APP Engine (GAE) as the backend.

The Motive behind this app is to compare winners chosen by careful analysis (use feedback) and some sort of random pick (team on left) and see how much the two differ at end of the world cup (i app has only two users 😦 and predictions are 100% till date). GAE gave a free hosting and moreover i do not know a thing about Facebook app or GAE so it should be good learning.

Continue reading

Disabling services in Ubuntu

I install quite a few things on my laptop and some softwares start as services. E.g Mysql , apache. I donot want these applications all the time, they slow down my laptop.

One option is to stop them everytime using
sudo initctl stop jobname

Or go to /etc/init and rename the job conf to something job.conf.noexec (anything other than .conf).
To disable old style jobs that are non upstart use following utility and mark the job to not start in runlevel 3.
sysv-rc-conf

XML vs JSON : What does google insight say?

Just stumbled upon Google insights. A very interesting perspective on search statistics.

It shows the decline of XML and rise of JSON.

Update: As per one of the comments on HN, the scales of two graphs are not same, so xml enjoys the bigger volume but is on decline.  The intent is to show the relative search trends ( which kind of reflect the popularity, you may argue not always, but mostly it does)

XML Trends:

JSON Trends:

So it is Google who writes history now.

Groovy: Strange things

Does writing some code as a Script or as a class in Script make any difference?

I started out with some practice on Groovy builders as reading alone was not giving me any confidence (and not to mention that groovy documentation is not up-to-date). By this time i was confident that i knew a thing about groovy method invocation.

I started with a custom builder. Then wrote a script to test it. Running the script spits out the error message (Missing method exception). I pondered over this for quite sometime and was not able to figure out what was wrong. Is’t this what a BuilderSupport is supposed to do. I decided to write the script differently, creating an enclosing class. This time the error message was different. Cannot find missing method positive. This error message pointed out exactly what was wrong in the builder that i wrote. I copied pasted a plus sign in my code at line 29 in TreeBuilderWithSupport.

But still no clue on why the script ate the actual exception & there was no reference to BuilderSupport in exception stacktrace. Will try to find this out on groovy forums & a better way to debug groovy code. Update: use dump() or inspect the metaclass.

The builder code does not do much and was intended to print a tree (expanded/collapsed). Groovy’s documentation is turning out to be a disappointment, most of the pages turn out to be out of data or incomplete. package builder;

import java.util.Map;
import groovy.util.BuilderSupport;

class TreeBuilderWithSupport extends BuilderSupport{

	def out = System.out

	protected Object createNode(Object name) { out << name + "\n" return name;}

	protected Object createNode(Object name, Object value) { out << name + "($value)" return name;}

	protected Object createNode(Object name, Map attributes) { out << name attributes.each {  out << "$it.key : $it.value  " } out <<  +"\n" return name;}

	protected Object createNode(Object name, Map attributes, Object value) { out << name  attributes.each {  out << "$it.key $it.value  val=$value" } out << + "\n" return name;}

	protected void setParent(Object parent, Object child) {}

	def missingMethod(String m, args) { out << "missing"}
}
package builder
def tb = new TreeBuilderWithSupport();

tb.tree {  
	level1 (a:1, b:2) {   
		level2{    
			level3 {    
			}   
		}  
	}
}
Caught: groovy.lang.MissingMethodException: No signature of method: builder.TestTreeWithSupportAsScript.level1() is applicable for argument types: (java.util.LinkedHashMap, builder.TestTreeWithSupportAsScript$_run_closure1_closure2) values: [[a:1, b:2], builder.TestTreeWithSupportAsScript$_run_closure1_closure2@147917a]Possible solutions: every(), every(groovy.lang.Closure) at builder.TestTreeWithSupportAsScript$_run_closure1.doCall(TestTreeWithSupportAsScript.groovy:6) at builder.TestTreeWithSupportAsScript$_run_closure1.doCall(TestTreeWithSupportAsScript.groovy) at builder.TestTreeWithSupportAsScript.run(TestTreeWithSupportAsScript.groovy:5)
package builder

import groovy.xml.MarkupBuilder;

class TestTreeWithSupport {

public static void main(String[] args) {  
	def tb = new TreeBuilderWithSupport();

	tb.tree {    
		level1 (a:1, b:2) {     
			level2{      
				level3 {      
				}     
			}    
		}  
	} 
}
Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.positive() is applicable for argument types: () values: []Possible solutions: notify(), size(), tokenize() at builder.TreeBuilderWithSupport.createNode(TreeBuilderWithSupport.groovy:29) at builder.TestTreeWithSupport$_main_closure1.doCall(TestTreeWithSupport.groovy:11) at builder.TestTreeWithSupport$_main_closure1.doCall(TestTreeWithSupport.groovy) at builder.TestTreeWithSupport.main(TestTreeWithSupport.groovy:10)