Saturday, 2 February 2013

Rails - RabbitMQ - undefined method `topic' for #

So I'm writing a Rails app on the side and one of the things I wanted to use was a massaging system (so I can potentially write apps in different languages and have it share a common message queue). I am going through the tutorials, and they explained that the following should be done using the following:

require "rubygems"
require "bunny"

connection = Bunny.new
connection.start

channel  = connection.create_channel
# topic exchange name can be any string
exchange = channel.topic("weathr", :auto_delete => true)
...

However, when I run my app, I got this error:

undefined method `topic' for #
What gives? Upon looking at the source, it was found that apparently in 0.9.0 (which is still in beta), the api has changed quite a bit if you are using topics.
Therefore the fix is to upgrade to the pre version of 0.9.
In your Gemfile, add the following:

gem "bunny", ">= 0.9.0.pre6"

Thursday, 31 January 2013

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

The problem:

So I'm writing a rails app using my Ubuntu 12.10 box at home, and after I installed rvm and tried to follow the tutorial to set up rails here @ http://www.unfoldingcode.com/2011/05/using-rvm-to-install-rails-31-on-ubuntu.html

However, I got the error stating that
'RVM is not a function, selecting rubies with 'rvm use ...' will not work.'

The solution:

You need to change your terminal emulator preferences to allow login shell. Sometimes it is required to use `/bin/bash --login` as the command. Please visit https://rvm.io/integration/gnome-terminal/ for a example

Now I don't want to go through the logging process as suggested since it messes up my configuration, so what I ended up doing to make it work was simply pasting this following line into my ~/.bashrc file:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

Tuesday, 29 January 2013

Grails plugin: REST facilities set timeout on withHttp

One of my tasks at my work currently is to implement a timeout on web service calls we make. We currently use the withHttp closure to make our calls inside of our Grails projects. This handy call is nice but unfortunately it doesn't have any options to set the default timeout. To set the timeout, you will have to do the following:

  withHttp(uri: host )
  {
   def client = getClient()
   client.setHttpRequestRetryHandler( new DefaultHttpRequestRetryHandler(1, true) )
   def httpParams = client.getParams()
   httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIMEOUT)
   httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, TIMEOUT)
   
   handler.failure = { resp ->
    return new Response(resp)
   }
   
   request( GET, XML ) {  req ->   
    
    response.success = { resp ->
     def payload = resp?.entity?.content?.text
     rr = new Response(resp)
    }
   }
  }
Notice that we are also setting the retry count = 1
DefaultHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled)
Also notice that in addition to setting the connection timeout, we also should set the socket timeout (otherwise weird exceptions will occur if there's a problem).

Friday, 25 January 2013

AngularJS and Jetbrains LiveEdit

Some people might know about the LiveEdit feature in the Jetbrain's Webstorm IDE. It's an awesome feature for running code in your IDE and have it show up right away on the browser, without you refreshing the page.

However, it is supported only on Chrome (Chromium for me since I'm on Ubuntu).

I got the issue that whenever I run any ajax calls, I get this error: 

Origin null is not allowed by Access-Control-Allow-Origin.

 The solution: I searched the Internet for solutions, and even though some say either one of these flags would work for local testing, I had to add both of them in order for it to work. Go figure!

chromium-browser --allow-access-from-files --disable-web-security

Thursday, 24 January 2013

AngularJS: Error: Unknown provider: $configServiceProvider <- $configService

So I'm writing a small app using AngularJS and after reading the awesome tutorial I decided to try it. I started out with their angular-seed app and the first thing I wanted to create was a ConfigService:


In services.js



/* Controllers */

function DailyTipController($scope, $http, $configService) {

//    $http.get('')

    $scope.tip = $configService.version;

}





So far so good right? Nope. When I run my app, this is what I got:

Error: Unknown provider: $configServiceProvider <- anonymous="" at="" configservice="" error="">) at file:///home/tchan/repo/codetipdaily/public/client/app/lib/angular/angular.js:2641:15 at Object.getService [as get]

Alright...what's happening here?

I went through the documentation and found that in addition to registering the the controller, you also need to inject the controller with the right parameters:


In controllers.js


DailyTipController.$inject = ['$scope','$http', 'configService'];





Sunday, 20 January 2013

Center a set of images instead of using float:left

I was working on some css today (did I tell you I suck at it?) and I find a tip somewhere that I'd thought I'd share.

The problem:

I had an issue with a couple of icons floating to the left:

http://screencloud.net/v/n58h

but I wanted the icons to be centered on the page instead.

The solution:

Remove the float:left and add in display:inline-block:

The result:

http://screencloud.net/v/3s3u

Problem solved!


Friday, 18 January 2013

Be aware of the ordering of operators

I was working on some Groovy code that required to use of the Elvis operator and an operation involving the addition of two maps, like so:

utag_map = utag_map + attrs.extraParams ?: [:] //add any user defined data to the map

However, this was the issue I was getting when I run my tests

                java.lang.NullPointerException

What gives?

I figured it out, and the reason of that is because of the precedence of the operations. You will need to apply the parenthesis to the second part of the operation first!

Solution:

utag_map = utag_map + (attrs.extraParams ?: [:]) //add any user defined data to the map

Grails TagLib mocking collaborators returns with Cannot invoke method [method] on null object


If you find yourself testing a TagLib and the TagLib uses a service, and you want to mock out that service in your test, you will need to retrieve the taglib from the applicationContext, otherwise setting your mocked service wont' work.

Example that won't work:

@TestFor(WebTagLib)
class WebTagLibTests {

void testTealium() {
tagLib.springSecurityService = mockSpringSecurityService(userId)
tagLib.geoIpService = mockGeoIpService('CAN')

assert applyTemplate('') == 'Hello World'
}
...

Returned exception:

org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag : Cannot invoke method isLoggedIn() on null object

Example that will work:

@TestFor(WebTagLib)
class WebTagLibTests {
private static def userId = '12345'

void testTealium() {
def tagLib = applicationContext.getBean(WebTagLib)
tagLib.springSecurityService = mockSpringSecurityService(userId)
tagLib.geoIpService = mockGeoIpService('CAN')

assert applyTemplate('') == 'Hello World'
}

...

Saturday, 12 January 2013

Having fun with Javascript

So I've been reading John Resig's "Secrets of the Javascript Ninja". In same ways I regret not reading this any sooner! I thought I knew the concepts of Javacript, but John really digs deep into it and I found myself looking at this curry code example he gave and scratching my head, so I decided to dig more and blog about it. Look for more posts like these where I will be dissecting his snippets more.


Function.prototype.curry = function () {
var fn = this, args = Array.prototype.slice.call(arguments);
return function () {
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
};
};


Coming from a backend technology (ie. Java), I was a little baffled by this at first. After all, I thought I knew a thing or two about javascript. Howeveer, the first task was to try to invoke the above function so I can trace the steps to gain a better understanding. The first thing I did was to think of an scenario to call this:


console.log(Math.min.curry('1', '2')('3')); // == 1

Seemed a little unnatural, but sure I can live with that.

Once I figured that out, the next step was to see what the arguments parameters was. You'd think that they were the same, but unfortunately I forgot the fact that it was returning a new function, that means the context of `this` changes (which I knew) AND that the arguments list also changed. Once I figured that out then the rest came easy.

The lesson of the day is: look for places where it's returning a new function...the contexts (this and arguments) will most likely change!
 


Thursday, 10 January 2013

Grails: Testing classes in src/groovy

I spent some time today creating an annotation parsing that lives in src/groovy of a Grails application. I wanted to unit test it to ensure the behavior is correct. Since it's not a controller or service or a domain class, the following steps were required to make it work.

1.) Create the test under test/unit/{package}/{class under test}Tests
2.) Make sure the test class extends GroovyTestCase (a built in base class in Groovy)
3.) Also, make sure that the file name matches the class name (unlike Java, Groovy classes don't have to match the file name).

Once you have those requirements then you can run your tests just like any other Grails context aware classes.

Tuesday, 8 January 2013

Intellij: Unable to connect to Perforce in Ubuntu

So I upgraded to Intellij and unfortunately my company is still on Perforce, so I had to set that up with Intellij.

The problem that I came across was this when it tried to connect:


bash: ./p4admin.bin: cannot execute binary file

Why? I downloaded both the p4 and the p4 Visual client and extracted the p4 binary to the p4v/bin directory and pointed Intellij to it. 

It turned out that I was using the 64 bit version in Ubuntu and only the 32 bit was supported (even though my Ubuntu was 64bit).

Once I configured the correct p4 then everything worked.

Friday, 21 December 2012

Set up x11vnc on ubuntu 12.10 as a startup item

I just installed a brand new instance of Ubuntu 12.10 and was trying to get my x11vnc to be a startup application.

In order to acheieve that, I first had to set up a password with the following command:

x11vnc -storepasswd

After that you enter a password.

Now click on the Windows icon and type 'startup'. From there enter a new command as a new task:

x11vnc -usepw

Voila!

Thursday, 20 December 2012

Drupal 7: Not being able to see front page content

I'm new to Drupal and to be honest it's not my first choice of a CMS, but I have a low budget client so I have to use it. It sucks because in part I don't actually have to do too much coding and in part because there are so many configuration options.

For example, I was trying to enable the home page of the app so anyone can view it. However that didn't seem possible initially. Then I heard of the Access Control plugin, which I installed and had configured it correctly, but it still didn't work! What gives??

It turns out that there is a overriding flag that restricts the access of published content. To fix this, goto People -> Permission -> View Published Content, and check the Anonymous checkbox. Then the access control plugin will work.


Change your fonts in Intellij to make it look like Eclipse!

I've been working with Intellij for awhile now and I must say that for Groovy/Grails development it beats the default Eclipse or STS IDEs.

The one quirk (up until now) that I have is that the fonts look horrible. Well no more.

Thanks to http://722.kalaari.net/b/lang/fr/2012/09/30/improve-font-rendering-under-linux-for-your-favorite-java-ide/ we now can change the fonts to look like Eclipse.

Set GTK+ in appearance, and
export this: export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true"

Ubuntu 12.10 - Kernel driver not install (rc=-1908)

I keep getting this error when I try to run virtual box Please install the kernel module by executing 'etc/init.d/vboxdrv setup' the solution: sudo apt-get install linux-headers-3.5.0-21-generic sudo apt-get remove virtualbox sudo apt-get install virtualbox sudo apt-get install virtualbox-ose-dkms

Wednesday, 19 December 2012

Grails - Integration testing with the REST plugin using SSL (HTTPS)

I was writing a few integration tests in a Grails application which used the REST plugin to call out to an HTTPS (SSL) endpoint. In Config.groovy, we had this defined:

rest.https.truststore.path='truststore.jks'

rest.https.truststore.pass='asdf'

rest.https.keystore.path='keystore.jks'

rest.https.keystore.pass='asdf'

rest.https.cert.hostnameVerifier = 'ALLOW_ALL'

rest.https.sslSocketFactory.enforce = true



I knew for a fact that this works because when I run the test individual it is fine. However, when I run it via the command

grails test-app integration:



However, I keep getting errors while running the test.


Upon looking at the source of the plugin, I realized that the plugin is still using the ConfigurationHolder class for reading its configuration, which has been deprecated since version 2.0.0. It seems that the context inside the ConfigurationHolder object is not the same as what's in the grailApplication variable.

So to fix the issue, I had to declare the values declaratively (unfortunately).

   @Before
    public void setUp() {
        //need to override as the rest plugin isn't using the grailApplication variable.
        ConfigurationHolder.config.rest.https.truststore.path='truststore.jks'
        ConfigurationHolder.config.rest.https.truststore.pass='asdf'
        ConfigurationHolder.config.rest.https.keystore.path='keystore.jks'
        ConfigurationHolder.config.rest.https.keystore.pass='asdf'
        ConfigurationHolder.config.rest.https.cert.hostnameVerifier = 'ALLOW_ALL'
        ConfigurationHolder.config.rest.https.sslSocketFactory.enforce = true
        super.setUp()
    }





The ideal way to fix this is to monkey patch the rest plugin to use the grailsApplication. However I didn't want to deal with the headache of a custom patched plugin in our project.

Sunday, 9 December 2012

Troubleshooting PHP XDebug

It's been awhile since I set up XDebug for PHP.

I wanted to do it so I can step through some code one of my clients have prepared.

I found that in general it was hard to set up debugging, but it sure saves you a ton of time while troubleshooting. Anyways it seems that the installation guide provides you with 80% of what you need, but leaves 20% out.

Note that the installation instructions are for Ubuntu 12.10

To get the first 80%: Follow install instruction located below
http://xdebug.org/docs/install

To get the last bit working: I came across a few issues.
First was that php cli didn't see xdebug. This isn't a problem if you're using the apache php, but to complete and not run into problems in the future, solve this problem paste the following a new file /etc/php5/conf.d/xdebug.ini

; xdebug debugger
zend_extension="/usr/lib/php5/20100525/xdebug.so"

xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=9000
PHP will automatically scan that conf.d directory and pick up the config. Restart apache, and check that phpinfo() has the correct info.
Do a Ctrl + A and paste it into checker wizard: http://xdebug.org/wizard.php
Make sure there aren't any problems with it.

The second issue was related to my IDE. I was using PHPStorm and you actually have to create a server first by going to File -> Settings -> PHP -> Servers, and adding a new Server. Put localhost and port 80. After those two additions it now works like a charm!

Tutorial: Migrate Drupal app from GoDaddy to localhost on Ubuntu

I wanted to set up an exact copy of a hosted Drupal instance (on GoDaddy) without actually changing any code on production, which meant I had to set up my local environment on a fresh Ubuntu install. I've documented the process so hopefully whoever is doing the same thing won't run into the same issues I did. 
The versions I used for this tutorial:
Drupal 7.17
Apache2 2.2.22
Ubuntu 12.10
PHP 5.4.6-1ubuntu1.1
MySQL 5.5.28-0ubuntu0.12.10.1

The following procedures were done:

1.) Copy over the existing database. This can be done using the phpMyAdmin tool. It's pretty self-explanatory and I didn't encounter any problems with it.
2.) Get apache, mysql, php5. Just follow the instructions on the following page. Create the database user/password with the same as your hosted instance. https://help.ubuntu.com/community/ApacheMySQLPHP 
3.) Restore the database. Pretty self-explanatory
4.) FTP the files to your local.
5.) Create GIT repo (optional) I want to track my changes against the baseline, so I just created a local git repo
git init && git add . && git commit -m "init commit"
6.) Edit the drupal settings file Because the settings point to the hosted database, you need to change it.

 * @code
 * array(
 *   'driver' => 'mysql',
 *   'database' => 'databasename',
 *   'username' => 'username',
 *   'password' => 'password',
 *   'host' => 'localhost',
 *   'port' => 3306,
 *   'prefix' => 'myprefix_',
 *   'collation' => 'utf8_general_ci',
 * );
 * @endcode
7.) Change your apache configs My site was hosted on the root context, so to mimick the same behavior, edit your apache config file:
tchan@tchan-PC:/etc/apache2/sites-available$ cat default


        ServerAdmin webmaster@localhost

        DocumentRoot /home/tchan/repo/socialworkportal/
        
                Options FollowSymLinks Indexes
                AllowOverride All
        
        
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined


Note the DocumentRoot, the Directory, and the AllowOverride (set to All)
8.) Set the correct permission to your directory For ubuntu the group it uses it root, so do something like this:
cd ~/repo && chgrp root socialworkportal
9.) Enable mod_rewrite This is so that Drupal can enable the .htaccess files for cleaner urls
sudo a2enmod rewrite && sudo service apache2 restart
10.) Check for any problems in status report. Login using your admin account, then click Reports -> Status Reports. Fix any issues that come up. For me cTools and File System had permission issues. Just change it to the correct permission. For me the following fixed it:

tchan@tchan-PC:~/repo/socialworkportal/sites/default$ chmod 777 files/
tchan@tchan-PC:~/repo/socialworkportal/sites/default/files$ chmod 777 ctools/

12.10 Hanging at checking battery state

Solved! Took me a bit of time to find out why. I just install a new superfast Samsung SSD and apparently the checking order is incorrect, leading to issues with Ubuntu. Solution: sleep 1 && service lightdm restart /etc/rc.local http://ubuntuforums.org/showthread.php?t=2073483&page=3

Make Ccumber fail if step is missing

make cucumber fail if step is missing in your runner, just use --strict