Thursday, June 27, 2013

Chef clients bulk delete

===============================ACHTUNG===============================

If you want to remove all clients from chef-server, then DONT use below command

knife client bulk delete *

instead use

knife client bulk delete '^(?!(chef|cli))'

it will not delete the clients used for proper functioning of chef server , like chef-validator , chef-ui etc


Tuesday, June 11, 2013

Updgrade Chef-Solo for vagrant

Vagrant, by default, uses an older version of chef-solo and you may run into problems because of that. Please follow the instructions in the readme file here to upgrade chef-solo to latest version for vagrant.

Wednesday, August 15, 2012

My Little Spy Function

I needed to spy on functions of an object and quickly came up with this little code to do much as i wanted.. For more advanced spying on javascript functions in your tests, consider using sinon.js or some other framework.
function Spy(funcName,obj){

 var originalFunction ;
    if(typeof obj === 'object'){
        originalFunction = obj[funcName];
    }
    else{
        originalFunction = global[funcName]
    }

 var numCalled = 0;
 var invocations = [];
 var spy = function(){
  numCalled++;
  invocations.push(arguments);
        if(typeof obj === 'object')
  return originalFunction.apply(obj,arguments);
        else
            return originalFunction.apply(global,arguments);
 }
 spy.calledOnce = function(){
  return numCalled == 1 ? true : false;
 }
 spy.times = function(num){
  return num == numCalled ? true : false ;
 }
 spy.firstCallWith = function(){
  return invocations[0];
 }
 spy.nthCallWith = function(n){
  return invocations[n-1];
 }
    if(typeof obj === 'object'){
        obj[funcName] =  spy;
    } else {
        global[funcName] =  spy;
    }
 return spy;
}
Now to spy on function emit of Dummy socket module below
var Socket = function(){
    function emit(name,message){
    }
    return {
        "emit" : emit
    }
}
exports['Line Parser not invoked since no socket is connected'] = function(test){
    test.expect(1);
    //given
    var socket = new Socket();
    var spy = new Spy("emit" , socket);
    //Run the test
    //verify the spy
    test.ok(spy.calledOnce(), "Socket.emit has been called once");

    test.done();
}

Monday, May 21, 2012

Maven in offline mode

I needed to tell maven to search my local repository only i.e maven should not try to connect to central repository.
Solution: just add -o flag like

maven -o clean install


Wednesday, April 25, 2012

Chef : Notify resource from ruby_block

Lets say for some sane/insane reason , you want to notify a resource to take some action from within ruby_block , you can accomplish it as follows


ruby_block "dummy" do
    block do
        if some_condition_is_true
           resources(:file => "create_file").run_action(:create)
        end
    end
end

file "create_file" do
         path "/tmp/test.txt"
         owner "you"
         content "dummy"
         action :nothing
end

Caveat :

       If file resource "create_file" further notifies another resource , that resource will not be notified. What i mean to say is that calling a resource from within ruby_block by using run_action method directly does not build up the notification chain . For example if file resource was as below


file "create_file" do
         path "/tmp/test.txt"
         owner "you"
         content "dummy"
         action :nothing
         notifies :run , resources(:execute => "some_script")
end
and file resource is notified from within ruby_block , then file resource will not further notify "some_script" resource.

Sunday, April 22, 2012

Game Of Life

Just finished Basic "Game Of life" simulation on HTML5 canvas. Here is the demo and here is the source code

I used kineticjs library to interact with canvas.

Thanks "this site" for button.

Monday, April 9, 2012

Nodejs Express : request.body is null

Just had an other frustration with nodejs and this time again problem with header and fault was mine since i missed Content-type header.
While writing a nodeunit test ,

exports.parseRequest = function(test){
 http = require('http')
 test.expect(1)
 options = {
  "host": "127.0.0.1",
  "port": 3000,
  "path": "/movies/",
  "method": 'POST',
  "headers" : {
   Content-Type":"application/x-www-form-urlencoded"
  }
 }  
 request = http.request(options,function(response){
  console.log("Status "+response.statusCode)
  result = ''
  response.on('data',function(chunk){
   result += chunk
  })
  response.on('end',function(){
   response.destroy() 
   test.equal(result,"Hello World", "Reponse got")
   test.done();
   
  })
 })
 request.on('error' , function (connectionException){
   console.log("ERROR occured while creating connection to localhost "+connectionException);
 })
 request.write("data=sheat");
 request.end();
}
and there you go , i missed that content-type header on line 10 above and ended up wasting 30+mins to figure out why request.body is 'undefined'. >Make the header adjust according to content , application/json etc

Friday, April 6, 2012

Nodejs : not sending host header by default


After having heard about nodejs for so long now , i decided to play with it today and unfortunately ended up in frustation when i was not able to make the below <20 lines code execute successfully.


var connection = http.createClient(80, "localhost");


var request = connection.request('GET', "/");

request.end();


request.on('response', function(response){
 
  var result = "";
  console.log(response.statusCode)
  response.on('data', function(chunk){
   result += chunk;
  })
  response.on('end', function(){
   console.log(result);
  })
  
});
 
connection.addListener('error' , function (connectionException){
 console.log("ERROR occured while calling Rotten Tomatoes Api "+connectionException);
})

I was initially making call to rottentomatoes api and was getting 400 , Bad request.
I changed hostname to localhost ( i had apache running locally) and was more frustated to see the same 400. This prompted me to check the apache error_log and this is what i was getting there

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23):

and little googling told me that nodejs does not send the host header by default [Stumped]. so i had to manually add the host header like below.
var request = connection.request('GET', "/" , {"Host":"localhost");


I am not sure but i think it should be a good idea to include some common headers by default in the request sent by nodejs.

Thursday, September 1, 2011

My Csv Parser For Java


import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 *
 * @author Rizwan Sharif
 *
 */
public class CsvParser {
                /**
                 * Original Regex without escaped qoutes:  ("(([^"]|"")+)"|([^,]+)|,)(?=(,|$))
                 * Regex explained :
                 * First Part : "(([^"]|"")+)"  if value starts with " then it can either be followed by any character not "  ([^"] or by "" , one or more times
                 * Second Part : ([^,]+) for simple values : any character except ,
                 * Third Part : ,  can be only comma
                 * Forth Part : all above three parts should be followed either by comma or by Endline.
                 */
                public static final String CSV_PATTERN = "(\"(([^\"]|\"\")+)\"|([^,]+)|,)(?=(,|$))";
                private static Pattern csvRE;

                 public CsvParser() {
                            csvRE = Pattern.compile(CSV_PATTERN);
                }
                 public List<String> parseLine(String line) {
                            List<String> list = new ArrayList<String>();
                            Matcher m = csvRE.matcher(line);
                            // For each field
                            while (m.find()) {
                              String match = m.group();
                              if (match == null)
                                break;
                              if (match.endsWith(",")) {  // trim trailing ,
                                match = match.substring(0, match.length() - 1);
                              }
                              if (match.startsWith("\"")) { // assume also ends with
                                match = match.substring(1, match.length() - 1);
                              }
                              if (match.length() == 0)
                                match = null;
                              list.add(match);
                            }
                            return list;
                  }
}

Saturday, June 11, 2011

Javascript: How Double And "&&" Works

Recently this question baffled us all.Coming from other languages we would expect that following line

var result =  true && "Rizwan" ;

assigns true or false to result variable (true in above case) but if you do "alert(result)" in next line , you see "Rizwan" in the alertbox instead of true.Confused? Read till end and it will be clear.

Javascript and Falsy Values

    In javascript following are considered false

  •    false
  •    0
  •    null
  •    undefined
  •    "" ,empty String
  •    NaN (Not a number , like 0/0)


Everything else evaluates to true.

Keeping this in mind , we go back to our problem

var result =  true && "Rizwan";

In javascript && operator evaluates its first operand and if its true, it returns whatever is the second operand ("Rizwan" in the above case) .

And if first operand is falsy value , && operarot just returns that first operand.

var result =  null && "Rizwan"; // result will contain null

Similary || operator returns its first operand if its true , otherwise it returns it second operator if first operator is a falsy value. 

Friday, March 25, 2011

Hotlinking

Hotlinking:
Let's say i own example.com and i have webpage test.html accessible through www.example.com/test.html and test.html is codes as

<body>
          <img src="rizwan.com/image1.jpg"/>
</body>

Now when you load example.com/test.html , image1 will be loaded from rizwan.com and not from example.com. So i have hotlinked image1 from my webpage to rizwan.com

Problem:
             Since bandwidth is charged, and i have asked your browser to show that 500KB (lets assume) image1 from answer.com , answer.com is going to pay for that bandwidth , not example.com. Hence bandwidth theft.

Solution:
            Http Referrer can be used to identify if image1 is being linked from any other site except answer.com. If yes , then we can simply reject the request or do whatever you like.
How can we check the referrer? Well Conditional Rewrite rules can help.

RewriteCond %{HTTP_REFERRE] !^http://(www\.)?answer.com/.*$
RewriteRule \.*/image1.jpg$ /image/sucker.jpg [L]


Well , first condition checks if referrer is anything except our website, if yes then next rewrite rule is excuted and alternate image is sent instead of image1.jpg, You can as well return 404 , a low bandwidth image etc

Thursday, October 7, 2010

Bypass Query Over Limit For Geocoder: Google Maps API

Recently I needed to get Longitude/Latitudes of long list of cities.(more than thousand cities)
I used Geocoding API of google maps.  Using this API  , i sent individual requests to google geocoder passing in the name of individual city and storing back the longitude and latitude it returned.

Since i looped over the name of the cities , requests to geocoder were sent too quickly. and i got back the result 'QUERY OVER LIMIT' . Infact google had specified a query rate limit , you cannot send too many requests in quick succession of time. I am not aware what actual rate limit is used by google , but some hit and trial showed me that if number of requests was kept to 15/s then it was fine.

So i needed a way to sleep my loop after every 10 iterations (using 10/second rate ) . Now first thing that comes to your mind is 'hey use sleep function ' . Ah i wish i could but javascript supports no 'sleep' or 'wait' functions.

So what then? Use setTimeout("function name" , time in milliseconds) . it calls the 'function name' after 'time in milliseconds' expires.
counter=1; 
mySleepFunction= function ()
{
    var geocoder=new google.maps.Geocoder();
    var cityList=["NewYork","Tokyo","Beijing","London","Paris","Berlin","Warsaw","Helsinki","Stockholm",,"Lahore","Islamabad",,"Karachi","Faisalabad",,"Multan","Peshawar",,"Quetta","Gwadar"]; 
    for(;counter<= cityList.length ; counter++)
    {
        if(counter %10 == 0)
        {
              counter++;
              setTimeout("mySleepFunction()",5000);
              break;
        }
        if (geocoder)
        {
           geocoder.geocode({ 'address': cityList[counter-1] }, function (results, status)
           {
               if (status == google.maps.GeocoderStatus.OK)
               {
                  console.log(results[0].address_components[0].long_name+","+results[0].geometry.location.lat()+","+results[0].geometry.location.lng());
                  // Parse return results here , google sends back xml/json and you can extract longitude/latitude 
               }
               else
               {
                  //do whatever you like
               }
            });  
        }
    }
}

Here is the result of above script:


So after every ten iterations , function sets timer for calling itself after 5secs until whole list is processed. I had a list of around 1000 cities and it took me around 15mins to get all the results .



Beware though, Google won't allow more than 2500 requests from one PC/user/client/IP address(??) in 24hrs.