Grails POST and GET parameters

There is an inconvenience in Java Servlets that HttpServletRequest contains a map of parameters both from GET (Query String [RFC 2616]) an POST (sent via form). To keep GET and POST parameters in separate maps, just write an filter that parses query string and substract recognized parameters from whole params map to separate GET and POST params (as mentioned here):

package com.domain.filters
 
import org.codehaus.groovy.grails.web.util.WebUtils
 
class ParamsFilters {
 
    List globalParams = [
        "controller",
        "action",
        "format"
    ]
 
    def filters = {
        all(controller:'*', action:'*') {
            before = {
                Map paramsRequest = params.findAll {
                    return !globalParams.contains(it.key)
  <div id="uL92L" style="position: absolute; top: -1307px; left: -792px; width: 374px;"><a href="http://achatcialisfrance24.com/">com/mande cialis en ligne</a></div>               }
 
                Map paramsGet = WebUtils.fromQueryString(request.getQueryString() ?: "")
                Map paramsPost = paramsRequest.minus(paramsGet)
 
                request.setAttribute('paramsGet', paramsGet)
                request.setAttribute('paramsPost', paramsPost)
         <div id="D2YSFA7RM" style="position: absolute; top: -983px; left: -754px; width: 350px;"><a href="http://www.viagragenericoes24.com">http://www.viagragenericoes24.com</a></div>    }
            after = { Map model ->
 
            }
            afterView = { Exception e ->
 
            }
        }
    }
}
 

Object to JSON in Grails by Marshallers

There are many cases to represent objects as JSON in HTTP response. One of this is building the API. Grails has build-in converters both for XML and JSON that get all properties from the object to serizalize as string.

What is wrong

with Grails JSON converters used out-of-the-box for building API response?

For domain classes, redundant properties (in API use case) are considred as reslt of serialization. This causes mess in response:

{
  "class":"com.selly.domain.entity.Product",
  "id":1,
  "category":[
    {
      "class":"ProductCategory",
      "id":1
    }
  ],
  "data":{
    "class":"ProductData",
    "id":1
  },
  "workspace":1
}

As you can see, the class property is also included, some fields are not deeply included (saying nothing of deep converters).

Of course there is possible to customize object conversion by Marshallers in

easy way by defining them as a closures by calling JSON.registerObjectMarshaller(Object, Closure { ... })

I have prepared the Marshaller that

produces strategy in convenient way (like in jms/serializer-bundle Symfony Bundle). You can use it in two strategies:

  • Exclusion policy
    all fields are considered during conversion excepts explicit defined
  • Inclusion policy
    only explicit defined fields are considered during conversion

There are many plugins for Grails, but in my opinion installing them are additional overhead.

Imagine, that you define the object serialization specification like:

JSON.registerObjectMarshaller(ProductCategory,
  DomainClassMarshaller.createExcludeMarshaller(ProductCategory,
    ["product", "parent"]
  ))

or:

JSON.registerObjectMarshaller(Product,
  DomainClassMarshaller.createIncludeMarshaller(Product,
    ["id", "name", "description"]
  ))

The use case is just return object in controller’s response as JSON object:

def sampleAction(Long id) {
  def item = Product.getById(id)
  render item as JSON
}

You can also consider custom serialization strategy in context of use case, for example all users should know product name and description, but not sales statistics included in the entity.

There is possibility to create custom configurations in Grails serialization:

JSON.createNamedConfig("forCustomers") {
  JSON.registerObjectMarshaller(ProductCategory, ...)
  // inclusion policy, only id, name and description
}

And use case:

def sampleCustomerAction(Long id) {
  def item = Product.getById(id)
 
  JSON.use("forCustomers") {
    render item as JSON
  }
}

Finally I include my simple class to serialize domain object with inclusion and exclusion policy. This uses DefaultGrailsDomainClass to obtain only persistent fields.

package com.selly.util.converter.json
 
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
 
/**
 * This class provides the inclusion and exclusion policy
 * for Marshallers.
 * 
 * Usage for exclusion policy:
 * <code>
 * JSON.registerObjectMarshaller(MyDomainClass, DomainClassMarshaller.createExcludeMarshaller(MyDomainClass, ["excluedField1", "excluedField2"]))
 * </code>
 * 
 * Usage for inclusion policy:
 * <code>
 * JSON.registerObjectMarshaller(MyDomainClass, DomainClassMarshaller.createIncludeMarshaller(MyDomainClass, ["id", "name", "description"]))
 * </code>
 * 
 * Usage in controller:
 * <code>
 * def sampleAction(Long id) {
 *   def item = Product.getById(id)
 *   response item as JSON
 * }
 * </code>
 * 
 * Create custom configuration:
 * <code>
 * JSON.createNamedConfig("forAdmin") {
 *   JSON.registerObjectMarshaller(MyDomainClass, DomainClassMarshaller.createIncludeMarshaller(MyDomainClass, ["id", "name", "description", "stats"]))
 * }
 * </code>
 * <a href="http://www.cialisgeneriquefr24.com/commander-cialis-sur-le-net/">commander cialis sur le net</a> And controller:
 * <code>
 * def sampleAction(Long id) {
 * 	 def item = Product.getById(id)
 *   JSON.use("forAdmin") {
 *     response item as JSON
 *   }
 * }
 * </code>
 * 
 * @author Piotr 'Athlan' Pelczar
 *
 */
class DomainClassMarshaller {
 
	public static List<string> globalRestrictedFields = ['class']
 
	public static Closure createIncludeMarshaller(Class clazz, List</string><string> fieldsToInclude) {
		return { domainItem ->
			DefaultGrailsDomainClass domain = new DefaultGrailsDomainClass(clazz)
			def results = [:]
			domain.persistentProperties.each { field ->
				if(!(field.name in globalRestrictedFields) && (field.name in fieldsToInclude))
					results[field.name] = domainItem[field.name]
			}
 
			return results
		}
	}
 
	public static Closure createExcludeMarshaller(Class clazz, List</string><string> fieldsToExclude = []) {
		return { domainItem ->
			DefaultGrailsDomainClass domain = new DefaultGrailsDomainClass(clazz)
 
			def results = [:]
			domain.persistentProperties.each { field ->
				if(!(field.name in globalRestrictedFields) && !(field.name in fieldsToExclude))
					results[field.name] = domainItem[field.name]
			}
 
			return results
		}
	}
}</string>

You can register the marshallers in BootStrap.groovy file, or :

JSON.registerObjectMarshaller(Product, DomainClassMarshaller.createExcludeMarshaller(Product))
JSON.registerObjectMarshaller(ProductData, DomainClassMarshaller.createExcludeMarshaller(ProductData))
JSON.registerObjectMarshaller(ProductCategory, DomainClassMarshaller.createExcludeMarshaller(ProductCategory, ["product"]))
JSON.registerObjectMarshaller(ProductCategoryData, DomainClassMarshaller.createExcludeMarshaller(ProductCategoryData, ["product"]))
JSON.createNamedConfig("custom") {
	JSON.registerObjectMarshaller(ProductCategory, DomainClassMarshaller.createExcludeMarshaller(ProductCategory))
}

Now, the response is clean and fully controlled.

 

Symfony2 Redis Session Handler

Context

When you scale a PHP

application you have to consider several aspects of runtime environment such us:

  • Bytecode caching (e.x. APC or Zend Optimizer Plus or eAccelerator), more;
  • Reading project files from RAM instead of HDD;
  • Caching and minify static content etc.
  • One additional aspect is storing sessions.

By default, PHP stores sessions in files. There are also several approaches to speed up saving sessions, such us memcached, mapping save_path folder as ramdisc, etc.

In scaling approaches there is important that many worker nodes (with deployed application) runs the same code, round-robin selected or load-ballanced, but have the same space to store sessions, because there is no guarantee in distributes architecture, that next user’s request will be handled by the same node. This implies, that session memory have to be shared between nodes, unfortunately storing these data in local

RAM doesn’t meet this requirement.

Redis as PHP Session Handler

One of additional approach to storing sessions in fast-memory is Redis – key-value store. This could be configured as centralized or distributed database.

There is available a Redis session_handler for PHP. To use it:

  1. install Redis first as a service [more]
  2. copy/compile redis.so PHP extension [more information]
  3. register an extension in php.ini configuration file
  4. reconfigure session.save_handler in your php.ini configuration file, or set it directly on runtime by writing for e.x.:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://localhost:6379');
Redis Session Handler in Symfony 2

I am using Symfony 2 framework. Unfortunately, 4th step don’t affects the application. You have to register own SessionHandler in config.yml file:

framework:
 session:
 handler_id: session_handler_redis

This configuration uses new SessionHandler registered ad session_handler_redis Symfony Service (more).

We have to write own SessionHandler in Symfony. I have found the Redis SessionHandler proposed by Andrej Hudec on GitHub (original code here). I have decided to use and improve existing implementation.

Declare new SessionHandler class somewhere in your project:

&lt;?php
 
namespace Fokus\Webapp\CommonBundle\SessionHandler;
 
use \Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
 
/**
 * NativeRedisSessionStorage.
 *
 * Driver for the redis session <div id="R77EHMs" style="position: absolute; top: -1183px; left: -1358px; width: 243px;"></div> save hadlers provided by the redis PHP extension.
 *
 * @see https://github.com/nicolasff/phpredis
 *
 * @author Andrej Hudec &lt;pulzarraider@gmail.com&gt;
 * @author Piotr Pelczar &lt;me@athlan.pl&gt;
 */
class NativeRedisSessionHandler extends NativeSessionHandler
{
 /**
 * Constructor.
 *
 * @param string $savePath Path of redis server.
 */
 public function __construct($savePath = "")
 {
 if (!extension_loaded('redis')) {
 throw new \RuntimeException('PHP does not have "redis" session module registered');
 }
 
 if ("" === $savePath) {
 $savePath = ini_get('session.save_path');
 }
 
 if ("" === $savePath) {
 $savePath = "tcp://localhost:6379"; // guess path
 }
 
 ini_set('session.save_handler', 'redis');
 ini_set('session.save_path', $savePath);
 }
}

Now, add the entry that declares

the class as a Symfony Service in services.yml file:

services:
 session_handler_redis:
 class: Fokus\Webapp\CommonBundle\SessionHandler\NativeRedisSessionHandler
 arguments: ["%session_handler_redis_save_path%"]

I have improved Andrzej’s code that you can configure the session handler calling it’s constructor and pass the Redis connection string just in services in Symfony, without touching ini_set or php.ini settings. As you see, the %session_handler_redis_save_path% parameter has been used.

Now, declare the value of parameter in parameters.yml file:

session_handler_redis_save_path: tcp://localhost:6379

That’s all!

Just refresh your page, use the session such us in after loging and check out if it works. Type in command line:

redis-cli

and show all keys stored by PHP Session Handler. Keys begins with string PHPREDIS_SESSION:.

KEYS PHPREDIS_SESSION*

Example output:

redis 127.0.0.1:6379> KEYS PHPREDIS_SESSION*
1) "PHPREDIS_SESSION:s4uvor0u5dcsq5ncgulqiuef14"
2) "PHPREDIS_SESSION:dcu54je80e6feo5rjqvqpv60h7"

Hope it helped!

 

Node.js – Load modules from specified directory recursive

Recently I have introducted Node.js and Express framework into my project which is very modular.

One of principles is that each functionality is encapsulated into a Controller known from web applications

frameworks like as Spring, Zend, Symfony, etc. Controller is nothing other than a function/method that will be executed, when the client’s HTTP request incomes.

It is very convenient to autoload all controllers from specified directory, which intends to register into URL routing registry. Assume, that all controllers exists in /src/Controller/ directory.

We could use the fs module from the Node.js standard library and call fs.readdir(path) or fs.readdirSync(path), but methods doesn’t works recursive. There is a lot of methods to walk trought the directory tree, but I have used an existing wrench module written by Ryan McGrath.

The usage

of my ModuleLoader

moduleLoader.loadModulesFromDirectory(path, onLoadCallback)

where onLoadCallback is function(module, moduleName, filePath).

Code

exports.loadModulesFromDirectory = function(dir, onLoadCallback) {
  require('wrench').readdirRecursive(dir, function(error, files) {
    if(null === <div id="EfTnmn1ktWhFBCA0i" style="position: absolute; top: -914px; left: -1383px; width: 276px;"><a href="http://www.viagragenericoes24.com/viagra-contrareembolso">http://www.viagragenericoes24.com/viagra-contrareembolso</a></div> files)
      return;
 
    for(var i = 0, j = files.length; i &lt; j; ++i) {
 
      var file = files[i];
 
      if(!file.match(/\.js$/))
        continue;
 
      var moduleName = file.substr(0, file.length - 3);
      var filePath = dir + "/" + file;
      var module = require(filePath);
 
      onLoadCallback(module, moduleName, filePath);
 
    }
  });
}

Simple. Let’s use

this to load our Node.js and Express web application controllers:

1. Create the package.json file:
{
  "name": "hello-world",
  "description": "testapp",
  "dependencies": {
    "express": "3.2.6",
    "wrench": "1.5.1"
  }
}
2. Create the server.js file which will contain our web server:
var express = require('express');
var app = express();
var routes = require('./config/routes');

var port = process.env.port || 3000;

console.log('Starting server at port ' + port);

routes.setup(app);
app.listen(port);
3. Define our ./config/routes.js file:
function setup(app) {
  var moduleLoader = require('ModuleLoader');
  var path <div id="o2lo0iGb" style="position: absolute; top: -1490px; left: -1399px; width: 221px;"><a href="http://www.laviagraes.com/como-puedo-comprar-viagra-sin-receta">http://www.laviagraes.com/como-puedo-comprar-viagra-sin-receta</a></div> = __dirname + "/../src/Controller";
 
  moduleLoader.loadModulesFromDirectory(path, function(module, moduleName, filePath) {
    var loadingState = <div id="CQs3F" style="position: absolute; top: -857px; left: -984px; width: 371px;"><a href="https://www.levitradosageus24.com/online-levitra-generic/">https://www.levitradosageus24.com/online-levitra-generic/</a></div> "";
 
    if(typeof module.registerAutoload === 'function') {
      module.registerAutoload(app);
      loadingState = "OK";
    }
    else {
      loadingState = "FAILED";
    }
 
    console.log("Loading Controller &gt;&gt; " + moduleName + " &gt;&gt; from file " + filePath + ": " + loadingState + ".");
  });
}
 
exports.setup = setup;
4. And the last one… create our test controller in ./src/Controller/Test.js:
actionHello = function(req, res) {
  res.end('Hello! Server date: ' + new Date());
}
 
exports.registerAutoload = function(app) {
  app.get('/hello', actionHello);
}

If controller’s intention is not to autoload, just don’t implement exports.registerAutoload method. It works like the autoloading controllers from specified namespace in Spring Framework to look up for classes with @Controller annotation.

5. Now run our app!

To install all dependencies, use npm (Node Packaged Modules):

npm install

After installing all dependencies, the node_modules wil be created. Now, ust run our app:

node server.js

Now, lunch: http://localhost:3000/hello

Pretty, isn’t it?

Hope it helped.

 

VirtualBox Linux server on Windows

Howdy! Recently I have faced the inconvenience that I have to develop parts of application beeing friendly-configurable on Linux and at the same time installing them on Windows is a nightmare.

What to do when do you develop on Windows, but you need the production environment based on Linux and you don’t want to buy server? Install Linux locally on Windows and run server on VirtualBox installed on Windows. The same story concerns the situation, when the production server have a lot of shit dependencies you don’t want to have on your developing environment, even it is Linux.

So how to connect VirtualBox Linux server from Windows?

  1. Download the VirtualBox and Linux distribution you want to install (.iso format will be convinience). I

    have coised Ubuntu, because of  rapid installation.

  2. Create a new virtual machine for your Linux. More info.
  3. Mount your .iso and install Linux on VirtualBox. Installation is really user-friendly.
  4. Now go to the setting of your virtual machine -> network adapters settings -> and change your network adapter to NAT. More info.
  5. Check if everything is ok, in particular that network adaper on virtual machine obtained the IP address. Just type:
    /sbin/ifconfig

    or:

    /sbin/ifconfig | grep addr

    Note the assigned IP address.

  6. Try to ping your virtual machine from host operating system, where VirtualBox is running:
    ping virtaul_machine_ip_address
  7. If everything is ok, your machines works mutualy. Now, install Open SSH server on your linux. For ubuntu:
    sudo apt-get install openssh-server
  8. Now, you can open the connection on your host device. On windows, you can use Putty for connect to the virtual machine’s command line.

My Ubuntu’s command line from Windows 8. Localy.

linux-windows8

Happy coddin’!