How to have custom mapper keys in your documents with Jongo

Posted: décembre 31st, 2013 | Author: | Filed under: Dev, Java, Jongo, MongoDB, NoSQL, Tutorial | No Comments »

I’m giving a try to Jongo to replace spring-data-mongodb in a project but I have to manage documents with ‘not really java compatible keys’.
For example, a key with a first upper case letter and some ‘-’ inside … (well ok that’s ugly but I can’t change that now).

In spring-data, I’m using MappingMongoConverter, it works but Jongo seems to be easier to use and deploy than spring data.

And yes, it’s very simple to customize the way Jongo manages your beans !
The reason is that Jongo uses Jackson Mapper (by default but you could use your own or favorite one).
So, you just have to create a PropertyNamingStrategy !!!

1 – Create a NamingStrategy

With this naming strategy, we just search in a map if there’s a replacement value for the provided key.


import static com.fasterxml.jackson.databind.PropertyNamingStrategy.PropertyNamingStrategyBase;

import java.util.Map;

public class MapTransformNamingStrategy extends PropertyNamingStrategyBase{

    private static final long serialVersionUID = 1L;

    private Map<String, String> mapping;

    public MapTransformNamingStrategy(Map<String, String> mapping) {
        this.mapping = mapping;

    public String translate(String property) {
        if (mapping.containsKey(property)) {
            return mapping.get(property);

        return property;

2 – Use it with Jongo

As you could see in the Jongo documentation :

Jongo comes with a custom Jackson configuration that can be extended.

So you just have to use addModifier and a MapperModifier implementation to set your naming strategy to the mapper.


import com.fasterxml.jackson.databind.ObjectMapper;
import org.jongo.marshall.jackson.configuration.MapperModifier;

import java.util.HashMap;
import java.util.Map;

public class CustomMapperModifier implements MapperModifier{
    Map<String, String> mapping = new HashMap<String, String>();

    public CustomMapperModifier(){
        mapping.put("myProperty", "custom-key-for-my-property");

    public void modify(ObjectMapper objectMapper) {
        objectMapper.setPropertyNamingStrategy(new MapTransformNamingStrategy(mapping));
Jongo jongo = new Jongo(db, new JacksonMapper.Builder().addModifier(new CustomMapperModifier()).build());

3 – Full example

Here is a DummyObject class to test :


import org.bson.types.ObjectId;

public class DummyObject {

    private ObjectId id;
    private String myProperty;

    public ObjectId getId() {
        return id;

    public void setId(ObjectId id) { = id;

    public String getMyProperty() {
        return myProperty;

    public void setMyProperty(String myProperty) {
        this.myProperty = myProperty;

And a unit test (I’m using an embedded mongo for the test)


import com.mongodb.DB;
import com.mongodb.MongoClient;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.MongodConfig;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import org.jongo.marshall.jackson.JacksonMapper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;


import static org.fest.assertions.Assertions.assertThat;

public class NamingStrategyTest {

    public static MongodExecutable mongodExe;
    public static MongodProcess    mongod;

    public static void runBeforeAllTests() throws Exception {
        MongodStarter runtime = MongodStarter.getDefaultInstance();
        NamingStrategyTest.mongodExe = runtime.prepare(new MongodConfig(Version.Main.V2_0, 12345, Network.localhostIsIPv6()));
        NamingStrategyTest.mongod = NamingStrategyTest.mongodExe.start();

    public static void runAfterAllTests() {

    public void testNaming(){
        DB db = null;
        try {
            db = new MongoClient("localhost", 12345).getDB("myDB");

            Jongo jongo = new Jongo(db, new JacksonMapper.Builder().addModifier(new CustomMapperModifier()).build());

            MongoCollection dum = jongo.getCollection("dummies");

            DummyObject d = new DummyObject();
            String prop = "where is brian ?";


            DummyObject check = dum.findOne("{custom-key-for-my-property: '"+prop+"'}").as(DummyObject.class);

        } catch (UnknownHostException e) {


Compiling and installing Hyperdex from sources with Java and YCSB bindings on Debian

Posted: août 2nd, 2012 | Author: | Filed under: BigData, Dev, Java, Linux, NoSQL, Tutorial | No Comments »

After a lot of hours I finally succeed to build Hyperdex on a Debian with Java and YCSB bindings.

1 – Apt sources

Edit /etc/apt/sources.list and add backports packages

deb squeeze-backports main

If you don’t have contrib and non-free for the main line, add them :

deb squeeze main contrib non-free

Add the Hyperdex repository

wget -O - \
  | apt-key add -

wget -O /etc/apt/sources.list.d/hyperdex.list \


apt-get update

2 – Install dependencies

apt-get install git openjdk-6-jdk build-essential libcityhash-dev libgoogle-glog-dev \
libpopt-dev libpo6-dev libe-dev libbusybee-dev python python-dev python-pyparsing \
python-setuptools python-argparse cython swig2.0 autoconf automake autoconf-archive libtool pkg-config gperf
easy_install sphinx
tar zxf ycsb-0.1.4.tar.gz
export CLASSPATH=`pwd`/ycsb-0.1.4/core/lib/core-0.1.4.jar
git clone git://
git clone git://

cd po6
autoreconf -i; ./configure; make && make install
cd ..

cd e
autoreconf -i; ./configure; make && make install
cd ..

3 – Install Hyperdex

git clone git://

cd Hyperdex
autoreconf -i; ./configure --enable-java-bindings --enable-ycsb; make && make install

CORS-Compliant REST API with Jersey and ContainerResponseFilter

Posted: février 27th, 2012 | Author: | Filed under: Dev, Java, Java EE, JAX-RS, Jersey, Tools, Tutorial | Tags: , , , , , , , | 25 Comments »

I recently had to consume a REST API with a cross-domain call and i’ve found a solution in this excellent blog post from Kdecherf.

The problem with this implementation is that you need to call a method for each of your api’s methods.

So with the ContainerResponseFilter interface, you could do this for ALL of your methods … transparently.

1 – Configure web.xml

You just have to add an init-param to your Jersey Servlet


2 – ResponseCorsFilter



import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

public class ResponseCorsFilter implements ContainerResponseFilter {

	public ContainerResponse filter(ContainerRequest req, ContainerResponse contResp) {

		ResponseBuilder resp = Response.fromResponse(contResp.getResponse());
		resp.header("Access-Control-Allow-Origin", "*")
	      		.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");

		String reqHead = req.getHeaderValue("Access-Control-Request-Headers");

		if(null != reqHead && !reqHead.equals("")){
			resp.header("Access-Control-Allow-Headers", reqHead);

        	return contResp;


And that’s all !

Thanks again to Kdecherf for his war upon JSONP and for sharing those headers :D

Using Jsp in a Jersey JAX-RS RESTful application

Posted: décembre 29th, 2011 | Author: | Filed under: Dev, Glassfish, Java, Java EE, JAX-RS, Jersey, Tools, Tutorial | Tags: , , , , , , , , , , , | 30 Comments »

So, ok we could easily produce some RESTful applications with Jersey.
But sometimes, the output could be very big to put in a method and a template could be useful.

Jersey provides MVC support for JSP pages.
There is a JSP template processor that resolves absolute template references to processable template references that are JSP.

1 – Configure web.xml


Instead of a servlet mapping you need to have a filter.

With the JSPTemplatesBasePath param, you choose your jsp folder


And with the WebPageContentRegex you are able to serve static resources.
In the previous example, static resources are on the /resources/ or /WEB-INF/jsp/ path but you can put what you want :


2 – Return Viewable or Response

Now you can use the Viewable class with your jsp path

package com.ezakus.web;

import javax.ejb.Stateless;

import com.sun.jersey.api.view.Viewable;

public class MyController {

    public Viewable index() {
    	return new Viewable("/index");


Note : /index assume that you have a /WEB-INF/jsp/index.jsp on your path

You can also use the Response class

package com.ezakus.web;

import javax.ejb.Stateless;

import com.sun.jersey.api.view.Viewable;

public class MyController {

    public Response index() {
    	return Response.ok(new Viewable("/index")).build();


3 – Using Viewable’s model

The Viewable object could be created with a model :

package com.ezakus.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;

import com.sun.jersey.api.view.Viewable;

public class MyController {

    public Response index() {
    	Map<String, Object> map = new HashMap<String, Object>();
        map.put("user", "usul");
        List<String> l = new ArrayList<String>();
        l.add("light saber");
        l.add("fremen clothes");
        map.put("items", l);
    	return Response.ok(new Viewable("/cart", map)).build();


Note : Jersey will assign the model instance to the attribute « it » in the jsp. (Yes, life is hard)

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  <h1>Welcome ${it.user}!</h1>
  	items in your cart :<br />
    <c:forEach var="item" items="${it.items}">
    	${item}<br />

How to change the Glassfish server log level from command line

Posted: décembre 28th, 2011 | Author: | Filed under: Admin, asadmin, Glassfish, Java, Java EE, Tools, Tutorial | Tags: , , , , , , , , , , , | 1 Comment »

When deploying applications with glassfish, you have sometimes (just sometimes) to read the server log :) You can change, mostly on the fly (no restart needed), the log levels, that could be very useful. First, list the log levels :

asadmin list-log-levels

Don’t forget to give instance name if you want those for this instance

asadmin list-log-levels instance1

Here is an example :

asadmin list-log-levels instance1

ShoalLogger	<CONFIG>
com.sun.enterprise.server.logging.GFFileHandler	<ALL>
java.util.logging.ConsoleHandler	<FINEST>
javax.enterprise.resource.corba	<INFO>
javax.enterprise.resource.javamail	<INFO>
javax.enterprise.resource.jdo	<INFO>
javax.enterprise.resource.jms	<INFO>
javax.enterprise.resource.jta	<INFO>
javax.enterprise.resource.resourceadapter	<INFO>
javax.enterprise.resource.sqltrace	<FINE>
javax.enterprise.resource.webcontainer.jsf.application	<INFO>
javax.enterprise.resource.webcontainer.jsf.config	<INFO>
javax.enterprise.resource.webcontainer.jsf.context	<INFO>
javax.enterprise.resource.webcontainer.jsf.facelets	<INFO>
javax.enterprise.resource.webcontainer.jsf.lifecycle	<INFO>
javax.enterprise.resource.webcontainer.jsf.managedbean	<INFO>
javax.enterprise.resource.webcontainer.jsf.renderkit	<INFO>
javax.enterprise.resource.webcontainer.jsf.resource	<INFO>
javax.enterprise.resource.webcontainer.jsf.taglib	<INFO>
javax.enterprise.resource.webcontainer.jsf.timing	<INFO>
javax.enterprise.system.container.cmp	<INFO>
javax.enterprise.system.container.ejb	<INFO>
javax.enterprise.system.container.ejb.mdb	<INFO>
javax.enterprise.system.container.web	<INFO>
javax.enterprise.system.core.classloading	<INFO>
javax.enterprise.system.core.config	<INFO>
javax.enterprise.system.core	<INFO>
javax.enterprise.system.core.naming	<INFO>	<INFO>
javax.enterprise.system.core.selfmanagement	<INFO>
javax.enterprise.system.core.transaction	<INFO>
javax.enterprise.system	<INFO>	<INFO>	<INFO>	<INFO>	<INFO>
javax.enterprise.system.util	<INFO>
javax.enterprise.system.webservices.registry	<INFO>
javax.enterprise.system.webservices.rpc	<INFO>
javax.enterprise.system.webservices.saaj	<INFO>
javax	<INFO>	<INFO>
org.apache.catalina	<INFO>
org.apache.coyote	<INFO>
org.apache.jasper	<INFO>
org.eclipse.persistence.session	<INFO>
org.glassfish.admingui	<INFO>
org.jvnet.hk2.osgiadapter	<INFO>
Command list-log-levels executed successfully.

After that, you just have to set it, for example :

asadmin set-log-levels javax.enterprise.system.container.ejb=<level>
# Here with the instance
asadmin set-log-levels <instance-name> javax.enterprise.system.container.ejb=<level>

As you could see in the asadmin documentation :
The default setting is INFO.

When you perform this, i think you are watching the logs.
So you could view the changes applied, if not, you have to restart the instance (or server).
Hope it would be useful for you

Java EE 6 Glassfish 3.1.1 Cluster with Load-Balancer Installation

Posted: décembre 21st, 2011 | Author: | Filed under: Dev, Java, Java EE, Tutorial | Tags: , , , , , , , , , , , , | 12 Comments »

In this tutorial we’ll see how to install a Glassfish cluster with this architecture


Assumptions : there’s nothing on servers (either java, xauth or whatever you want)


Prepare Node 2 and Node 1


Add the glassfish user (with the same password on each) and choose the installation path

adduser glassfish mkdir /opt/glassfish3
chown glassfish:glassfish

Add non-free in sources.list for sun jdk installation

# vi /etc/apt/sources.list
deb squeeze main non-free
deb-src squeeze main non-free

Install sun jdk

apt-get update apt-get install sun-java6-jdk


Prepare LB


Add the glassfish user (still with the same password)

adduser glassfish


On Node 1

  • Install xauth

The simpliest way is to install glassfish in graphical mode so we need xauth for x forwarding with ssh.

apt-get install xauth

Logout and Log in with -X option.

  • Glassfish install

Download the GlassFish Server 3.1.1 Open Source Edition Full Platform

chmod +x ./

Choose custom, install and configure, choose the installation path (/opt/glassfish3 for us)

chown -R glassfish:glassfish 

Add the path to <installation path>/bin to glassfish user’s PATH (.bashrc .profile …)
With this, glassfish user could use asadmin command line tool

  • Glassfish config

To know what we could do with asadmin

asadmin list-commands

So let’s go

asadmin login
asadmin enable-secure-admin asadmin restart-domain
#If you forget the domain name : <strong>asadmin list-domains
  • Installing Node 2 from Node 1

asadmin setup-ssh --generatekey=true node-2 lb-1
asadmin install-node node-2
  •  Create cluster

First, create the cluster config (based on the existing one),  all cluster nodes will share the same config.

asadmin copy-config default-config cluster-config

Now we could create the nodes

asadmin create-node-ssh --nodehost localhost node-1-ssh
asadmin create-node-ssh --sshuser glassfish --sshkeyfile /home/glassfish/.ssh/id_rsa --nodehost node-2 node-2-ssh

And finally the cluster and the instances

asadmin create-cluster --config cluster-config usul-cluster
asadmin create-instance --cluster usul-cluster --node node-1-ssh gf-1
asadmin create-instance --cluster usul-cluster --node node-2-ssh gf-2
# Verifying
asadmin list-instances --long=true
# Start the cluster
asadmin start-cluster usul-cluster

Load-Balancer setup

  • Install xauth because lb installer needs GUI

Edit : As John said in the comments : The Load Balancer installer requires a GUI on first install, but you can save the LB configuration to a file and subsequent installs can be done in a headless manner.

yum install xauth

We also need the JDK, so download java 6 sdk bin installer on (the bin one, not rpm.bin)


chmod +x jdk-6u30-linux-x64.bin
mv jdk1.6.0_30 /usr/local && cd /usr/local && ln -s jdk1.6.0_30 jdk
# Install in the system
# 1 because there's no java on the server, put 2 or 3 if you already have another java version)
# and launch alternatives --config
java alternatives --install /usr/bin/java java /usr/local/jdk/bin/java 1

# Verifying
java -version
  • Install and prepare Apache

yum install httpd mod_ssl openssl

For cert generation, be careful to put your server name in Common Name

# Generate private key
openssl genrsa -out ca.key 1024
# Generate CSR
openssl req -new -key ca.key -out ca.csr
# Generate Self Signed Key
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
# Copy the files to the correct locations
cp ca.crt /etc/pki/tls/certs
cp ca.key /etc/pki/tls/private/ca.key
cp ca.csr /etc/pki/tls/private/ca.csr

Edit /httpd/conf/ssl.conf and set the correct paths

SSLCertificateFile /etc/pki/tls/certs/ca.crt
SSLCertificateKeyFile /etc/pki/tls/private/ca.key

Now we need to tweak this installation because the load balancer installer needs some files and paths

# Folder for the glassfish DAS certificate
mkdir /etc/httpd/conf/ssl.crt
# Installer will look for files in $apache_home/conf/extra
ln-s /etc/httpd/conf.d /etc/httpd/conf/extra
touch /etc/httpd/conf/extra/httpd-ssl.conf
touch /etc/httpd/conf/extra/httpd-vhosts.conf
# Installer will look for bin/apachectl and bin/envvars
mkdir /etc/httpd/bin
touch /etc/httpd/bin/envvars
touch /etc/httpd/bin/apachectl

Edit Mpm config file

PidFile "logs/"
LockFile "logs/accept.lock"

<IfModule mpm_prefork_module>
 StartServers 5
 MinSpareServers 5
 MaxSpareServers 10
 MaxClients 150
 MaxRequestsPerChild 0

<IfModule mpm_worker_module>
 StartServers 2
 MaxClients 150
 MinSpareThreads 25
 MaxSpareThreads 75
 ThreadsPerChild 25
 MaxRequestsPerChild 0

Edit apachectl

/usr/sbin/apachectl -v


chmod 755 /etc/httpd/bin/apachectl
  • Export the DAS certificate

The load balancer needs an xml file to be updated : loadbalancer.xml By putting the certificate on the LB, we could update it from the DAS with apply-http-lb-changes

#Export crt
keytool \
 -export \
 -rfc \
 -alias s1as \
 -keystore <installPath>/glassfish/domains/usul/config/keystore.jks \
 -file ./glassfish.crt \
 -storepass changeit

# Send it on the LB
scp glassfish.crt root@lb-1:/etc/httpd/conf/

# The installer will put the crt into ssl.crt later
  • Install the load-balancer

Download loadbalancer :

# Don't forget to ssh -X because of GUI intall
java -jar glassfish-lbconfigurator-3_1_1.jar

Choose apache and put the installation dir (/etc/httpd)

Choose the DAS cert in /etc/httpd/conf/

When finished, edit /etc/init.d/httpd and add

 if [ -f /etc/httpd/bin/envvars]; then
 . /etc/httpd/bin/envvars
  • Configure the ssl access

keytool -printcert -file /etc/httpd/conf/ssl.cert/glassfish.crt

Copy Serial number (UPPER CASE !!!) and Organization (O) and Organization Unit (OU)
Edit /etc/httpd/conf/extra/httpd-ssl.conf and edit both SSLRequire at the end of file with O OU and Serial (in Upper Case)
You will have something like this

 SSLVerifyClient require
 SSLVerifyDepth 1
 SSLCACertificateFile /etc/httpd/conf/ssl.crt/glassfish.crt
 SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
 and %{SSL_CLIENT_S_DN_O} eq "Oracle Corporation" \
 and %{SSL_CLIENT_S_DN_OU} eq "GlassFish" \
 and %{SSL_CLIENT_M_SERIAL} eq "4EEB6172" )

 SSLVerifyClient require
 SSLVerifyDepth 1
 SSLCACertificateFile /etc/httpd/conf/ssl.crt/glassfish.crt
 SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
 and %{SSL_CLIENT_S_DN_O} eq "Oracle Corporation" \
 and %{SSL_CLIENT_S_DN_OU} eq "GlassFish" \
 and %{SSL_CLIENT_M_SERIAL} eq "4EEB6172" )

Edit /etc/httpd/conf/extra/httpd-vhosts.conf

#Be sure to have :
NameVirtualHost *:80
<VirtualHost *:80>
 ServerName lb-1
 DocumentRoot "/var/www"
 #  The document root is not important, it must exist to avoid warnings or errors in logs but this is not used

Raise the MaxClients in /etc/httpd/conf/extra/httpd-mpm.conf because installer put 1 that is not enough

chown -R apache:apache /etc/httpd
# just check before that apache is the user for apache in httpd.conf
/etc/init.d/httpd restart

Create the load-balancer in the DAS

asadmin create-http-lb --devicehost lb-1 --deviceport 443 --target usul-cluster lb-1

asadmin apply-http-lb-changes lb-1